Skip to content

Files

Latest commit

703efc5 · Jun 2, 2022

History

History
345 lines (219 loc) · 20.1 KB

managed-identity.md

File metadata and controls

345 lines (219 loc) · 20.1 KB
title description services author ms.service ms.custom ms.topic ms.date ms.author
Managed identities in Azure Container Apps
Using managed identities in Container Apps
container-apps
cebundy
container-apps
event-tier1-build-2022
how-to
06/02/2022
v-bcatherine

Managed identities in Azure Container Apps

A managed identity from Azure Active Directory (Azure AD) allows your container app to access other Azure AD-protected resources. For more about managed identities in Azure AD, see Managed identities for Azure resources.

Your container app can be granted two types of identities:

  • A system-assigned identity is tied to your container app and is deleted when your container 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 container app and other resources. A container app can have multiple user-assigned identities. The identity exists until you delete them.

Why use a managed identity?

You can use a managed identity in a running container app to authenticate to any service that supports Azure AD authentication.

With managed identities:

  • Your app connects to resources with the managed identity. You don't need to manage credentials in your container app.
  • You can use role-based access control to grant specific permissions to a managed identity.
  • System-assigned identities are automatically created and managed. They're deleted when your container app is deleted.
  • You can add and delete user-assigned identities and assign them to multiple resources. They're independent of your container app's life cycle.
  • You can use managed identity to authenticate with a private Azure Container Registry without a username and password to pull containers for your Container App.

Common use cases

System-assigned identities are best for workloads that:

  • are contained within a single resource
  • need independent identities

User-assigned identities are ideal for workloads that:

  • run on multiple resources and can share a single identity
  • need pre-authorization to a secure resource

Limitations

The identity is only available within a running container, which means you can't use a managed identity in scaling rules or Dapr configuration. To access resources that require a connection string or key, such as storage resources, you'll still need to include the connection string or key in the secretRef of the scaling rule.

Configure managed identities

You can configure your managed identities through:

  • the Azure portal
  • the Azure CLI
  • your Azure Resource Manager (ARM) template

When a managed identity is added, deleted, or modified on a running container app, the app doesn't automatically restart and a new revision isn't created.

Note

When adding a managed identity to a container app deployed before April 11, 2022, you must create a new revision.

Add a system-assigned identity

  1. In the left navigation of your container app's page, scroll down to the Settings group.

  2. Select Identity.

  3. Within the System assigned tab, switch Status to On. Select Save.

:::image type="content" source="media/managed-identity/screenshot-system-assigned-identity.png" alt-text="Screenshot of system-assigned identities.":::

Run the az containerapp identity assign command to create a system-assigned identity:

az containerapp identity assign --name myApp --resource-group myResourceGroup --system-assigned

An ARM template can be used to automate deployment of your container app and resources. To add a system-assigned identity, add an identity section to your ARM template.

"identity": {
    "type": "SystemAssigned"      
}

Adding the system-assigned type tells Azure to create and manage the identity for your application. For a complete ARM template example, see ARM API Specification.


Add a user-assigned identity

Configuring a container app with a user-assigned identity requires that you first create the identity then add its resource identifier to your container app's configuration. You can create user-assigned identities via the Azure portal or the Azure CLI. For information on creating and managing user-assigned identities, see Manage user-assigned managed identities.

First, you'll need to create a user-assigned identity resource.

  1. Create a user-assigned managed identity resource according to the steps found in Manage user-assigned managed identities.

  2. In the left navigation for your container app's page, scroll down to the Settings group.

  3. Select Identity.

  4. Within the User assigned tab, select Add.

  5. Search for the identity you created earlier and select it. Select Add.

:::image type="content" source="media/managed-identity/screenshot-user-assigned-identity.png" alt-text="Screenshot of user-assigned identities.":::

  1. Create a user-assigned identity.

    az identity create --resource-group <GROUP_NAME> --name <IDENTITY_NAME> --output json
    

    Note the id property of the new identity.

  2. Run the az containerapps identity assign command to assign the identity to the app. The identities parameter is a space separated list.

    az containerapp identity assign --resource-group <GROUP_NAME> --name <APP_NAME> \
        --user-assigned <IDENTITY_RESOURCE_ID>
    

    Replace <IDENTITY_RESOURCE_ID> with the id property of the identity. To assign more than one user-assigned identity, supply a space-separated list of identity IDs to the --user-assigned parameter.

To add one or more user-assigned identities, add an identity section to your ARM template. Replace <IDENTITY1_RESOURCE_ID> and <IDENTITY2_RESOURCE_ID> with the resource identifiers of the identities you want to add.

Specify each user-assigned identity by adding an item to the userAssignedIdentities object with the identity's resource identifier as the key. Use an empty object as the value.

"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "<IDENTITY1_RESOURCE_ID>": {},
        "<IDENTITY2_RESOURCE_ID>": {}
    }
}

For a complete ARM template example, see ARM API Specification.

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.


Configure a target resource

For some resources, you'll need to configure role assignments for your app's managed identity to grant access. Otherwise, calls from your app to services, such as Azure Key Vault and Azure SQL Database, will be rejected even if you use a valid token for that identity. To learn more about Azure role-based access control (Azure RBAC), see What is RBAC?. 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.

Connect to Azure services in app code

With managed identities, an app can obtain tokens to access Azure resources that use Azure Active Directory, such as Azure SQL Database, Azure Key Vault, and Azure Storage. These tokens represent the application accessing the resource, and not any specific user of the application.

Container Apps provides an internally accessible REST endpoint to retrieve tokens. The REST endpoint can be accessed from within the app with a standard HTTP GET, which can be implemented with a generic HTTP client in every language. For .NET, JavaScript, Java, and Python, the Azure Identity client library provides an abstraction over this REST endpoint. Connecting to other Azure services is as simple as adding a credential object to the service-specific client.

Note

When connecting to Azure SQL data sources with Entity Framework Core, consider using Microsoft.Data.SqlClient, which provides special connection strings for managed identity connectivity.

For .NET apps, the simplest way to work with a managed identity is through the Azure Identity client library for .NET. See the respective documentation headings of the client library for information:

The linked examples use DefaultAzureCredential. It's useful for most the scenarios because the same pattern works in Azure (with managed identities) and on your local machine (without managed identities).

For Node.js apps, the simplest way to work with a managed identity is through the Azure Identity client library for JavaScript. See the respective documentation headings of the client library for information:

The linked examples use DefaultAzureCredential. It's useful for most the scenarios because the same pattern works in Azure (with managed identities) and on your local machine (without managed identities).

For more code examples of the Azure Identity client library for JavaScript, see Azure Identity examples.

For Python apps, the simplest way to work with a managed identity is through the Azure Identity client library for Python. See the respective documentation headings of the client library for information:

The linked examples use DefaultAzureCredential. It's useful for most the scenarios because the same pattern works in Azure (with managed identities) and on your local machine (without managed identities).

For Java apps and functions, the simplest way to work with a managed identity is through the Azure Identity client library for Java. See the respective documentation headings of the client library for information:

The linked examples use DefaultAzureCredential. It's useful for most the scenarios because the same pattern works in Azure (with managed identities) and on your local machine (without managed identities).

For more code examples of the Azure Identity client library for Java, see Azure Identity Examples.

Use the following script to retrieve a token from the local endpoint by specifying a resource URI of an Azure service. Replace the place holder with the resource URI to obtain the token.

$resourceURI = "https://<AAD-resource-URI>"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers @{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token

A raw HTTP GET request looks like the following example.

X-IDENTITY-HEADER contains the GUID that is stored in the IDENTITY_HEADER environment variable.

GET http://localhost:42356/msi/token?resource=https://vault.azure.net&api-version=2019-08-01 HTTP/1.1
X-IDENTITY-HEADER: 853b9a84-5bfa-4b22-a3f3-0b9a43d9ad8a

A response might look like this example:

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"
}

This response is the same as the response for the Azure AD service-to-service access token request. To access Key Vault, you'll then add the value of access_token to a client connection with the vault.

REST endpoint reference

Note

An older version of this endpoint, 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.

A container app with a managed identity exposes the identity endpoint by defining two environment variables:

  • IDENTITY_ENDPOINT - local URL from which your container app can request tokens.
  • IDENTITY_HEADER - a header used to help mitigate server-side request forgery (SSRF) attacks. The value is rotated by the platform.

To get a token for a resource, make an HTTP GET request to the 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. The resource 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. Use "2019-08-01" or later.
X-IDENTITY-HEADER Header The value of the IDENTITY_HEADER environment variable. This header mitigates server-side request forgery (SSRF) attacks.
client_id Query (Optional) The client ID of the user-assigned identity to be used. Can't be used on a request that includes principal_id, mi_res_id, or object_id. If all ID parameters (client_id, principal_id, object_id, and mi_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. Can't 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, and mi_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. Can't be used on a request that includes principal_id, client_id, or object_id. If all ID parameters (client_id, principal_id, object_id, and mi_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.

For more information on the REST endpoint, see REST endpoint reference.


View managed identities

You can show the system-assigned and user-assigned managed identities using the following Azure CLI command. The output will show the managed identity type, tenant IDs and principal IDs of all managed identities assigned to your container app.

az containerapps identity show --name <APP_NAME> --resource-group <GROUP_NAME>

Remove a managed identity

When you remove a system-assigned identity, it's deleted from Azure Active Directory. System-assigned identities are also automatically removed from Azure Active Directory when you delete the container app resource itself. Removing user-assigned managed identities from your container app doesn't remove them from Azure Active Directory.

  1. In the left navigation of your app's page, scroll down to the Settings group.

  2. Select Identity. Then follow the steps based on the identity type:

    • System-assigned identity: Within the System assigned tab, switch Status to Off. Select Save.
    • User-assigned identity: Select the User assigned tab, select the checkbox for the identity, and select Remove. Select Yes to confirm.

To remove the system-assigned identity:

az containerapp identity remove --name <APP_NAME> --resource-group <GROUP_NAME> --system-assigned

To remove one or more user-assigned identities:

az containerapp identity remove --name <APP_NAME> --resource-group <GROUP_NAME> \
    --user-assigned <IDENTITY1_RESOURCE_ID> <IDENTITY2_RESOURCE_ID>

To remove all user-assigned identities:

az containerapp identity remove --name <APP_NAME> --resource-group <GROUP_NAME> \
    --user-assigned <IDENTITY1_RESOURCE_ID> <IDENTITY2_RESOURCE_ID>

To remove all identities, set the type of the container app's identity to None in the ARM template:

"identity": {
    "type": "None"
}

Next steps

[!div class="nextstepaction"] Monitor an app