Skip to main content

AKS Workload Identity

This guide explains Workload Identity, Managed Identity, and User-Assigned Identity concepts and usage in Azure Kubernetes Service (AKS).

Overview

When workloads (Pods) running on AKS need to access Azure resources, a secure authentication mechanism is required. Azure provides the following Identity features.

What is Managed Identity

Managed Identity is an identity managed by Azure AD (now Microsoft Entra ID) that eliminates the need to manage secrets when applications authenticate to Azure services.

Types of Managed Identity

1. System-Assigned Managed Identity

  • An identity directly tied to an Azure resource (VM, App Service, AKS, etc.)
  • Lifecycle is linked to the resource (identity is deleted when resource is deleted)
  • One identity per resource
  • Easy to enable

Advantages:

  • Easy to manage
  • Identity lifecycle matches resource lifecycle

Limitations:

  • Cannot share the same identity across multiple resources

2. User-Assigned Managed Identity

  • Created as an independent identity resource separate from Azure resources
  • Can assign the same identity to multiple Azure resources
  • Independently manage identity lifecycle

Advantages:

  • Can share the same identity across multiple resources
  • Identity persists even after resource deletion
  • More flexible management

Use Cases:

  • Accessing the same Azure resource from multiple AKS clusters
  • Using the same identity across development/staging/production environments

Workload Identity Federation

Workload Identity Federation is a feature of Microsoft Entra that allows software workloads to securely access Microsoft Entra protected resources without managing secrets or certificates. AKS Workload Identity applies this Workload Identity Federation mechanism to AKS (Kubernetes).

Benefits of Adoption

Typically, when applications outside Azure or on Kubernetes access Azure resources, managing secrets (passwords or API keys) is required. However, secrets carry risks of leakage and expiration. Using Workload Identity Federation offers the following benefits:

  • No Secrets Needed: Eliminates the need to store and manage credentials.
  • Improved Security: Reduces leakage risk by relying on tokens from external Identity Providers (IdP).
  • Reduced Operational Burden: Eliminates tasks like secret rotation and certificate renewal.

Supported Scenarios

Workload Identity Federation can be used in diverse scenarios beyond AKS, including:

  • Kubernetes: AKS, EKS (AWS), GKE (Google Cloud), on-premises, etc.
  • CI/CD: GitHub Actions, Azure Pipelines, etc.
  • Other Clouds: Workloads running on Google Cloud, AWS
  • On-Premises: Services running outside Azure

How it Works (Overview)

You configure a trust relationship (Federated Identity Credential) between a User-Assigned Managed Identity (or App Registration) in Microsoft Entra ID and an external Identity Provider (IdP).

  1. The external workload acquires a token from the external IdP.
  2. The token is presented to Microsoft Entra ID.
  3. Microsoft Entra ID validates the trust relationship and issues an access token.
  4. The access token is used to access Azure resources.

AKS Workload Identity

Workload Identity is a mechanism to securely assign Managed Identity to Pods in AKS.

Challenges with Previous Methods

Previously, Azure AD Pod Identity was used to assign identities to Pods, but had the following challenges:

  • Complex architecture
  • Security concerns
  • Maintenance burden

How Workload Identity Works

Workload Identity uses OpenID Connect (OIDC) to federate Kubernetes Service Accounts with Azure Managed Identity.

Flow:

  1. Pod is associated with a Kubernetes Service Account
  2. Service Account issues an OIDC token
  3. OIDC token is presented to Azure AD
  4. Azure AD validates and issues an access token for Azure resources
  5. Pod accesses Azure resources

Benefits of Workload Identity

  • Improved Security: No need to grant permissions at node level, fine-grained control at Pod level
  • Kubernetes Native: Uses Service Account, a Kubernetes standard feature
  • Simple Management: Easier to manage than traditional Pod Identity
  • Industry Standard: Cloud-native approach using OIDC

Configuration

1. Enable Workload Identity on AKS Cluster

# Create new cluster
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-oidc-issuer \
--enable-workload-identity

# Update existing cluster
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-oidc-issuer \
--enable-workload-identity

2. Create User-Assigned Managed Identity

# Create Managed Identity
az identity create \
--name myIdentity \
--resource-group myResourceGroup \
--location eastus

# Get Client ID
export USER_ASSIGNED_CLIENT_ID=$(az identity show \
--resource-group myResourceGroup \
--name myIdentity \
--query 'clientId' -o tsv)

3. Grant Access Permissions to Azure Resources

# Example: Grant access to Storage Account
az role assignment create \
--role "Storage Blob Data Contributor" \
--assignee $USER_ASSIGNED_CLIENT_ID \
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>

4. Create Kubernetes Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
name: workload-identity-sa
namespace: default
annotations:
azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"

5. Create Federated Credential

# Get OIDC Issuer URL
export AKS_OIDC_ISSUER=$(az aks show \
--resource-group myResourceGroup \
--name myAKSCluster \
--query "oidcIssuerProfile.issuerUrl" -o tsv)

# Create Federated Credential
az identity federated-credential create \
--name myFederatedIdentity \
--identity-name myIdentity \
--resource-group myResourceGroup \
--issuer "${AKS_OIDC_ISSUER}" \
--subject system:serviceaccount:default:workload-identity-sa

6. Use in Pod

apiVersion: v1
kind: Pod
metadata:
name: workload-identity-pod
namespace: default
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: workload-identity-sa
containers:
- name: app
image: mcr.microsoft.com/azure-cli
command: ["sleep", "infinity"]

Implementation Examples

Accessing Azure Storage

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

# Automatically authenticate using Workload Identity
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url="https://<storage-account>.blob.core.windows.net",
credential=credential
)

# List blobs
container_client = blob_service_client.get_container_client("mycontainer")
blob_list = container_client.list_blobs()
for blob in blob_list:
print(blob.name)

Accessing Azure Key Vault

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

// Automatically authenticate using Workload Identity
var credential = new DefaultAzureCredential();
var client = new SecretClient(
new Uri("https://<keyvault-name>.vault.azure.net/"),
credential
);

// Get secret
KeyVaultSecret secret = await client.GetSecretAsync("my-secret");
Console.WriteLine($"Secret value: {secret.Value}");

Troubleshooting

Common Issues

1. Authentication Error

Symptom: AADSTS700016: Application with identifier was not found in the directory

Cause and Resolution:

  • Federated Credential configuration is incorrect
  • Service Account annotations are incorrect
  • OIDC Issuer URL is incorrect

How to Check:

# Check Service Account
kubectl get sa workload-identity-sa -o yaml

# Check Pod labels
kubectl get pod workload-identity-pod -o yaml | grep azure.workload.identity

2. Permission Error

Symptom: 403 Forbidden or This request is not authorized to perform this operation

Cause and Resolution:

  • Managed Identity doesn't have appropriate role assignment
  • Role propagation takes time (wait up to 5 minutes)

How to Check:

# Check role assignments
az role assignment list \
--assignee $USER_ASSIGNED_CLIENT_ID \
--all -o table

3. Pod Cannot Acquire Identity

Cause:

  • Pod doesn't have azure.workload.identity/use: "true" label
  • Service Account is not specified correctly

Debugging:

# Check environment variables in Pod
kubectl exec -it workload-identity-pod -- env | grep AZURE

# Check if the following environment variables are set:
# - AZURE_CLIENT_ID
# - AZURE_TENANT_ID
# - AZURE_FEDERATED_TOKEN_FILE

Best Practices

1. Principle of Least Privilege

Grant only the minimum necessary permissions.

# ❌ Bad: Grant Contributor role
az role assignment create \
--role "Contributor" \
--assignee $USER_ASSIGNED_CLIENT_ID

# ✅ Good: Allow only specific operations
az role assignment create \
--role "Storage Blob Data Reader" \
--assignee $USER_ASSIGNED_CLIENT_ID \
--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>

2. Namespace Isolation

Separate Namespaces and Service Accounts by environment and purpose.

# Development environment
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: development
annotations:
azure.workload.identity/client-id: "${DEV_CLIENT_ID}"
---
# Production environment
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
annotations:
azure.workload.identity/client-id: "${PROD_CLIENT_ID}"

3. Identity Lifecycle Management

  • Manage User-Assigned Managed Identity as a reusable resource
  • Manage with Infrastructure as Code (Terraform, Bicep, etc.)
  • Regularly audit usage

4. Monitoring and Logging

# Check Azure AD sign-in logs
az monitor activity-log list \
--resource-group myResourceGroup \
--offset 1h

# Check AKS logs
kubectl logs -l azure.workload.identity/use=true -n default

Summary

FeatureDescriptionUse Case
System-Assigned Managed IdentityIdentity directly tied to resourceSingle resource usage
User-Assigned Managed IdentityIndependent identity resourceSharing across multiple resources
Workload IdentitySecurely assign identity to PodsApplications on AKS

Key Benefits

  • No secret management required
  • Improved security
  • Kubernetes-native implementation
  • Fine-grained access control

Migration

Migration from Azure AD Pod Identity to Workload Identity is recommended. If you're currently using Pod Identity, plan for a systematic migration.

References