Connecting from your application to resources without handling credentials

Azure resources with managed identities support always provide an option to specify a managed identity to connect to Azure resources that support Microsoft Entra authentication. Managed identities support makes it unnecessary for developers to manage credentials in code. Managed identities are the recommended authentication option when working with Azure resources that support them. Read an overview of managed identities.

This page demonstrates how to configure an App Service so it can connect to Azure Key Vault, Azure Storage, and Microsoft SQL Server. The same principles can be used for any Azure resource that supports managed identities and that will connect to resources that support Microsoft Entra authentication.

The code samples use the Azure Identity client library, which is the recommended method as it automatically handles many of the steps for you, including acquiring an access token used in the connection.

What resources can managed identities connect to?

A managed identity can connect to any resource that supports Microsoft Entra authentication. In general, there's no special support required for the resource to allow managed identities to connect to it.

Some resources don't support Microsoft Entra authentication, or their client library doesn't support authenticating with a token. Keep reading to see our guidance on how to use a Managed identity to securely access the credentials without needing to store them in your code or application configuration.

Creating a managed identity

There are two types of managed identities: system-assigned and user-assigned. System-assigned identities are directly linked to a single Azure resource. When the Azure resource is deleted, so is the identity. A user-assigned managed identity can be associated with multiple Azure resources, and its lifecycle is independent of those resources.

We recommend that you use a user-assigned managed identity, for most scenarios. If the source resource you're using doesn't support user-assigned managed identities, then you should refer to that resource provider's documentation to learn how to configure it to have a system-assigned managed identity.

Important

The account used to create managed identities needs a role such as "Managed Identity Contributor" to create a new user-assigned managed identity.

Create a user-assigned managed identity using your preferred option:

After you create a user-assigned managed identity, take note of the clientId and the principalId values that are returned when the managed identity is created. You use principalId while adding permissions, and clientId in your application's code.

Configure App Service with a user-assigned managed identity

Before you can use the managed identity in your code, we have to assign it to the App Service that will use it. The process of configuring an App Service to use a user-assigned managed identity requires that you specify the managed identity's resource identifier in your app config.

Adding permissions to the identity

Once you've configured your App Service to use a user-assigned managed identity, grant the necessary permissions to the identity. In this scenario, we're using this identity to interact with Azure Storage, so you need to use the Azure Role Based Access Control (RBAC) system to grant the user-assigned managed identity permissions to the resource.

Important

You'll need a role such as "User Access Administrator" or "Owner" for the target resource to add Role assignments. Ensure you're granting the least privilege required for the application to run.

Any resources you want to access requires that you grant the identity permissions. For example, if you request a token to access Key Vault, you must also add an access policy that includes the managed identity of your app or function. Otherwise, your calls to Key Vault will be rejected, even if you use a valid token. The same is true for Azure SQL Database. To learn more about which resources support Microsoft Entra tokens, see Azure services that support Microsoft Entra authentication.

Using managed identities in your code

After you complete the steps outlined above, your App Service has a managed identity with permissions to an Azure resource. You can use the managed identity to obtain an access token that your code can use to interact with Azure resources, instead of storing credentials in your code.

We recommended that you use the client libraries that we provide for your preferred programming language. These libraries acquire access tokens for you, making it easy to authenticate with Microsoft Entra ID. For more information, see Client libraries for managed identities authentication.

Using an Azure Identity library to access Azure resources

The Azure Identity libraries each provide a DefaultAzureCredential type. DefaultAzureCredential attempts to automatically authenticate the user through different flows, including environment variables or an interactive sign-in. The credential type can be used in a development environment with your own credentials. It can also be used in your production Azure environment using a managed identity. No code changes are required when you deploy your application.

If you're using user-assigned managed identities, you should also explicitly specify the user-assigned managed identity you wish to authenticate with by passing in the identity's client ID as a parameter. You can retrieve the client ID by browsing to the identity in the Azure portal.

Accessing a Blob in Azure Storage

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

// code omitted for brevity

// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
    ManagedIdentityClientId = clientID
};
var credential = new DefaultAzureCredential(credentialOptions);                        

var blobServiceClient1 = new BlobServiceClient(new Uri("<URI of Storage account>"), credential);
BlobContainerClient containerClient1 = blobServiceClient1.GetBlobContainerClient("<name of blob>");
BlobClient blobClient1 = containerClient1.GetBlobClient("<name of file>");

if (blobClient1.Exists())
{
    var downloadedBlob = blobClient1.Download();
    string blobContents = downloadedBlob.Value.Content.ToString();                
}

Accessing a secret stored in Azure Key Vault

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;

// code omitted for brevity

// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
    ManagedIdentityClientId = clientID
};
var credential = new DefaultAzureCredential(credentialOptions);        

var client = new SecretClient(
    new Uri("https://<your-unique-key-vault-name>.vault.azure.net/"),
    credential);
    
KeyVaultSecret secret = client.GetSecret("<my secret>");
string secretValue = secret.Value;

Accessing Azure SQL Database

using Azure.Identity;
using Microsoft.Data.SqlClient;

// code omitted for brevity

// Specify the Client ID if using user-assigned managed identities
var clientID = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID");
var credentialOptions = new DefaultAzureCredentialOptions
{
    ManagedIdentityClientId = clientID
};

AccessToken accessToken = await new DefaultAzureCredential(credentialOptions).GetTokenAsync(
    new TokenRequestContext(new string[] { "https://database.windows.net//.default" }));                        

using var connection = new SqlConnection("Server=<DB Server>; Database=<DB Name>;")
{
    AccessToken = accessToken.Token
};
var cmd = new SqlCommand("select top 1 ColumnName from TableName", connection);
await connection.OpenAsync();
SqlDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
    Console.WriteLine(dr.GetValue(0).ToString());
}
dr.Close();	

Using the Microsoft Authentication Library (MSAL) to access Azure resources

Apart from the Azure Identity libraries, you can also use MSAL to access Azure resources using managed identities. The following code snippets demonstrate how to use MSAL to access Azure resources in various programming languages.

For system-assigned managed identities, the developer doesn't need to pass any additional information. MSAL automatically infers the relevant metadata about the assigned identity. For user-assigned managed identities, the developer needs to pass either the client ID, full resource identifier, or the object ID of the managed identity.

You can then acquire a token to access a resource. Prior to using managed identities, developers must enable them for the resources they want to use.

using Microsoft.Identity.Client;
using System;

string resource = "https://vault.azure.net";

// Applies to system-assigned managed identities only
IManagedIdentityApplication mi = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned)
    .Build();

// Applies to user-assigned managed identities only
string userAssignedManagedIdentityClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
IManagedIdentityApplication mi = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.WithUserAssignedClientId(userAssignedManagedIdentityClientId))
    .Build();

// Acquire token
AuthenticationResult result = await mi.AcquireTokenForManagedIdentity(resource)
    .ExecuteAsync()
    .ConfigureAwait(false);

if (!string.IsNullOrEmpty(result.AccessToken))
{
    Console.WriteLine(result.AccessToken);
}

Connecting to resources that don't support Microsoft Entra ID or token based authentication in libraries

Some Azure resources either don't yet support Microsoft Entra authentication, or their client libraries don't support authenticating with a token. Typically these resources are open-source technologies that expect a username and password or an access key in a connection string.

To avoid storing credentials in your code or your application configuration, you can store the credentials as a secret in Azure Key Vault. Using the example displayed above, you can retrieve the secret from Azure KeyVault using a managed identity, and pass the credentials into your connection string. This approach means that no credentials need to be handled directly in your code or environment. For a detailed example, see Use managed identities to access Azure Key Vault certificates. For more info on Azure Key Vault authentication, see Azure Key Vault authentication.

Guidelines if you're handling tokens directly

In some scenarios, you may want to acquire tokens for managed identities manually instead of using a built-in method to connect to the target resource. These scenarios include no client library for the programming language that you're using or the target resource you're connecting to, or connecting to resources that aren't running on Azure. When acquiring tokens manually, we provide the following guidelines:

Cache the tokens you acquire

For performance and reliability, we recommend that your application caches tokens in local memory, or encrypted if you want to save them to disk. As Managed identity tokens are valid for 24 hours, there's no benefit in requesting new tokens regularly, as a cached one will be returned from the token issuing endpoint. If you exceed the request limits, you'll be rate limited and receive an HTTP 429 error.

When you acquire a token, you can set your token cache to expire 5 minutes before the expires_on (or equivalent property) that will be returned when the token is generated.

Token inspection

Your application shouldn't rely on the contents of a token. The token's content is intended only for the audience (target resource) that is being accessed, not the client that's requesting the token. The token content may change or be encrypted in the future.

Don't expose or move tokens

Tokens should be treated like credentials. Don't expose them to users or other services; for example, logging/monitoring solutions. They shouldn't be moved from the source resource that's using them, other than to authenticate against the target resource.

Next steps