azure
Azure Identity and Access Management: Complete Guide
Intermediate
16 minutes
October 2026
CloudOpsGuide Team
Azure Identity and Access Management: Complete Guide
Master Azure IAM — RBAC roles, managed identities, service principals, and access control patterns for secure cloud operations.
Table of Contents
- Identity Types
- Azure RBAC
- Managed Identities
- Service Principals
- Role Assignments
- Best Practices
- Common Patterns
Identity Types
| Type | Purpose | Where |
|---|---|---|
| User | Human accounts | Microsoft Entra ID |
| Service Principal | App/service identity | Microsoft Entra ID |
| Managed Identity | Azure-managed SP | Azure resource-linked |
| Group | Collection of users | Microsoft Entra ID |
Azure RBAC
Role-Based Access Control controls what identities can do on Azure resources.
Built-in Roles
| Role | Scope | Permissions |
|---|---|---|
| Owner | Full access + manage access | Everything |
| Contributor | Full resource access | Can't grant access |
| Reader | View-only | Read only |
| User Access Administrator | Manage access | RBAC only |
Common Workload Roles
Azure Kubernetes Service Cluster Admin Role — manage AKS
Storage Blob Data Contributor — read/write blobs
Key Vault Secrets Officer — manage secrets
Virtual Machine Contributor — manage VMs
Network Contributor — manage networking
Scopes
/subscriptions/{sub-id} — subscription level
/subscriptions/{sub-id}/resourceGroups/{rg} — resource group level
/subscriptions/.../resourceGroups/{rg}/providers/... — resource level
Always assign at the lowest scope possible.
Managed Identities
The preferred way for Azure services to authenticate — no credentials to manage.
Types
| System-Assigned | User-Assigned | |
|---|---|---|
| Lifecycle | Tied to resource | Independent |
| Multi-resource | No | Yes |
| Use case | Simple, single service | Shared identity across services |
Enable System-Assigned
# Enable on a VM
az vm identity assign -g my-rg -n my-vm
# Enable on an AKS cluster
az aks update -g my-rg -n my-cluster --enable-managed-identity
Use in Code
// C# — Azure SDK picks up managed identity automatically
var credential = new DefaultAzureCredential();
var client = new SecretClient(new Uri("https://myvault.vault.azure.net/"), credential);
# Python
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://myvault.vault.azure.net/", credential=credential)
Service Principals
When managed identities can't be used (CI/CD pipelines, Terraform, external tools).
Create
az ad sp create-for-rbac \
--name terraform-sp \
--role Contributor \
--scopes /subscriptions/{sub-id}/resourceGroups/my-rg
Terraform Authentication
export ARM_CLIENT_ID="..."
export ARM_CLIENT_SECRET="..."
export ARM_SUBSCRIPTION_ID="..."
export ARM_TENANT_ID="..."
Or use Azure CLI authentication (for local dev):
az login
Better: Workload Identity Federation
No secrets at all — uses OIDC tokens from GitHub Actions/Azure DevOps:
az ad app federated-credential create \
--id <app-object-id> \
--parameters '{
"name": "github-federated",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:myorg/myrepo:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}'
Role Assignments
Assign a Role
az role assignment create \
--assignee <principal-id> \
--role "Storage Blob Data Contributor" \
--scope /subscriptions/{sub-id}/resourceGroups/my-rg
List Assignments
# Who has access to a resource group
az role assignment list --resource-group my-rg --output table
# What roles does a user have
az role assignment list --assignee user@example.com --output table
Remove an Assignment
az role assignment delete \
--assignee <principal-id> \
--role "Contributor" \
--scope /subscriptions/{sub-id}/resourceGroups/my-rg
Best Practices
1. Prefer Managed Identities
# Don't do this — secrets to manage
az ad sp create-for-rbac --name my-app --role Contributor
# Do this instead — no secrets
az vm identity assign -g my-rg -n my-vm
az role assignment create \
--assignee $(az vm show -g my-rg -n my-vm --query identity.principalId -o tsv) \
--role Reader \
--scope /subscriptions/{sub-id}
2. Minimum Privilege
# Bad — Contributor on entire subscription
--role Contributor --scope /subscriptions/{sub-id}
# Good — specific role on specific RG
--role "Storage Blob Data Contributor" \
--scope /subscriptions/{sub-id}/resourceGroups/my-rg
3. Use Groups, Not Individuals
# Create a group for team access
az ad group create --display-name "AKS-Admins" --mail-nickname aksadmins
# Assign role to the group
az role assignment create \
--assignee $(az ad group show -g "AKS-Admins" --query id -o tsv) \
--role "Azure Kubernetes Service Cluster Admin" \
--scope /subscriptions/{sub-id}
4. Review Regularly
# Find all assignments on a subscription
az role assignment list --all --output table > access-review.csv
Common Patterns
AKS Accessing ACR
# Give AKS's kubelet identity pull access to ACR
az aks update -g my-rg -n my-cluster --attach-acr my-acr
Terraform Service Principal
SP=$(az ad sp create-for-rbac --name tf-sp --role Contributor --scopes /subscriptions/{sub-id})
export ARM_CLIENT_ID=$(echo $SP | jq -r .appId)
export ARM_CLIENT_SECRET=$(echo $SP | jq -r .password)
export ARM_TENANT_ID=$(echo $SP | jq -r .tenant)
export ARM_SUBSCRIPTION_ID="{sub-id}"
App Service Reading Key Vault
# Enable managed identity
az webapp identity assign -g my-rg -n my-app
# Grant Key Vault access
az keyvault set-policy \
--name my-vault \
--object-id $(az webapp show -g my-rg -n my-app --query identity.principalId -o tsv) \
--secret-permissions get list
GitHub Actions with OIDC
# .github/workflows/deploy.yml
permissions:
id-token: write
contents: read
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# No client_secret needed — OIDC handles auth
Troubleshooting
"Insufficient privileges" errors
# Check what role the caller has
az role assignment list --assignee <id> --all --output table
Managed identity not working
# Verify the identity exists
az vm show -g my-rg -n my-vm --query identity
# Check the role assignment was created
az role assignment list --assignee $(az vm show -g my-rg -n my-vm --query identity.principalId -o tsv)
Service principal expired
az ad app credential reset --id <app-id>
Related Articles
Last Updated: October 2026
Author: CloudOpsGuide Team
Difficulty: Intermediate
Estimated Reading Time: 16 minutes