Configure an application to trust a managed identity (preview)

This article describes how to configure a Microsoft Entra application to trust a managed identity. You can then exchange the managed identity token for an access token that can access Microsoft Entra protected resources without needing to use or manage App secrets.

Prerequisites

Important considerations and restrictions

To create, update, or delete a federated identity credential, the account performing the action must have the Application Administrator, Application Developer, Cloud Application Administrator, or Application Owner role. The microsoft.directory/applications/credentials/update permission is required to update a federated identity credential.

A maximum of 20 federated identity credentials can be added to an application or user-assigned managed identity.

When you configure a federated identity credential, there are several important pieces of information to provide:

  • issuer and subject are the key pieces of information needed to set up the trust relationship. The combination of issuer and subject must be unique on the app. When the Azure workload requests Microsoft identity platform to exchange the Managed Identity token for an access token, the issuer and subject values of the federated identity credential are checked against the issuer and subject claims provided in the Managed Identity token. If that validation check passes, Microsoft identity platform issues an access token to the external software workload.

  • issuer is the URL of the Microsoft Entra tenant's Authority URL in the form https://login.microsoftonline.com/{tenant}/v2.0. The Microsoft Entra App and the Managed Identity must belong to the same tenant. If the issuer claim has leading or trailing whitespace in the value, the token exchange is blocked.

    Important

    Although the app registration and the managed identity must be in the same tenant, the service principal of the app registration can still redeem the managed identity token.

  • subject is the GUID of the Managed Identity's Object ID (Principal ID) assigned to the Azure workload. The Microsoft identity platform looks at the incoming external token and rejects the exchange for an access token if the subject field configured in the Federated Identity Credential doesn't match the Principal ID of the Managed Identity. The GUID is case sensitive.

  • Important

    You can only use User-Assigned Managed Identities in this feature.

  • *audiences list the audiences that can appear in the external token (Required). You must add a single audience value, which has a limit of 600 characters. The value must be one of the following and must match the value of the aud claim in the Managed Identity token.

    • Public cloud: api://AzureADTokenExchange
    • Fairfax: api://AzureADTokenExchangeUSGov
    • Mooncake: api://AzureADTokenExchangeChina
    • USNat: api://AzureADTokenExchangeUSNat
    • USSec: api://AzureADTokenExchangeUSSec

    Important

    If you accidentally add incorrect information in the issuer, subject or audience setting the federated identity credential is created successfully without error. The error does not become apparent until the token exchange fails.

  • name is the unique identifier for the federated identity credential. (Required) This field has a character limit of 3-120 characters and must be URL friendly. Alphanumeric, dash, or underscore characters are supported, and the first character must be alphanumeric only. It's immutable once created.

  • description is the user-provided description of the federated identity credential (Optional). The description isn't validated or checked by Microsoft Entra ID. This field has a limit of 600 characters.

Wildcard characters aren't supported in any federated identity credential property value.

Get the Object ID of the managed identity

  1. Sign in to the Azure portal.
  2. In the search box, enter Managed Identities. Under Services, select Managed Identities.
  3. Search for and select the user-assigned managed identity you created as part of the prerequisites.
  4. In the Overview pane, copy the Object (principal) ID value. This value is used as the subject field in the federated credential configuration.

Screenshot of a user-assigned managed identity in the Azure portal. The Object ID is highlighted which will be used as the *subject* field in the federated credential configuration.

Configure a federated identity credential on an existing application

In this section, you'll configure a federated identity credential on an existing application to trust a managed identity. Use the following tabs to choose how to configure a federated identity credential on an existing application.

  1. Sign in to the Microsoft Entra admin center. Check that you are in the tenant where your application is registered.

  2. Browse to Identity > Applications > App registrations, and select your application in the main window.

  3. Under Manage, select Certificates & secrets.

  4. Select the Federated credentials tab and select Add credential.

    Screenshot of the certificates and secrets pane of the Microsoft Entra admin center with the federated credentials tab highlighted.

  5. From the Federated credential scenario dropdown, select Other Issuer and fill in the values according to the following table:

    Field Description Example
    Issuer The OAuth 2.0 / OIDC issuer URL of the Microsoft Entra ID authority. https://login.microsoftonline.com/{tenantID}/v2.0
    Subject identifier The Principal ID GUID of the Managed Identity. aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb
    Name A unique descriptive name for the credential. msi-webapp1
    Description (Optional) A user-provided description of the federated identity credential. Trust the workloads UAMI to impersonate the App
    Audience The audience value that must appear in the external token. Public cloud: api://AzureADTokenExchange
    Fairfax: api://AzureADTokenExchangeUSGov
    Mooncake: api://AzureADTokenExchangeChina
    USNat: api://AzureADTokenExchangeUSNat
    USSec: api://AzureADTokenExchangeUSSec

    Screenshot of the credential window in the Microsoft Entra admin center.

Update your application code to request an access token

The following code samples in the following table show client credential "service to service" flows. However, managed identities as a credential can be used in other authentication flows such as on-behalf-of (OBO) flows. The samples are valid in both cases where the resource tenant is in the same tenant as the app registration and the Managed identity or a different tenant.

Azure.Identity

The following example demonstrates how to connect to an Azure storage container using Azure.Identity, but can be adapted to access any resource protected by Microsoft Entra. The samples are valid in both cases where the resource tenant is in the same tenant as the app registration and the managed identity or a different tenant.

using Azure.Identity;
using Azure.Storage.Blobs;

internal class Program
{
    // This example demonstrates how to access an Azure blob storage account by utilizing the manage identity credential.
  static void Main(string[] args)
  {
        string storageAccountName = "YOUR_STORAGE_ACCOUNT_NAME";
        string containerName = "CONTAINER_NAME";
        
        // The application must be granted access on the target resource
      string appClientId = "YOUR_APP_CLIENT_ID";

        // The tenant where the target resource is created, in this example, the storage account tenant
        // If the resource tenant different from the app tenant, your app needs to be 
      string resourceTenantId = "YOUR_RESOURCE_TENANT_ID";

        // The managed identity which you configured as a Federated Identity Credential (FIC)
      string miClientId = "YOUR_MANAGED_IDENTITY_CLIENT_ID"; 

        // Audience value must be one of the below values depending on the target cloud.
        // Public cloud: api://AzureADTokenExchange
        //  Fairfax: api://AzureADTokenExchangeUSGov
        //  Mooncake: api://AzureADTokenExchangeChina
        //  USNat: api://AzureADTokenExchangeUSNat
        //  USSec: api://AzureADTokenExchangeUSSec
      string audience = "api://AzureADTokenExchange";

        // 1. Create an assertion with the managed identity access token, so that it can be exchanged an app token
        var miCredential = new ManagedIdentityCredential(managedIdentityClientId);
        ClientAssertionCredential assertion = new(
            tenantId,
            appClientId,
            async (token) =>
            {
                // fetch Managed Identity token for the specified audience
                var tokenRequestContext = new Azure.Core.TokenRequestContext(new[] { $"{audience}/.default" });
                var accessToken = await miCredential.GetTokenAsync(tokenRequestContext).ConfigureAwait(false);
                return accessToken.Token;
            });

        // 2. The assertion can be used to obtain an App token (taken care of by the SDK)
        var containerClient  = new BlobContainerClient(new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}"), assertion);

        await foreach (BlobItem blob in containerClient.GetBlobsAsync())
        {
            // TODO: perform operations with the blobs
            BlobClient blobClient = containerClient.GetBlobClient(blob.Name);
            Console.WriteLine($"Blob name: {blobClent.Name}, uri: {blobClient.Uri}");            
        }
  }
}

Microsoft.Identity.Web

In Microsoft.Identity.Web, a web application or web API can replace the client certificate with a signed client assertion for authentication. In your application, you can update the ClientCredentials section in your appsettings.json to the following configuration:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "YOUR_APPLICATION_ID",
    "TenantId": "YOUR_TENANT_ID",

   "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "YOUR_USER_ASSIGNED_MANAGED_IDENTITY_CLIENT_ID",
        "TokenExchangeUrl":"api://AzureADTokenExchange"
      }
   ]
  }
}

MSAL (.NET)

In MSAL, you can use the ManagedClientApplication class to acquire a Managed Identity token. This token can then be used as a client assertion when constructing a confidential client application.

Warning

For .NET apps, we strongly advise to use higher-level libraries that are based on MSAL, such as Microsoft.Identity.Web or Azure.Identity.

using Microsoft.Identity.Client;
using Azure.Storage.Blobs;
using Azure.Core;

internal class Program
{
  static async Task Main(string[] args)
  {
        string storageAccountName = "YOUR_STORAGE_ACCOUNT_NAME";
        string containerName = "CONTAINER_NAME";

      string appClientId = "YOUR_APP_CLIENT_ID";
      string resourceTenantId = "YOUR_RESOURCE_TENANT_ID";
      Uri authorityUri = new($"https://login.microsoftonline.com/{resourceTenantId}");
      string miClientId = "YOUR_MI_CLIENT_ID";
      string audience = "api://AzureADTokenExchange";

      // Get mi token to use as assertion
      var miAssertionProvider = async (AssertionRequestOptions _) =>
      {
            var miApplication = ManagedIdentityApplicationBuilder
                .Create(ManagedIdentityId.WithUserAssignedClientId(miClientId))
                .Build();

            var miResult = await miApplication.AcquireTokenForManagedIdentity(audience)
                .ExecuteAsync()
                .ConfigureAwait(false);
            return miResult.AccessToken;
      };

      // Create a confidential client application with the assertion.
      IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(appClientId)
        .WithAuthority(authorityUri, false)
        .WithClientAssertion(miAssertionProvider)
        .WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
        .Build();

        // Get the federated app token for the storage account
      string[] scopes = [$"https://{storageAccountName}.blob.core.windows.net/.default"];
      AuthenticationResult result = await app.AcquireTokenForClient(scopes).ExecuteAsync().ConfigureAwait(false);

        TokenCredential tokenCredential = new AccessTokenCredential(result.AccessToken);
        var client = new BlobContainerClient(
            new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}"),
            tokenCredential);

        await foreach (BlobItem blob in containerClient.GetBlobsAsync())
        {
            // TODO: perform operations with the blobs
            BlobClient blobClient = containerClient.GetBlobClient(blob.Name);
            Console.WriteLine($"Blob name: {blobClient.Name}, URI: {blobClient.Uri}");
        }
  }
}

See also