Skip to content

[BUG] Multiple Scopes for AzureCliCredential not supported #48240

Open
@eluchsinger

Description

@eluchsinger

Library name and version

Azure.Identity 1.13.2

Describe the bug

Hey team.

The AzureCliCredential authentication differs from ManagedIdentity authentication. This only works when deployed to Azure using Managed Identity, obviously not locally, because we're using ManagedIdentityCredential.

var credential = new ChainedTokenCredential(
                new ManagedIdentityCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);

var result = await graphServiceClient.Users[userId]
                .Messages[emailId]
                .GetAsync();

Snipped simplified

But now the problem is that below code should work locally, but does not work. Azure CLI does not seem to know how to use multiple scopes.

var credential = new ChainedTokenCredential(
                new AzureCliCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);

var result = await graphServiceClient.Users[userId]
                .Messages[emailId]
                .GetAsync();

Snipped simplified

The exception is:

Exception: Azure.Identity.AuthenticationFailedException: The ChainedTokenCredential failed due to an unhandled exception: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> Azure.Identity.AuthenticationFailedException: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> System.ArgumentException: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
    at Azure.Identity.ScopeUtilities.ScopesToResource(String[] scopes)
    at Azure.Identity.AzureCliCredential.RequestCliAccessTokenAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
    at Azure.Identity.AzureCliCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)

This implementation difference leads to this code working on Azure, but not locally. It may be very big blocker, if this would prevent developers from using Managed Identity, because it's breaking local development.

Expected behavior

The AzureCliCredential should support multiple scopes and behave at least closely to how ManagedIdentity works.

Possible use cases that need this are for example (as shown in the snippets) accessing MS Graph using explicit scopes.

Actual behavior

AzureCliCredential throws an exception.

Exception: Azure.Identity.AuthenticationFailedException: The ChainedTokenCredential failed due to an unhandled exception: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> Azure.Identity.AuthenticationFailedException: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> System.ArgumentException: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
    at Azure.Identity.ScopeUtilities.ScopesToResource(String[] scopes)
    at Azure.Identity.AzureCliCredential.RequestCliAccessTokenAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
    at Azure.Identity.AzureCliCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)

Reproduction Steps

var credential = new ChainedTokenCredential(
                new AzureCliCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);

var result = await graphServiceClient.Users[userId]
                .Messages[emailId]
                .GetAsync();

Environment

.NET SDK:
Version: 9.0.102
Commit: cb83cd4923
Workload version: 9.0.100-manifests.43af17c7
MSBuild version: 17.12.18+ed8c6aec5

Metadata

Metadata

Assignees

Labels

Azure.IdentityClientThis issue points to a problem in the data-plane of the library.customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK teamquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type

Projects

Status

Untriaged

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions