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
- An Azure account with an active subscription. Create an account for free.
- This Azure account must have permissions to manage applications, specifically to update permissions. Any of the following Microsoft Entra roles include the required permissions:
- An understanding of the concepts in managed identities for Azure resources.
- A user-assigned managed identity assigned to the Azure compute resource (for example, a virtual machine or Azure App Service) that hosts your workload.
- An app registration in Microsoft Entra ID. This app registration must belong to the same tenant as the managed identity
- If you need to access resources in another tenant, your app registration must be a multitenant application and provision the app into the other tenant. Additionally, you must grant the app access permissions on the resources in that tenant. Learn about how to add a multitenant app in other tenants
- The app registration must have access granted to Microsoft Entra protected resources (for example, Azure, Microsoft Graph, Microsoft 365, etc.). This access can be granted through API permissions or delegated permissions.
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
andsubject
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 theissuer
andsubject
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 theissuer
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.
- Public cloud:
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
- Sign in to the Azure portal.
- In the search box, enter Managed Identities. Under Services, select Managed Identities.
- Search for and select the user-assigned managed identity you created as part of the prerequisites.
- In the Overview pane, copy the Object (principal) ID value. This value is 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.
Sign in to the Microsoft Entra admin center. Check that you are in the tenant where your application is registered.
Browse to Identity > Applications > App registrations, and select your application in the main window.
Under Manage, select Certificates & secrets.
Select the Federated credentials tab and select Add credential.
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
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}");
}
}
}