Skip to content

[Feature Request] Uniform Managed Identity client credential for authorization code redemption across App Service (IMDS) and AKS Workload Identity #3861

Description

@adangelo-mylight150

Microsoft.Identity.Web Library

Microsoft.Identity.Web

Microsoft.Identity.Web version

4.10.0

Web app

Sign-in users (authorization code flow)

Web API

Not Applicable

Token cache serialization

Not Applicable

Description

We run the same ASP.NET Core web applications in a dual-run topology: the exact same container image is deployed both on Azure App Service and on Azure Kubernetes Service (AKS) with Microsoft Entra Workload ID.

Our goal is a single, uniform configuration that behaves identically in both hosting environments — same image and same configuration.

We also want to keep the user-assigned Managed Identity as the single central pivot for accessing all Azure resources. The Managed Identities already allows to access Azure resources, is given permission (app roles) to call downstream api with app token, and we set up FIC between the managed identity and an app registration for when using the MI as the client credential when redeeming the authorization code.

All works well in Azure App Service and we did managed to make it work on AKS with AKS FIC on the managed identity, but for the Authorization code call.

Expected behavior

Redeem the authorization code on behalf of the managed identity from an AKS workload.

We don’t want to configure a FIC on the app registration with the identity of the Workload

What works today

  • On App ServiceSignedAssertionFromManagedIdentity works, because IMDS is reachable and ManagedIdentityClientAssertion can obtain the MI-signed assertion.
"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "TenantId": "<tenant-id>",
  "ClientId": "<web-application-app-registration-client-id>",
  "ResponseType": "code",
  "ClientCredentials": [
    {
      "SourceType": "SignedAssertionFromManagedIdentity",
      "ManagedIdentityClientId": "<mi-client-id>"
    }
  ]
}

The app registration has a FIC that trusts the Managed Identity as the assertion issuer/subject. On App Service this resolves correctly and as expected.

What fails

On AKS with Workload Identity, the same configuration, as expected, fails during authorization code redemption:

ArgumentException: IDW10109: No credential could be loaded. [...]
Credential SignedAssertionFromManagedIdentity=<mi-client-id> failed because:
MSAL.NetCore.4.84.1.0.MsalServiceException:
ErrorCode: managed_identity_request_failed
Microsoft.Identity.Client.MsalServiceException: [Managed Identity] Authentication unavailable.
Either the requested identity has not been assigned to this resource,
or other errors could be present. [...]
Status: BadRequest
Content: {"error":"invalid_request","error_description":"Identity not found"}

The following configuration is working, but it requires adding a FIC with the cluster as the issuer and the service account as the subject on the app registration (which is precisely what we want to avoid).

"AzureAd": {
  "Instance": "<https://login.microsoftonline.com/>",
  "TenantId": "<tenant-id>",
  "ClientId": "<web-application-app-registration-client-id>",
  "ResponseType": "code",
  "ClientCredentials": [
    {
      "SourceType": "SignedAssertionFilePath"
    }
  ]
}

What we tried

We exchanged the Workload Identity token (AZURE_FEDERATED_TOKEN_FILE) for Managed Identity Token and tried to use that token as a client assertion to redeem the authorization code. The idea is to provide a custom client signed assertion provider :

var clientId = configuration.GetValue<string>("AZURE_CLIENT_ID");
var scope = "api://AzureADTokenExchange/.default";

var credential = new WorkloadIdentityCredential(
    new WorkloadIdentityCredentialOptions
    {
        ClientId = clientId
    });

var tokenRequestContext = new TokenRequestContext([scope]);
var accessToken = await credential.GetTokenAsync(tokenRequestContext, cancellationToken);

Exchanging that projected token for an Entra access token and reusing it as a client_assertion is explicitly rejected with AADSTS700231 (a token obtained via a federated identity credential may not be used as a federated identity credential).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions