Azure Managed Identities: Enterprise Implementation and Security Guide
Prerequisites
- Azure subscription with Owner or User Access Administrator rights
- Working knowledge of Azure CLI and Microsoft Entra ID
Steps
Azure Managed Identities lets Azure resources obtain Microsoft Entra ID tokens without storing secrets in code, pipelines, or configuration files. Enterprises use it to reduce credential exposure, simplify workload authentication, and enforce least-privilege access across cloud-native platforms.
Overview
Azure Managed Identities is a Microsoft Entra ID capability that provides an automatically managed service principal for Azure resources such as virtual machines, App Service, AKS, Functions, and Logic Apps. Its core purpose is to let workloads authenticate to Azure services like Key Vault, Storage, SQL Database, and Microsoft Graph without embedding client secrets or certificates.
Enterprises adopt Managed Identities because they eliminate secret sprawl, reduce operational overhead for credential rotation, and align with Zero Trust and least-privilege principles. Two identity types exist:
- System-assigned managed identity: lifecycle tied to a single Azure resource
- User-assigned managed identity: standalone identity reusable across multiple resources
Architecture
Core components include:
- Azure resource hosting the workload
- Managed Identity endpoint / Instance Metadata Service (IMDS)
- Microsoft Entra ID token service
- Target Azure service such as Key Vault or Storage
- Azure RBAC or service-specific access policy
Deployment models:
- System-assigned for single-resource trust boundaries
- User-assigned for shared identity across apps, jobs, or AKS workloads
- Federated workload patterns where AKS or CI/CD integrates with Entra-backed trust chains
View as text
[Application on VM/App Service/AKS] | | 1. request token for https://vault.azure.net v [Managed Identity Endpoint / IMDS] ---- 2. token request ----> [Microsoft Entra ID] [Microsoft Entra ID] ---- 3. access token ----> [Managed Identity Endpoint / IMDS] | | 4. bearer token v [Azure Key Vault] ---- 5. authorize via RBAC/access policy ----> [Secret Returned]
Data flow is straightforward: the workload requests a token from the local managed identity endpoint, Entra ID issues a scoped access token, and the workload presents that token to the target service. Authorization is then enforced by Azure RBAC or service-specific controls.
Implementation Guide
- Create a resource group and Key Vault.
az group create --name rg-mi-prod --location westeurope
az keyvault create --name kvmientprod01 --resource-group rg-mi-prod --location westeurope --enable-rbac-authorization true
- Create a VM with a system-assigned identity.
az vm create --resource-group rg-mi-prod --name vm-mi-01 --image Ubuntu2204 --admin-username azureadmin --generate-ssh-keys --assign-identity
- Capture the principal ID and grant least-privilege access.
PRINCIPAL_ID=$(az vm show -g rg-mi-prod -n vm-mi-01 --query identity.principalId -o tsv)
KV_ID=$(az keyvault show -g rg-mi-prod -n kvmientprod01 --query id -o tsv)
az role assignment create --assignee-object-id $PRINCIPAL_ID --assignee-principal-type ServicePrincipal --role "Key Vault Secrets User" --scope $KV_ID
- Create a secret for validation.
az keyvault secret set --vault-name kvmientprod01 --name DbPassword --value "S3cureValue-Prod-01"
- Test token retrieval from the VM.
curl -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net" | jq
- For reusable identity, create a user-assigned identity and attach it.
az identity create --name uami-shared-prod --resource-group rg-mi-prod
UAMI_ID=$(az identity show -g rg-mi-prod -n uami-shared-prod --query id -o tsv)
az vm identity assign --resource-group rg-mi-prod --name vm-mi-01 --identities $UAMI_ID
Production config example for App Service:
{
"name": "my-enterprise-api",
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-mi-prod/providers/Microsoft.ManagedIdentity/userAssignedIdentities/uami-shared-prod": {}
}
}
}
Code Examples
TOKEN=$(curl -s -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com" | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" -H "x-ms-version: 2023-11-03" "https://stmiarchiveprod.blob.core.windows.net/?comp=list"
apiVersion: v1
kind: Pod
metadata:
name: workload-mi
namespace: prod
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: sa-workload-mi
containers:
- name: app
image: mcr.microsoft.com/azure-cli:2.61.0
command: ["/bin/sh","-c"]
args: ["az login --identity && az keyvault secret show --vault-name kvmientprod01 --name DbPassword"]
from azure.identity import ManagedIdentityCredential
from azure.keyvault.secrets import SecretClient
credential = ManagedIdentityCredential()
client = SecretClient(vault_url="https://kvmientprod01.vault.azure.net/", credential=credential)
secret = client.get_secret("DbPassword")
print(secret.value)
Security Hardening
- Prefer system-assigned identities when the identity should not outlive the resource.
- Use user-assigned identities only for explicit reuse scenarios such as blue/green deployments or shared automation.
- Grant minimum RBAC roles like
Key Vault Secrets Userinstead of broad roles such asContributor. - Restrict network access to dependent services using private endpoints, firewalls, and NSGs.
- Store sensitive data in Key Vault with purge protection and soft delete enabled.
- Monitor token usage with Entra sign-in logs, Azure Activity Log, and Defender for Cloud.
- For AKS, prefer Microsoft Entra Workload ID over legacy pod-managed identity patterns.
Comparison
| Feature | Azure Managed Identities | AWS IAM Roles for EC2/EKS | Google Cloud Service Accounts |
|---|---|---|---|
| Pricing | No direct extra charge; pay for dependent services | No direct extra charge | No direct extra charge |
| Deployment | Native on Azure resources, deep Entra integration | Native on AWS compute and Kubernetes via IRSA | Native on GCP workloads and GKE |
| Scalability | High, supports system and reusable user-assigned identities | High, role-based and instance/profile driven | High, broad workload coverage |
| Security | Secretless auth, RBAC, Conditional Access adjacency, Key Vault integration | Strong IAM policy model, STS temporary creds | Strong IAM model, short-lived tokens, workload identity federation |
Troubleshooting
Error 1: IMDS unavailable
Log sample:
curl: (7) Failed to connect to 169.254.169.254 port 80: Connection refused
ManagedIdentityCredential authentication unavailable. Connection to IMDS endpoint cannot be established.
Fix:
- Confirm the workload runs on an Azure resource that supports Managed Identity
- Ensure local firewall or proxy does not block
169.254.169.254 - Verify identity is enabled on the resource
Error 2: Unauthorized to Key Vault
Log sample:
{"error":{"code":"Forbidden","message":"The user, group or application 'appid=8b7f4d2a-1111-2222-3333-9d0f4d5e6a77;oid=7c3e2b10-aaaa-bbbb-cccc-1234567890ab' does not have secrets get permission on key vault 'kvmientprod01;location=westeurope'."}}
Fix:
- Assign
Key Vault Secrets Userat vault scope - Wait for RBAC propagation, typically a few minutes
- Confirm the token audience is
https://vault.azure.net
Error 3: Wrong identity selected
Log sample:
Azure.Identity.CredentialUnavailableException: ManagedIdentityCredential authentication unavailable. Multiple user assigned identities exist, please specify the clientId / resourceId of the identity in the token request.
Fix:
- Pass
client_idexplicitly in SDK configuration - Remove unnecessary attached user-assigned identities
- Standardize identity-per-application patterns
Best Practices
Do
- Use one managed identity per application boundary
- Map roles to specific scopes such as a single Key Vault or storage account
- Combine Managed Identity with PIM, policy, and resource locks for administrative control
- Document identity ownership and lifecycle in CMDB or IaC repositories
Don't
- Do not assign
OwnerorContributorwhen data-plane roles are sufficient - Do not reuse one user-assigned identity across unrelated production systems
- Do not assume authentication equals authorization; RBAC must still be explicitly configured
- Do not leave legacy secrets in app settings after migrating to Managed Identity
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI