How to use managed identities for App Service and Azure Functions
This topic shows you how to create a managed identity for App Service and Azure Functions applications and how to use it to access other resources.
Important
Managed identities for App Service and Azure Functions won't behave as expected if your app is migrated across subscriptions/tenants. The app needs to obtain a new identity, which is done by disabling and re-enabling the feature. See Removing an identity below. Downstream resources also need to have access policies updated to use the new identity.
A managed identity from Azure Active Directory (Azure AD) allows your app to easily access other Azure AD-protected resources such as Azure Key Vault. The identity is managed by the Azure platform and does not require you to provision or rotate any secrets. For more about managed identities in Azure AD, see Managed identities for Azure resources.
Your application can be granted two types of identities:
- A system-assigned identity is tied to your application and is deleted if your app is deleted. An app can only have one system-assigned identity.
- A user-assigned identity is a standalone Azure resource that can be assigned to your app. An app can have multiple user-assigned identities.
Add a system-assigned identity
Creating an app with a system-assigned identity requires an additional property to be set on the application.
Using the Azure portal
To set up a managed identity in the portal, you will first create an application as normal and then enable the feature.
Create an app in the portal as you normally would. Navigate to it in the portal.
If using a function app, navigate to Platform features. For other app types, scroll down to the Settings group in the left navigation.
Select Identity.
Within the System assigned tab, switch Status to On. Click Save.
Note
To find the managed identity for your web app or slot app in the Azure portal, under Enterprise applications, look in the User settings section. Usually, the slot name is similar to <app name>/slots/<slot name>
.
Using the Azure CLI
To set up a managed identity using the Azure CLI, you will need to use the az webapp identity assign
command against an existing application. You have three options for running the examples in this section:
- Use Azure Cloud Shell from the Azure portal.
- Use the embedded Azure Cloud Shell via the "Try It" button, located in the top-right corner of each code block below.
- Install the latest version of Azure CLI (2.0.31 or later) if you prefer to use a local CLI console.
The following steps will walk you through creating a web app and assigning it an identity using the CLI:
If you're using the Azure CLI in a local console, first sign in to Azure using az login. Use an account that's associated with the Azure subscription under which you would like to deploy the application:
az login
Create a web application using the CLI. For more examples of how to use the CLI with App Service, see App Service CLI samples:
az group create --name myResourceGroup --location westus az appservice plan create --name myPlan --resource-group myResourceGroup --sku S1 az webapp create --name myApp --resource-group myResourceGroup --plan myPlan
Run the
identity assign
command to create the identity for this application:az webapp identity assign --name myApp --resource-group myResourceGroup
Using Azure PowerShell
Note
This article has been updated to use the Azure Az PowerShell module. The Az PowerShell module is the recommended PowerShell module for interacting with Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
The following steps will walk you through creating an app and assigning it an identity using Azure PowerShell. The instructions for creating a web app and a function app are different.
Using Azure PowerShell for a web app
If needed, install the Azure PowerShell using the instructions found in the Azure PowerShell guide, and then run
Login-AzAccount
to create a connection with Azure.Create a web application using Azure PowerShell. For more examples of how to use Azure PowerShell with App Service, see App Service PowerShell samples:
# Create a resource group. New-AzResourceGroup -Name $resourceGroupName -Location $location # Create an App Service plan in Free tier. New-AzAppServicePlan -Name $webappname -Location $location -ResourceGroupName $resourceGroupName -Tier Free # Create a web app. New-AzWebApp -Name $webappname -Location $location -AppServicePlan $webappname -ResourceGroupName $resourceGroupName
Run the
Set-AzWebApp -AssignIdentity
command to create the identity for this application:Set-AzWebApp -AssignIdentity $true -Name $webappname -ResourceGroupName $resourceGroupName
Using Azure PowerShell for a function app
If needed, install the Azure PowerShell using the instructions found in the Azure PowerShell guide, and then run
Login-AzAccount
to create a connection with Azure.Create a function app using Azure PowerShell. For more examples of how to use Azure PowerShell with Azure Functions, see the Az.Functions reference:
# Create a resource group. New-AzResourceGroup -Name $resourceGroupName -Location $location # Create a storage account. New-AzStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroupName -SkuName $sku # Create a function app with a system-assigned identity. New-AzFunctionApp -Name $functionAppName -ResourceGroupName $resourceGroupName -Location $location -StorageAccountName $storageAccountName -Runtime $runtime -IdentityType SystemAssigned
You can also update an existing function app using Update-AzFunctionApp
instead.
Using an Azure Resource Manager template
An Azure Resource Manager template can be used to automate deployment of your Azure resources. To learn more about deploying to App Service and Functions, see Automating resource deployment in App Service and Automating resource deployment in Azure Functions.
Any resource of type Microsoft.Web/sites
can be created with an identity by including the following property in the resource definition:
"identity": {
"type": "SystemAssigned"
}
Note
An application can have both system-assigned and user-assigned identities at the same time. In this case, the type
property would be SystemAssigned,UserAssigned
Adding the system-assigned type tells Azure to create and manage the identity for your application.
For example, a web app might look like the following:
{
"apiVersion": "2016-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('appName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[variables('appName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"hostingEnvironment": "",
"clientAffinityEnabled": false,
"alwaysOn": true
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
]
}
When the site is created, it has the following additional properties:
"identity": {
"type": "SystemAssigned",
"tenantId": "<TENANTID>",
"principalId": "<PRINCIPALID>"
}
The tenantId property identifies what Azure AD tenant the identity belongs to. The principalId is a unique identifier for the application's new identity. Within Azure AD, the service principal has the same name that you gave to your App Service or Azure Functions instance.
If you need to reference these properties in a later stage in the template, you can do so via the reference()
template function with the 'Full'
flag, as in this example:
{
"tenantId": "[reference(resourceId('Microsoft.Web/sites', variables('appName')), '2018-02-01', 'Full').identity.tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites', variables('appName')), '2018-02-01', 'Full').identity.principalId]",
}
Add a user-assigned identity
Creating an app with a user-assigned identity requires that you create the identity and then add its resource identifier to your app config.
Using the Azure portal
First, you'll need to create a user-assigned identity resource.
Create a user-assigned managed identity resource according to these instructions.
Create an app in the portal as you normally would. Navigate to it in the portal.
If using a function app, navigate to Platform features. For other app types, scroll down to the Settings group in the left navigation.
Select Identity.
Within the User assigned tab, click Add.
Search for the identity you created earlier and select it. Click Add.
Using Azure PowerShell
Note
This article has been updated to use the Azure Az PowerShell module. The Az PowerShell module is the recommended PowerShell module for interacting with Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
The following steps will walk you through creating an app and assigning it an identity using Azure PowerShell.
Note
The current version of the Azure PowerShell commandlets for Azure App Service do not support user-assigned identities. The below instructions are for Azure Functions.
If needed, install the Azure PowerShell using the instructions found in the Azure PowerShell guide, and then run
Login-AzAccount
to create a connection with Azure.Create a function app using Azure PowerShell. For more examples of how to use Azure PowerShell with Azure Functions, see the Az.Functions reference. The below script also makes use of
New-AzUserAssignedIdentity
which must be installed separately as per Create, list or delete a user-assigned managed identity using Azure PowerShell.# Create a resource group. New-AzResourceGroup -Name $resourceGroupName -Location $location # Create a storage account. New-AzStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroupName -SkuName $sku # Create a user-assigned identity. This requires installation of the "Az.ManagedServiceIdentity" module. $userAssignedIdentity = New-AzUserAssignedIdentity -Name $userAssignedIdentityName -ResourceGroupName $resourceGroupName # Create a function app with a user-assigned identity. New-AzFunctionApp -Name $functionAppName -ResourceGroupName $resourceGroupName -Location $location -StorageAccountName $storageAccountName -Runtime $runtime -IdentityType UserAssigned -IdentityId $userAssignedIdentity.Id
You can also update an existing function app using Update-AzFunctionApp
instead.
Using an Azure Resource Manager template
An Azure Resource Manager template can be used to automate deployment of your Azure resources. To learn more about deploying to App Service and Functions, see Automating resource deployment in App Service and Automating resource deployment in Azure Functions.
Any resource of type Microsoft.Web/sites
can be created with an identity by including the following block in the resource definition, replacing <RESOURCEID>
with the resource ID of the desired identity:
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<RESOURCEID>": {}
}
}
Note
An application can have both system-assigned and user-assigned identities at the same time. In this case, the type
property would be SystemAssigned,UserAssigned
Adding the user-assigned type tells Azure to use the user-assigned identity specified for your application.
For example, a web app might look like the following:
{
"apiVersion": "2016-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('appName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
}
},
"properties": {
"name": "[variables('appName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"hostingEnvironment": "",
"clientAffinityEnabled": false,
"alwaysOn": true
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
]
}
When the site is created, it has the following additional properties:
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<RESOURCEID>": {
"principalId": "<PRINCIPALID>",
"clientId": "<CLIENTID>"
}
}
}
The principalId is a unique identifier for the identity that's used for Azure AD administration. The clientId is a unique identifier for the application's new identity that's used for specifying which identity to use during runtime calls.
Obtain tokens for Azure resources
An app can use its managed identity to get tokens to access other resources protected by Azure AD, such as Azure Key Vault. These tokens represent the application accessing the resource, and not any specific user of the application.
You may need to configure the target resource to allow access from your application. For example, if you request a token to access Key Vault, you need to make sure you have added an access policy that includes your application's identity. Otherwise, your calls to Key Vault will be rejected, even if they include the token. To learn more about which resources support Azure Active Directory tokens, see Azure services that support Azure AD authentication.
Important
The back-end services for managed identities maintain a cache per resource URI for around 24 hours. If you update the access policy of a particular target resource and immediately retrieve a token for that resource, you may continue to get a cached token with outdated permissions until that token expires. There's currently no way to force a token refresh.
There is a simple REST protocol for obtaining a token in App Service and Azure Functions. This can be used for all applications and languages. For .NET and Java, the Azure SDK provides an abstraction over this protocol and facilitates a local development experience.
Using the REST protocol
Note
An older version of this protocol, using the "2017-09-01" API version, used the secret
header instead of X-IDENTITY-HEADER
and only accepted the clientid
property for user-assigned. It also returned the expires_on
in a timestamp format. MSI_ENDPOINT can be used as an alias for IDENTITY_ENDPOINT, and MSI_SECRET can be used as an alias for IDENTITY_HEADER. This version of the protocol is currently required for Linux Consumption hosting plans.
An app with a managed identity has two environment variables defined:
- IDENTITY_ENDPOINT - the URL to the local token service.
- IDENTITY_HEADER - a header used to help mitigate server-side request forgery (SSRF) attacks. The value is rotated by the platform.
The IDENTITY_ENDPOINT is a local URL from which your app can request tokens. To get a token for a resource, make an HTTP GET request to this endpoint, including the following parameters:
Parameter name In Description resource Query The Azure AD resource URI of the resource for which a token should be obtained. This could be one of the Azure services that support Azure AD authentication or any other resource URI. api-version Query The version of the token API to be used. Please use "2019-08-01" or later (unless using Linux Consumption, which currently only offers "2017-09-01" - see note above). X-IDENTITY-HEADER Header The value of the IDENTITY_HEADER environment variable. This header is used to help mitigate server-side request forgery (SSRF) attacks. client_id Query (Optional) The client ID of the user-assigned identity to be used. Cannot be used on a request that includes principal_id
,mi_res_id
, orobject_id
. If all ID parameters (client_id
,principal_id
,object_id
, andmi_res_id
) are omitted, the system-assigned identity is used.principal_id Query (Optional) The principal ID of the user-assigned identity to be used. object_id
is an alias that may be used instead. Cannot be used on a request that includes client_id, mi_res_id, or object_id. If all ID parameters (client_id
,principal_id
,object_id
, andmi_res_id
) are omitted, the system-assigned identity is used.mi_res_id Query (Optional) The Azure resource ID of the user-assigned identity to be used. Cannot be used on a request that includes principal_id
,client_id
, orobject_id
. If all ID parameters (client_id
,principal_id
,object_id
, andmi_res_id
) are omitted, the system-assigned identity is used.
Important
If you are attempting to obtain tokens for user-assigned identities, you must include one of the optional properties. Otherwise the token service will attempt to obtain a token for a system-assigned identity, which may or may not exist.
A successful 200 OK response includes a JSON body with the following properties:
Property name Description access_token The requested access token. The calling web service can use this token to authenticate to the receiving web service. client_id The client ID of the identity that was used. expires_on The timespan when the access token expires. The date is represented as the number of seconds from "1970-01-01T0:0:0Z UTC" (corresponds to the token's exp
claim).not_before The timespan when the access token takes effect, and can be accepted. The date is represented as the number of seconds from "1970-01-01T0:0:0Z UTC" (corresponds to the token's nbf
claim).resource The resource the access token was requested for, which matches the resource
query string parameter of the request.token_type Indicates the token type value. The only type that Azure AD supports is Bearer. For more information about bearer tokens, see The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750).
This response is the same as the response for the Azure AD service-to-service access token request.
REST protocol examples
An example request might look like the following:
GET /MSI/token?resource=https://vault.azure.net&api-version=2019-08-01 HTTP/1.1
Host: localhost:4141
X-IDENTITY-HEADER: 853b9a84-5bfa-4b22-a3f3-0b9a43d9ad8a
And a sample response might look like the following:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJ0eXAi…",
"expires_on": "1586984735",
"resource": "https://vault.azure.net",
"token_type": "Bearer",
"client_id": "5E29463D-71DA-4FE0-8E69-999B57DB23B0"
}
Code examples
Tip
For .NET languages, you can also use Microsoft.Azure.Services.AppAuthentication instead of crafting this request yourself.
private readonly HttpClient _client;
// ...
public async Task<HttpResponseMessage> GetToken(string resource) {
var request = new HttpRequestMessage(HttpMethod.Get,
String.Format("{0}/?resource={1}&api-version=2019-08-01", Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT"), resource));
request.Headers.Add("X-IDENTITY-HEADER", Environment.GetEnvironmentVariable("IDENTITY_HEADER"));
return await _client.SendAsync(request);
}
Using the Microsoft.Azure.Services.AppAuthentication library for .NET
For .NET applications and functions, the simplest way to work with a managed identity is through the Microsoft.Azure.Services.AppAuthentication package. This library will also allow you to test your code locally on your development machine, using your user account from Visual Studio, the Azure CLI, or Active Directory Integrated Authentication. When hosted in the cloud, it will default to using a system-assigned identity, but you can customize this behavior using a connection string environment variable which references the client ID of a user-assigned identity. For more on development options with this library, see the Microsoft.Azure.Services.AppAuthentication reference. This section shows you how to get started with the library in your code.
Add references to the Microsoft.Azure.Services.AppAuthentication and any other necessary NuGet packages to your application. The below example also uses Microsoft.Azure.KeyVault.
Add the following code to your application, modifying to target the correct resource. This example shows two ways to work with Azure Key Vault:
using Microsoft.Azure.Services.AppAuthentication; using Microsoft.Azure.KeyVault; // ... var azureServiceTokenProvider = new AzureServiceTokenProvider(); string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://vault.azure.net"); // OR var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
If you want to use a user-assigned managed identity, you can set the AzureServicesAuthConnectionString
application setting to RunAs=App;AppId=<clientId-guid>
. Replace <clientId-guid>
with the client ID of the identity you want to use. You can define multiple such connection strings by using custom application settings and passing their values into the AzureServiceTokenProvider constructor.
var identityConnectionString1 = Environment.GetEnvironmentVariable("UA1_ConnectionString");
var azureServiceTokenProvider1 = new AzureServiceTokenProvider(identityConnectionString1);
var identityConnectionString2 = Environment.GetEnvironmentVariable("UA2_ConnectionString");
var azureServiceTokenProvider2 = new AzureServiceTokenProvider(identityConnectionString2);
To learn more about configuring AzureServiceTokenProvider and the operations it exposes, see the Microsoft.Azure.Services.AppAuthentication reference and the App Service and KeyVault with MSI .NET sample.
Using the Azure SDK for Java
For Java applications and functions, the simplest way to work with a managed identity is through the Azure SDK for Java. This section shows you how to get started with the library in your code.
Add a reference to the Azure SDK library. For Maven projects, you might add this snippet to the
dependencies
section of the project's POM file:<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure</artifactId> <version>1.23.0</version> </dependency>
Use the
AppServiceMSICredentials
object for authentication. This example shows how this mechanism may be used for working with Azure Key Vault:import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.keyvault.Vault //... Azure azure = Azure.authenticate(new AppServiceMSICredentials(AzureEnvironment.AZURE)) .withSubscription(subscriptionId); Vault myKeyVault = azure.vaults().getByResourceGroup(resourceGroup, keyvaultName);
Remove an identity
A system-assigned identity can be removed by disabling the feature using the portal, PowerShell, or CLI in the same way that it was created. User-assigned identities can be removed individually. To remove all identities, set the identity type to "None".
Removing a system-assigned identity in this way will also delete it from Azure AD. System-assigned identities are also automatically removed from Azure AD when the app resource is deleted.
To remove all identities in an ARM template:
"identity": {
"type": "None"
}
To remove all identities in Azure PowerShell (Azure Functions only):
# Update an existing function app to have IdentityType "None".
Update-AzFunctionApp -Name $functionAppName -ResourceGroupName $resourceGroupName -IdentityType None
Note
There is also an application setting that can be set, WEBSITE_DISABLE_MSI, which just disables the local token service. However, it leaves the identity in place, and tooling will still show the managed identity as "on" or "enabled." As a result, use of this setting is not recommended.