Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azidentity: DefaultAzureCredentialOptions to allow opting out some of the auth methods #20502

Closed
magodo opened this issue Mar 29, 2023 · 12 comments
Assignees
Labels
Azure.Identity feature-request This issue requires a new behavior in the product in order be resolved. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team

Comments

@magodo
Copy link
Contributor

magodo commented Mar 29, 2023

Feature Request

Currently, the DefaultAzureCredentialOptions will always try each defined auth method in the fixed order. Imagine I have a VM and want to run some Go code on it to interact with ARM using this SDK, it will always try the MSI (i.e. the VM's identity) instead of falling back to using Azure CLI (i.e. my user account). The request sent from my App will then fail since I didn't give enough role to the VM, which I deliberately want to avoid.

@ghost ghost added the needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. label Mar 29, 2023
@jhendrixMSFT jhendrixMSFT added Azure.Identity and removed needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. labels Mar 29, 2023
@chlowell
Copy link
Member

We decided not to add such options because we want to keep the DefaultAzureCredential API simple to avoid overwhelming developers who are just getting started with Azure, and making the credential difficult to use and understand. The credential types used in the default chain are exported so you can use them directly. If you want to authenticate with the Azure CLI, you can simply call NewAzureCLICredential instead of NewDefaultAzureCredential. If you want to change the composition of the default chain, you can create a custom chain with NewChainedTokenCredential.

@chlowell chlowell added feature-request This issue requires a new behavior in the product in order be resolved. issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. labels Mar 29, 2023
@ghost
Copy link

ghost commented Mar 29, 2023

Hi @magodo. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text “/unresolve” to remove the “issue-addressed” label and continue the conversation.

@ghost
Copy link

ghost commented Apr 5, 2023

Hi @magodo, since you haven’t asked that we “/unresolve” the issue, we’ll close this out. If you believe further discussion is needed, please add a comment “/unresolve” to reopen the issue.

@ghost ghost closed this as completed Apr 5, 2023
@magodo
Copy link
Contributor Author

magodo commented Apr 11, 2023

@chlowell I have to disagree with you that DefaultAzureCredential is to avoid overwhelming developers who are just getting started with Azure, if you look at the option definition

type DefaultAzureCredentialOptions struct {
azcore.ClientOptions
// AdditionallyAllowedTenants specifies additional tenants for which the credential may acquire tokens. Add
// the wildcard value "*" to allow the credential to acquire tokens for any tenant. This value can also be
// set as a semicolon delimited list of tenants in the environment variable AZURE_ADDITIONALLY_ALLOWED_TENANTS.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be true for applications authenticating in disconnected or private clouds.
// This skips a metadata request that will fail for such applications.
DisableInstanceDiscovery bool
// TenantID identifies the tenant the Azure CLI should authenticate in.
// Defaults to the CLI's default tenant, which is typically the home tenant of the user logged in to the CLI.
TenantID string
}

Things like DisableInstanceDiscovery is far more complicated than an option like msiDisabled.

Apparently I can implement my own DefaultAzureCredential by copy-pasting 90% of the existing implementation and adding the logic I want. I don't see a reason why not just adding those toggles here, in a non-breaking manner?

@magodo magodo reopened this Apr 11, 2023
@chlowell
Copy link
Member

DisableInstanceDiscovery is an advanced option I'm not fond of, but without it applications on e.g. Azure Stack can't use the type at all. I don't know a similarly compelling use case for an option like DisableManagedIdentity. If I understand your scenario correctly, you want to decide at runtime whether to skip managed identity authentication with code like this (please correct me if I misunderstand):

opts := azidentity.DefaultAzureCredentialOptions{}
if condition {
	opts.DisableManagedIdentity = true
}
cred, err := azidentity.NewDefaultAzureCredential(&opts)

Here's a way to get the same result with the current API:

var cred azcore.TokenCredential
if condition {
	cred, err := azidentity.NewAzureCLICredential(nil)
} else {
	cred, err := azidentity.NewManagedIdentityCredential(nil)
}

Does that work for your application? I'm sorry to have implied in my first response that more code is necessary.

@chlowell chlowell added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Apr 11, 2023
@github-actions github-actions bot removed the issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. label Apr 11, 2023
@github-actions
Copy link

Hi @magodo. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue.

@magodo
Copy link
Contributor Author

magodo commented Apr 12, 2023

@chlowell Yes, I could do that, whilst I still want to keep checking the environment variables for client certificate/secret auth method in the meanwhile. What I'm actually asking is kind of a togglable DefaultAzureCredential, which users can choose which methods to enable/disable via the option.

@github-actions github-actions bot added needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team and removed needs-author-feedback Workflow: More information is needed from author to address the issue. labels Apr 12, 2023
@RickWinter
Copy link
Member

By design we do not allow modifying which credentials the DefaultAzureCredential uses. If you would like fine grained control over which credential is used and in which order, the proper approach is to use the ChainedTokenCredential.
https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/azidentity#define-a-custom-authentication-flow-with-chainedtokencredential

@magodo
Copy link
Contributor Author

magodo commented Apr 13, 2023

@RickWinter Would you mind to point which design are your referring to? I didn't recall there is a design principle about how the default auth should be like in the Azure SDK design principle.

@magodo
Copy link
Contributor Author

magodo commented Apr 13, 2023

BTW, things like AdditionallyAllowedTenants are unwieldly designed and implemented in the default credential, which makes it consued to follow in a rewrite. The chain's name is private, the same for the implementation of the defaultCredentialErrorReporter 😓

@chlowell
Copy link
Member

Would you mind to point which design are your referring to? I didn't recall there is a design principle about how the default auth should be like in the Azure SDK design principle.

There's a note in the readme (see the bottom of this section). I'll add something similar to the API documentation.

Why do you want to rewrite DefaultAzureCredential? ChainedTokenCredential enables combining credential types however you like. Expanding on my example above:

env, err := azidentity.NewEnvironmentCredential(nil)
if err != nil {
	// TODO: handle error
}
creds := []azcore.TokenCredential{env}
if condition {
	mi, err := azidentity.NewManagedIdentityCredential(nil)
	if err != nil {
		// TODO: handle error
	}
	creds = append(creds, mi)
}
cli, err := azidentity.NewAzureCLICredential(nil)
if err != nil {
	// TODO: handle error
}
creds = append(creds, cli)
cred, err := azidentity.NewChainedTokenCredential(creds, nil)

@magodo
Copy link
Contributor Author

magodo commented Apr 17, 2023

@chlowell Thanks for the illustration! But I noticed the // TODO: handle error part is actually hard to implement in a sensible way without touch the private types (like error). Also, you are simplifying the MSI part that the default one uses a timeWrapper, which also access some private error type in its implementation. Meanwhile, you are simplifying the NewEnvironmentCredential in regards of its usage of its additionallyAllowedTenants fields.

@magodo magodo reopened this Apr 17, 2023
@magodo magodo closed this as completed Apr 17, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Azure.Identity feature-request This issue requires a new behavior in the product in order be resolved. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team
Projects
None yet
Development

No branches or pull requests

4 participants