Skip to content

AzureCredentialHelper breaks SP auth when AZURE_CLIENT_ID is set (regression in 13.2.0) #15537

@EmmittJ

Description

@EmmittJ

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

AzureCredentialHelper.CreateDefaultAzureCredential() introduced in 13.2.0 silently breaks
applications that use a Service Principal (client credentials) for Azure SDK auth alongside a
User-Assigned Managed Identity (UAMI) for infrastructure operations. Any app setting
AZURE_CLIENT_ID to an App Registration client ID will consistently fail all Cosmos DB
(and other Aspire-hosted Azure SDK) calls with a misleading managed identity error.

Background

A common deployment pattern on Azure App Service is:

  • A User-Assigned Managed Identity (UAMI) attached to the App Service for infrastructure
    operations (ACR image pull, Key Vault reference resolution).
  • An App Registration / Service Principal used by the application for Azure SDK calls,
    configured via AZURE_CLIENT_ID + AZURE_CLIENT_SECRET + AZURE_TENANT_ID.

These two identities coexist — the UAMI handles host-level operations, the SP credential
handles application-level SDK access.

What changed in 13.2.0

AzureCredentialHelper.CreateDefaultAzureCredential() was added in #14951 with the following logic:

// AzureCredentialHelper.cs
if (Environment.GetEnvironmentVariable(DefaultAzureCredential.DefaultEnvironmentVariableName) is not null)
    return new DefaultAzureCredential(DefaultAzureCredential.DefaultEnvironmentVariableName);

if (Environment.GetEnvironmentVariable("AZURE_CLIENT_ID") is not null)
{
    // When we don't see DefaultEnvironmentVariableName, but we do see AZURE_CLIENT_ID,
    // we just use ManagedIdentityCredential because that's the only credential type that
    // Aspire Hosting enables by default.
    return new ManagedIdentityCredential(new ManagedIdentityCredentialOptions());
}

AZURE_CLIENT_ID is shared between EnvironmentCredential (which expects an App Registration
client ID) and ManagedIdentityCredential (which expects a UAMI client ID). The helper assumes
any AZURE_CLIENT_ID present must be for a UAMI, which is incorrect.

new ManagedIdentityCredential(new ManagedIdentityCredentialOptions()) with no ManagedIdentityId
queries IMDS for the system-assigned identity. If only a UAMI is attached (no system-assigned
MI), IMDS returns HTTP 400 and every Azure SDK call fails immediately.

In 13.1.0, DefaultAzureCredential was used directly and EnvironmentCredential would succeed
as the first step in the chain. In 13.2.0 the error is consistent on every request.

Workaround

Set AZURE_TOKEN_CREDENTIALS=environmentcredential as an app setting. This causes the helper
to take path 1, creating only an EnvironmentCredential that picks up AZURE_CLIENT_ID,
AZURE_CLIENT_SECRET, and AZURE_TENANT_ID as before.

Alternatively, AZURE_TOKEN_CREDENTIALS=prod produces the full
EnvironmentCredential → WorkloadIdentityCredential → ManagedIdentityCredential chain.

Note: This is a breaking change from 13.1.0. The AZURE_TOKEN_CREDENTIALS workaround
requires an explicit environment change that was not necessary before upgrading. Apps that
worked on 13.1.0 and upgrade to 13.2.0 without setting this variable will begin failing
consistently with no other changes made.

Expected Behavior

EnvironmentCredential is attempted first (as it was in 13.1.0), succeeds using
AZURE_CLIENT_ID + AZURE_CLIENT_SECRET + AZURE_TENANT_ID, and all Cosmos DB calls
complete successfully.

Steps To Reproduce

  1. Create an Azure App Service with only a User-Assigned Managed Identity attached (no
    system-assigned MI).
  2. Set app settings: AZURE_CLIENT_ID = App Registration client ID, AZURE_CLIENT_SECRET,
    AZURE_TENANT_ID.
  3. Use Aspire.Microsoft.EntityFrameworkCore.Cosmos version 13.2.0 (or any other Aspire Azure
    component that calls AzureCredentialHelper.CreateDefaultAzureCredential()) without setting
    settings.Credential explicitly.
  4. Deploy and make any request that triggers a Cosmos DB operation.

Exceptions (if any)

ManagedIdentityCredential authentication failed: Unable to load the proper Managed Identity.
Microsoft.Identity.Client.MsalServiceException: [Managed Identity] Error Message: Unable to
load the proper Managed Identity. Managed Identity Correlation ID: <guid>
Use this Correlation ID for further investigation.

.NET Version info

  • .NET 10
  • Aspire 13.2.0 (regression from 13.1.0)
  • Azure.Identity 1.18.0
  • Host: Azure App Service (Linux), User-Assigned MI only, no system-assigned MI

Anything else?

Component: Aspire.Microsoft.EntityFrameworkCore.Cosmos — the same AzureCredentialHelper
is shared across other Aspire Azure components so the issue likely affects any of them under
the same deployment configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-integrationsIssues pertaining to Aspire Integrations packages

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions