This chapter covers Managed Identities in Azure, a feature that allows Azure resources to authenticate to other Azure services without storing credentials in code. Managed Identities are a critical topic for the AZ-204 exam, appearing in approximately 10-15% of questions, especially those related to security, authentication, and Key Vault integration. Understanding how to enable, configure, and use Managed Identities—both system-assigned and user-assigned—is essential for developing secure cloud applications. We will explore the underlying mechanism, step-by-step setup, common scenarios, and exam traps.
Jump to a section
Imagine a large office building where employees need to access various secured rooms. Instead of giving each employee a physical key (password) that can be lost or copied, the building uses a badge system. Each employee gets a badge with a unique ID, and the building's directory service (Azure AD) knows which rooms (resources) each badge can access. When an employee enters a room, they simply tap their badge on a reader. The reader contacts the directory service, which verifies the employee's identity and permissions, and then issues a temporary access token (like a keycard that works for only that room and only for a few minutes). The employee never handles the actual key; they just present their badge. If the employee is terminated, the badge is deactivated in the directory, and access is revoked everywhere—no need to change locks. This is exactly how Managed Identities work: Azure resources (the employees) get an identity (badge) managed by Azure AD, and they use that identity to obtain tokens (temporary access) for other Azure resources (rooms), without ever storing credentials in code or configuration.
What Are Managed Identities and Why Do They Exist?
Managed Identities (formerly known as Managed Service Identities, MSI) provide Azure services with an automatically managed identity in Azure Active Directory. This identity can be used to authenticate to any service that supports Azure AD authentication, such as Key Vault, Storage, SQL Database, and more. The primary benefit is eliminating the need for developers to manage credentials—no connection strings, no client secrets, no certificates stored in app settings or code. This reduces security risks and operational overhead.
How Managed Identities Work Internally
There are two types: System-assigned and User-assigned.
System-assigned Managed Identity is enabled directly on an Azure resource (e.g., a Virtual Machine, App Service, or Function App). When enabled, Azure creates a service principal of the same name as the resource in the Azure AD tenant trusted by the subscription. The lifecycle of this identity is tied to the resource: if the resource is deleted, the identity is automatically removed.
User-assigned Managed Identity is created as a standalone Azure resource. It can be assigned to one or more Azure resources. Its lifecycle is independent of any resource; deleting a resource does not delete the identity. This allows reuse across multiple resources.
When a resource with a Managed Identity requests a token, the Azure Instance Metadata Service (IMDS) endpoint at 169.254.169.254 is used. The process is as follows:
The application code calls ManagedIdentityCredential from the Azure Identity SDK (or equivalent) to request a token for a specific resource (e.g., https://vault.azure.net for Key Vault).
The SDK sends an HTTP GET request to the IMDS endpoint: http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net. The request includes a header Metadata: true (required).
The IMDS endpoint contacts Azure AD (via a well-known endpoint like login.microsoftonline.com) and obtains an access token for the specified resource, using the service principal associated with the Managed Identity.
Azure AD returns the token to IMDS, which forwards it to the application.
The application uses the token in the Authorization header when calling the target resource.
Key Components, Values, Defaults, and Timers
IMDS endpoint: 169.254.169.254 (link-local IP, not routable from outside the VM/App Service).
API version: 2018-02-01 (the latest stable version as of 2021).
Resource parameter: The audience for the token, e.g., https://vault.azure.net for Key Vault, https://storage.azure.com for Storage, https://management.azure.com for Azure Resource Manager.
Token lifetime: Azure AD access tokens are valid for 1 hour by default. The SDK handles caching and refreshing automatically. The ManagedIdentityCredential in Azure.Identity SDK caches tokens in memory.
Supported resources: App Service, Azure VMs, Azure Functions, Azure Container Instances, Azure Kubernetes Service, Logic Apps, API Management, and more.
Configuration and Verification Commands
Enable system-assigned identity on a VM using Azure CLI:
az vm identity assign -g MyResourceGroup -n MyVmEnable system-assigned identity on an App Service:
az webapp identity assign -g MyResourceGroup -n MyAppCreate a user-assigned identity:
az identity create -g MyResourceGroup -n MyUserIdentityAssign user-assigned identity to a VM:
az vm identity assign -g MyResourceGroup -n MyVm --identities /subscriptions/.../providers/Microsoft.ManagedIdentity/userAssignedIdentities/MyUserIdentityGet the client ID of a user-assigned identity:
az identity show -g MyResourceGroup -n MyUserIdentity --query clientIdTest token acquisition from a VM (via curl):
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net' -H Metadata:trueGrant the identity access to Key Vault:
az keyvault set-policy --name MyVault --object-id <principal-id> --secret-permissions get listHow It Interacts with Related Technologies
Azure Key Vault: Managed Identities are the recommended way to access Key Vault from Azure resources. The identity must be granted appropriate permissions (e.g., get, list for secrets).
Azure Storage: Use Managed Identity to access Blob Storage, Queue Storage, etc. Assign RBAC role Storage Blob Data Reader to the identity.
Azure SQL Database: Use Managed Identity for Azure AD authentication. The identity must be added as a user in the SQL database.
Azure Functions: Managed Identity can be used to connect to Event Hubs, Service Bus, etc., without connection strings.
Azure Container Instances: Supports both system and user-assigned identities.
Important Defaults and Limitations
Max user-assigned identities per resource: 20 (for VMs, App Services, etc.).
Max user-assigned identities per subscription: 1000.
Token caching: SDK caches tokens; you can clear cache by restarting the app or using ManagedIdentityCredential with ExcludeSharedTokenCacheCredential.
Not supported: Managed Identities are not supported for on-premises resources, or for Azure resources that do not support IMDS (e.g., classic VMs).
Time skew: IMDS requires the VM's clock to be reasonably accurate (within 5 minutes of actual time) for token requests to succeed.
Step-by-Step Token Acquisition Process
Application initializes ManagedIdentityCredential with optional clientId (for user-assigned) or DefaultAzureCredential.
SDK sends HTTP GET to http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=<resource-url> with header Metadata: true.
IMDS checks if the request comes from a resource with a Managed Identity. If not, returns 400 Bad Request.
IMDS contacts Azure AD on behalf of the resource, using the service principal's credentials (which are managed internally).
Azure AD validates the request and returns a JWT access token to IMDS.
IMDS returns the token to the application (HTTP 200 with JSON body containing access_token, expires_in, etc.).
Application uses the token to authenticate to the target resource (e.g., Key Vault).
SDK caches the token until it expires (default 1 hour) and refreshes automatically when needed.
Code Example (C#)
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
public class KeyVaultExample
{
public async Task<string> GetSecretAsync(string keyVaultUrl, string secretName)
{
// Use DefaultAzureCredential which includes ManagedIdentityCredential
var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
KeyVaultSecret secret = await client.GetSecretAsync(secretName);
return secret.Value;
}
}DefaultAzureCredential tries multiple authentication sources in order: Environment variables, Managed Identity, Visual Studio, Azure CLI, etc. For production, you can use ManagedIdentityCredential directly.
Enable Managed Identity on Resource
In the Azure portal, navigate to your resource (e.g., App Service). Under 'Identity', set the status to 'On' for system-assigned, or attach a user-assigned identity. This triggers Azure to create a service principal in Azure AD for the resource. The principal ID is stored in the resource's metadata. No manual credential creation is needed.
Grant RBAC Permissions to Identity
The Managed Identity must be granted permissions to the target resource. For example, to access Key Vault, assign the 'Key Vault Secrets User' role to the identity at the Key Vault scope. This is done via Access control (IAM) in the target resource's blade. The identity is identified by its object ID (for system-assigned) or client ID (for user-assigned).
Request Token from IMDS
In application code, use the Azure Identity SDK to request a token. The SDK sends an HTTP GET to the IMDS endpoint at 169.254.169.254. The request includes the API version and the resource URI. The header 'Metadata: true' is mandatory. The SDK handles retries and caching automatically.
Azure AD Issues Token
IMDS forwards the request to Azure AD. Azure AD validates that the resource has a valid Managed Identity and that the service principal exists. It then issues a JWT access token for the specified resource audience. The token is valid for 1 hour by default. The token includes claims such as 'aud', 'iss', 'oid' (object ID), and 'appid' (client ID).
Use Token to Access Target Resource
The application receives the token and uses it in the 'Authorization: Bearer <token>' header when making requests to the target resource (e.g., Key Vault REST API). The target resource validates the token signature, issuer, audience, and expiry. If valid, the request is authorized based on the identity's permissions.
Enterprise Scenario 1: Securing Key Vault Access from Azure Functions
A financial services company uses Azure Functions to process transactions. The functions need to read secrets (e.g., database connection strings) from Key Vault. Previously, developers stored Key Vault URIs in app settings, but the connection strings themselves were in Key Vault. To authenticate, they used service principals with client secrets stored in app settings. This became a security risk because the client secret was effectively a credential in the code. With Managed Identities, they enabled system-assigned identity on each Function App, granted the 'Key Vault Secrets User' role to each identity, and updated the code to use DefaultAzureCredential. Now, no credentials are stored anywhere. The solution scales to hundreds of functions, each with its own identity. A common misconfiguration is forgetting to grant the identity permissions at the Key Vault scope, leading to 403 Forbidden errors. Also, if the Function App is deleted and recreated, a new identity is created, and permissions must be reassigned.
Enterprise Scenario 2: VM Access to Storage Blobs
A healthcare organization runs a batch processing application on Azure VMs that reads medical images from Blob Storage. The application needs to authenticate to Storage. Previously, they used storage account keys stored in environment variables, which were exposed if the VM was compromised. With Managed Identities, they enabled system-assigned identity on each VM, assigned the 'Storage Blob Data Reader' role to the identity at the storage account scope, and used the Azure Identity SDK in the application. The performance impact is negligible because token acquisition is fast (typically <100ms). However, if the VM is cloned (e.g., from a captured image), the new VM will have a different identity, and permissions must be set separately. A common issue is that the IMDS endpoint is only accessible from within the VM; you cannot test token acquisition from outside.
Enterprise Scenario 3: Multi-Service Application with User-Assigned Identity
A large e-commerce platform uses multiple Azure services (App Service, Functions, Container Instances) that all need to access the same Key Vault. Instead of enabling system-assigned identity on each resource and granting permissions individually, they create a single user-assigned identity and assign it to all resources. This simplifies permission management: only one RBAC assignment is needed. However, the downside is that the identity has broad access; if one resource is compromised, the attacker can access Key Vault on behalf of any resource using that identity. Therefore, user-assigned identities should be used carefully, with the principle of least privilege. The maximum of 20 identities per resource is rarely an issue, but the 1000 per subscription limit can be reached in large enterprises.
What AZ-204 Tests on Managed Identities (Objective 3.3)
The exam focuses on: (1) Distinguishing between system-assigned and user-assigned identities, (2) Understanding how to configure managed identities in code using the Azure Identity SDK, (3) Granting permissions via RBAC, (4) Troubleshooting token acquisition failures. Specific objective codes: 'Implement authentication by using the Microsoft Authentication Library (MSAL)' and 'Implement secure data solutions' often include managed identity scenarios.
Common Wrong Answers and Why Candidates Choose Them
'Managed Identities require storing a client secret in the application settings.' – Wrong. The whole point is to eliminate secrets. Candidates confuse managed identities with service principals. The correct answer is that no secrets are stored.
'System-assigned identities can be shared across multiple resources.' – Wrong. System-assigned is tied to a single resource. User-assigned can be shared. Candidates mix up the two types.
'The token is obtained by calling Azure AD directly from the application.' – Wrong. The application calls the IMDS endpoint, which then contacts Azure AD. Candidates forget the IMDS intermediary.
'Managed Identities can be used for on-premises servers.' – Wrong. Managed identities only work for Azure resources that support IMDS. On-premises servers cannot use it.
Specific Numbers and Terms That Appear on the Exam
IMDS IP: 169.254.169.254
API version: 2018-02-01
Header: Metadata: true
Token lifetime: 1 hour (3600 seconds)
Max user-assigned identities per resource: 20
Default Azure credential order: Environment → Managed Identity → VS Code → Azure CLI
Edge Cases and Exceptions
App Service on Linux: Managed identity is supported, but the IMDS endpoint is the same. However, the IDENTITY_ENDPOINT and IDENTITY_HEADER environment variables are also available (for backward compatibility).
Azure Functions: When running locally, DefaultAzureCredential will not use managed identity; it falls back to developer credentials. This can cause confusion when debugging.
Time skew: If the VM's clock is off by more than 5 minutes, token requests may fail. This is a common exam distractor.
Multiple identities: If a resource has both system-assigned and user-assigned identities, DefaultAzureCredential will use the system-assigned one by default. To use a specific user-assigned identity, you must specify the clientId.
How to Eliminate Wrong Answers
Always check if the answer mentions storing credentials – if so, it's likely wrong. If the answer talks about sharing identities across resources, it must be user-assigned, not system-assigned. If the answer says the application directly contacts Azure AD, it's wrong because IMDS is the intermediary. Remember that managed identities are only for Azure resources, not on-premises.
Managed Identities eliminate the need for developers to manage credentials by providing an automatically managed identity in Azure AD.
Two types: system-assigned (tied to resource lifecycle) and user-assigned (standalone, reusable).
Token acquisition uses the IMDS endpoint at 169.254.169.254 with API version 2018-02-01 and header Metadata: true.
Default token lifetime is 1 hour; the Azure Identity SDK handles caching and refresh.
Permissions are granted via RBAC roles on the target resource (e.g., Key Vault Secrets User).
Managed Identities are only supported on Azure resources that support IMDS (e.g., VMs, App Services, Functions).
User-assigned identities can be assigned to up to 20 resources, and up to 1000 can exist per subscription.
DefaultAzureCredential tries multiple authentication sources; in production, use ManagedIdentityCredential directly for clarity.
Common exam traps: confusing system vs user-assigned, thinking tokens come directly from Azure AD, and forgetting the Metadata header.
Managed Identities are the recommended approach for accessing Azure Key Vault from Azure resources.
These come up on the exam all the time. Here's how to tell them apart.
System-assigned Managed Identity
Created automatically when enabled on a resource.
Lifecycle tied to the resource; deleted when resource is deleted.
Cannot be shared across multiple resources.
One identity per resource (if enabled).
Simpler for single-resource scenarios.
User-assigned Managed Identity
Created as a standalone Azure resource.
Lifecycle independent of any resource.
Can be assigned to multiple resources simultaneously.
Multiple user-assigned identities can be assigned to one resource (up to 20).
Better for multi-resource scenarios requiring consistent permissions.
Mistake
Managed Identities require you to manage client secrets or certificates.
Correct
Azure automatically manages the credentials (certificates) for the identity. You never need to handle or store any secrets.
Mistake
System-assigned and user-assigned identities are interchangeable in all scenarios.
Correct
System-assigned is tied to the lifecycle of a single resource; user-assigned is independent and can be assigned to multiple resources. Choose based on whether you need a dedicated identity per resource or a shared identity.
Mistake
The application obtains tokens directly from Azure AD.
Correct
The application calls the Azure Instance Metadata Service (IMDS) endpoint at 169.254.169.254, which then obtains the token from Azure AD on behalf of the resource.
Mistake
Managed Identities work for any Azure resource, including classic VMs.
Correct
Only Azure resources that support IMDS (e.g., ARM VMs, App Services, Functions) can use Managed Identities. Classic VMs do not support it.
Mistake
You can use a Managed Identity to authenticate to any service that accepts Azure AD tokens, including third-party services.
Correct
Managed Identity tokens are intended for Azure services that are integrated with Azure AD. Third-party services must explicitly support Azure AD token validation and trust the Azure AD tenant.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
You can enable system-assigned managed identity on a VM using the Azure portal (VM > Identity > System assigned > On), Azure CLI (`az vm identity assign -g MyRG -n MyVm`), or PowerShell. For user-assigned, first create the identity resource, then assign it to the VM via CLI or portal. The change takes effect immediately; no reboot is required.
Yes, Azure Functions on Linux support both system-assigned and user-assigned managed identities. The IMDS endpoint is available. However, note that the environment variables `IDENTITY_ENDPOINT` and `IDENTITY_HEADER` are also set for backward compatibility. The Azure Identity SDK works the same as on Windows.
The system-assigned managed identity and its corresponding service principal in Azure AD are automatically deleted when the resource is deleted. Any permissions granted to that identity (e.g., Key Vault access policies) become orphaned and should be cleaned up manually. This is why user-assigned identities are preferred when the identity needs to persist beyond the resource's lifetime.
When using `ManagedIdentityCredential`, you can pass the `clientId` of the desired user-assigned identity. For example: `new ManagedIdentityCredential(clientId: "<client-id>")`. If you use `DefaultAzureCredential`, it will try system-assigned first if available; to force a specific user-assigned identity, use `ManagedIdentityCredential` directly.
Common causes: (1) The `Metadata: true` header is missing or misspelled. (2) The IMDS endpoint is being called from outside the resource (e.g., from your local machine). (3) The resource does not have a managed identity enabled. (4) The API version is incorrect. (5) The resource URL is invalid (e.g., missing `https://`). Check the request format and ensure the resource has an identity assigned.
Yes, you can use a managed identity to authenticate to Azure SQL Database. The identity must be added as a user in the SQL database (e.g., `CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER`). Then, grant necessary permissions (e.g., `ALTER ROLE db_datareader ADD MEMBER [<identity-name>]`). In your application, use the Azure Identity SDK to obtain a token for the resource `https://database.windows.net/`.
A service principal is created manually or via application registration, and you must manage its credentials (client secret or certificate). A managed identity is a special type of service principal whose credentials are automatically managed by Azure. Managed identities are easier to use and more secure because there are no stored secrets. They are also automatically rotated. Service principals are needed for non-Azure resources or when you need more control over the identity lifecycle.
You've just covered Managed Identities in Code — now see how well it sticks with free AZ-204 practice questions. Full explanations included, no account needed.
Done with this chapter?