Back to Blog
4 min read

Secure Azure Access with AKS Pod Identity

Secure Azure Access with AKS Pod Identity

Managing secrets and credentials in Kubernetes can be challenging. AKS Pod Identity allows your pods to use Azure Active Directory identities to access Azure resources securely, without embedding credentials in your code or configuration.

Understanding Pod Identity

Pod Identity assigns Azure managed identities to pods, enabling:

  • Secretless authentication to Azure services
  • Fine-grained access control per workload
  • Automatic credential rotation
  • Audit trail in Azure AD

Installing AAD Pod Identity

Using Helm

# Add the AAD Pod Identity Helm repo
helm repo add aad-pod-identity https://raw.githubusercontent.com/Azure/aad-pod-identity/master/charts
helm repo update

# Install in managed mode (recommended for managed AKS)
helm install aad-pod-identity aad-pod-identity/aad-pod-identity \
    --namespace kube-system \
    --set operationMode=managed \
    --set forceNamespaced=true

Verify Installation

kubectl get pods -n kube-system | grep aad-pod-identity

# Should see:
# aad-pod-identity-mic-xxx   Running
# aad-pod-identity-nmi-xxx   Running

Creating an Azure Identity

# Create a user-assigned managed identity
az identity create \
    --resource-group myResourceGroup \
    --name myPodIdentity

# Get the identity resource ID and client ID
IDENTITY_RESOURCE_ID=$(az identity show \
    --resource-group myResourceGroup \
    --name myPodIdentity \
    --query id -o tsv)

IDENTITY_CLIENT_ID=$(az identity show \
    --resource-group myResourceGroup \
    --name myPodIdentity \
    --query clientId -o tsv)

Assigning Permissions

Grant the identity access to Azure resources:

# Example: Grant access to Key Vault
az keyvault set-policy \
    --name myKeyVault \
    --object-id $(az identity show --resource-group myResourceGroup --name myPodIdentity --query principalId -o tsv) \
    --secret-permissions get list

# Example: Grant access to Storage Account
az role assignment create \
    --role "Storage Blob Data Reader" \
    --assignee $(az identity show --resource-group myResourceGroup --name myPodIdentity --query principalId -o tsv) \
    --scope /subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount

Creating AzureIdentity and AzureIdentityBinding

apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentity
metadata:
  name: my-pod-identity
  namespace: default
spec:
  type: 0  # 0 = User Assigned, 1 = Service Principal
  resourceID: /subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myPodIdentity
  clientID: {client-id-guid}
---
apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentityBinding
metadata:
  name: my-pod-identity-binding
  namespace: default
spec:
  azureIdentity: my-pod-identity
  selector: my-app  # Pods with this label will use this identity

Using the Identity in Pods

Label your pods with the identity selector:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
        aadpodidbinding: my-app  # This label binds to the AzureIdentityBinding
    spec:
      containers:
      - name: app
        image: myregistry.azurecr.io/my-app:v1
        env:
        - name: AZURE_CLIENT_ID
          value: "{client-id-guid}"

Example: Accessing Key Vault

from azure.identity import ManagedIdentityCredential
from azure.keyvault.secrets import SecretClient

# No credentials needed - uses pod identity
credential = ManagedIdentityCredential()
client = SecretClient(
    vault_url="https://mykeyvault.vault.azure.net",
    credential=credential
)

secret = client.get_secret("my-secret")
print(f"Secret value: {secret.value}")

Example: Accessing Azure Storage

from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobServiceClient

credential = ManagedIdentityCredential()
blob_service = BlobServiceClient(
    account_url="https://mystorageaccount.blob.core.windows.net",
    credential=credential
)

container_client = blob_service.get_container_client("mycontainer")
blobs = container_client.list_blobs()
for blob in blobs:
    print(blob.name)

Example: Accessing Azure SQL

using Azure.Identity;
using Microsoft.Data.SqlClient;

var credential = new ManagedIdentityCredential();
var token = await credential.GetTokenAsync(
    new TokenRequestContext(new[] { "https://database.windows.net/.default" })
);

using var connection = new SqlConnection(
    "Server=myserver.database.windows.net;Database=mydb;"
);
connection.AccessToken = token.Token;
await connection.OpenAsync();

// Execute queries...

Namespace Isolation

For multi-tenant clusters, use namespace-scoped identities:

apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentity
metadata:
  name: team-a-identity
  namespace: team-a
spec:
  type: 0
  resourceID: /subscriptions/.../userAssignedIdentities/teamAIdentity
  clientID: {team-a-client-id}
---
apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentityBinding
metadata:
  name: team-a-binding
  namespace: team-a
spec:
  azureIdentity: team-a-identity
  selector: team-a-workload

Troubleshooting

Check MIC Logs

kubectl logs -n kube-system -l app=mic --tail=100

Check NMI Logs

kubectl logs -n kube-system -l app=nmi --tail=100

Verify Identity Assignment

# Check if identity is assigned to the node
az vmss identity show \
    --resource-group MC_myResourceGroup_myAKSCluster_eastus \
    --name aks-nodepool1-12345678-vmss

Security Best Practices

  1. Principle of least privilege - Grant minimal permissions required
  2. Use namespace isolation - Scope identities to namespaces
  3. Audit identity usage - Monitor Azure AD sign-in logs
  4. Rotate identities periodically - Update identity bindings regularly
  5. Use Azure Policy - Enforce identity requirements

Conclusion

AKS Pod Identity provides a secure, credential-free way to access Azure resources from your Kubernetes workloads. By leveraging managed identities, you eliminate the need to manage secrets while maintaining strong security controls.

Tomorrow, we’ll explore the newer Workload Identity approach, which is becoming the recommended method for Azure identity in Kubernetes.

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.