Introduction
Azure Kubernetes Service (AKS) Workload Identity is a feature that allows pods to authenticate to Azure services using Azure Active Directory (AAD) tokens, without storing credentials in the cluster. It builds on the federated identity capability in Azure, establishing a trust relationship between an AKS cluster's OIDC issuer and Azure AD applications or managed identities.
When workload identity fails to authenticate, the pod cannot access Azure resources like storage accounts, key vaults, or databases. The most common cause is missing or misconfigured federated credentials, but issues can also arise from incorrect pod labeling, missing service account annotations, or problems with the managed identity itself.
Understanding the trust chain is essential: the AKS cluster has an OIDC issuer URL, the service account is associated with a specific pod, and Azure AD trusts tokens issued by the AKS cluster for specific service accounts. Any break in this chain—from the cluster issuer to the federated credential subject—results in authentication failure.
Symptoms
When AKS workload identity authentication fails, you will observe these symptoms:
- Pods cannot access Azure resources, returning 401 Unauthorized or 403 Forbidden errors
- Application logs show "authentication failed" or "token acquisition failed"
- Azure SDK operations fail with "DefaultAzureCredential failed to retrieve a token"
- The workload identity mutating webhook fails to inject the correct environment variables
- Service account tokens are not exchanged for Azure AD tokens
- Pod events show errors related to workload identity or service account
Common error messages in application logs:
Error: DefaultAzureCredential failed to retrieve a token
Error: Authentication failed: AADSTS50020: User account does not exist
Error: ManagedIdentityCredential authentication failed
Error: MSI endpoint not available
Error: Failed to get service account token: token exchange failedPod events showing workload identity issues:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning WorkloadIdentity 30s workload-identity Failed to get federated token: audience mismatch
Warning AuthFailed 20s azure-sdk Failed to acquire token: client assertion not foundCommon Causes
Several factors cause AKS workload identity authentication failures:
- 1.Missing federated credential: The Azure AD application or managed identity doesn't have a federated credential configured for the AKS cluster's OIDC issuer and service account.
- 2.Incorrect federated credential subject: The subject in the federated credential doesn't match the service account name and namespace in the format
system:serviceaccount:<namespace>:<service-account-name>. - 3.Service account missing workload identity label: The Kubernetes service account doesn't have the
azure.workload.identity/uselabel, preventing the mutating webhook from processing it. - 4.Missing service account annotation: The service account doesn't have the
azure.workload-identity/client-idannotation pointing to the correct Azure AD client ID. - 5.AKS cluster OIDC issuer not enabled: The AKS cluster doesn't have OIDC issuer URL configured, which is required for workload identity.
- 6.Workload identity addon not enabled: The AKS cluster doesn't have the
EnableWorkloadIdentityfeature enabled. - 7.Incorrect audience configuration: The token audience doesn't match what Azure expects (typically
api://AzureADTokenExchange).
Step-by-Step Fix
Follow these steps to diagnose and resolve workload identity authentication failures:
Step 1: Verify AKS cluster has workload identity enabled
Check the cluster configuration:
```bash # Check AKS cluster configuration az aks show --resource-group myResourceGroup --name myAKSCluster --query '{oidcIssuer: oidcIssuerProfile.issuerUrl, workloadIdentity: securityProfile.workloadIdentity}'
# Expected output: # { # "oidcIssuer": "https://oidc.prod-aks.azure.com/...", # "workloadIdentity": "Enabled" # }
# Enable workload identity if needed az aks update --resource-group myResourceGroup --name myAKSCluster --enable-workload-identity
# Get the OIDC issuer URL az aks show --resource-group myResourceGroup --name myAKSCluster --query oidcIssuerProfile.issuerUrl --output tsv ```
Step 2: Check service account configuration
Verify the service account has correct labels and annotations:
```bash # Get service account details kubectl get serviceaccount my-service-account -n my-namespace -o yaml
# Check for required label kubectl get serviceaccount my-service-account -n my-namespace -o jsonpath='{.metadata.labels.azure\.workload\.identity/use}'
# Check for client ID annotation kubectl get serviceaccount my-service-account -n my-namespace -o jsonpath='{.metadata.annotations.azure\.workload-identity/client-id}' ```
Required service account configuration:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: my-namespace
labels:
azure.workload.identity/use: "true" # Required label
annotations:
azure.workload-identity/client-id: "<azure-ad-client-id>" # Client ID of the managed identity or appStep 3: Create or fix the service account
Apply the correct configuration:
# Apply service account with workload identity configuration
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: my-namespace
labels:
azure.workload.identity/use: "true"
annotations:
azure.workload-identity/client-id: "$(az identity show --ids <identity-resource-id> --query clientId -o tsv)"
EOFStep 4: Check federated credential configuration
Verify the managed identity or app registration has the federated credential:
```bash # For user-assigned managed identity az identity federated-credential list --resource-group myResourceGroup --identity-name myIdentity
# Get the expected subject SERVICE_ACCOUNT="my-service-account" NAMESPACE="my-namespace" EXPECTED_SUBJECT="system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT}" echo "Expected subject: ${EXPECTED_SUBJECT}"
# Check if federated credential exists for this subject az identity federated-credential show --resource-group myResourceGroup --identity-name myIdentity --name my-federated-credential ```
Step 5: Create the federated credential
If missing, create the federated credential:
```bash # Get AKS OIDC issuer URL OIDC_ISSUER=$(az aks show --resource-group myResourceGroup --name myAKSCluster --query oidcIssuerProfile.issuerUrl --output tsv)
# Get service account subject NAMESPACE="my-namespace" SERVICE_ACCOUNT="my-service-account" SUBJECT="system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT}"
# Create federated credential for managed identity az identity federated-credential create \ --resource-group myResourceGroup \ --identity-name myIdentity \ --name my-federated-credential \ --issuer "${OIDC_ISSUER}" \ --subject "${SUBJECT}" \ --audiences "api://AzureADTokenExchange"
# For app registration (service principal) az ad app federated-credential create \ --id <app-client-id> \ --parameters '{ "name": "my-federated-credential", "issuer": "'${OIDC_ISSUER}'", "subject": "'${SUBJECT}'", "audiences": ["api://AzureADTokenExchange"] }' ```
Step 6: Verify pod configuration
Ensure the pod uses the correct service account:
```bash # Check pod's service account kubectl get pod my-pod -n my-namespace -o jsonpath='{.spec.serviceAccountName}'
# Check for workload identity environment variables injected kubectl exec my-pod -n my-namespace -- env | grep -i azure
# Expected environment variables: # AZURE_CLIENT_ID=... # AZURE_FEDERATED_TOKEN_FILE=/var/run/secrets/azure/tokens/azure-identity-token # AZURE_AUTHORITY_HOST=https://login.microsoftonline.com/ ```
Pod template configuration:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: my-namespace
spec:
serviceAccountName: my-service-account # Must match the configured SA
containers:
- name: my-app
image: myimage:latest
# Azure SDK will automatically use workload identityStep 7: Test authentication from the pod
Verify the pod can authenticate to Azure:
```bash # Install Azure CLI in the pod for testing kubectl exec -it my-pod -n my-namespace -- /bin/bash
# Inside the pod, test authentication az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" \ --client-id $AZURE_CLIENT_ID \ --tenant-id $AZURE_TENANT_ID
# Or use a simple test with Azure SDK python3 -c " from azure.identity import DefaultAzureCredential from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential() print(f'Credential created: {credential}') # Try to get a token token = credential.get_token('https://vault.azure.net/.default') print(f'Token acquired: {token.token[:20]}...') " ```
Step 8: Check Azure activity logs
Review logs for authentication failures:
# Check Azure activity log for recent failures
az monitor activity-log list \
--resource-group myResourceGroup \
--caller "<managed-identity-object-id>" \
--status Failed \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
--output tableVerification
After fixing the configuration, verify workload identity works:
```bash # Create a test pod kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: workload-identity-test namespace: my-namespace spec: serviceAccountName: my-service-account containers: - name: test image: mcr.microsoft.com/azure-cli:latest command: - /bin/bash - -c - | echo "Testing workload identity..." az login --federated-token "\$(cat \$AZURE_FEDERATED_TOKEN_FILE)" \ --client-id \$AZURE_CLIENT_ID \ --tenant-id \$AZURE_TENANT_ID az account show echo "SUCCESS: Workload identity working!" sleep 300 EOF
# Check pod logs kubectl logs workload-identity-test -n my-namespace
# Verify no authentication errors kubectl logs workload-identity-test -n my-namespace | grep -i "SUCCESS" ```
Prevention
To prevent workload identity authentication issues:
- 1.Use infrastructure as code: Define workload identity resources (managed identities, federated credentials) in Terraform or Bicep to ensure consistent configuration.
```bicep // Bicep example resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: 'myIdentity' location: location }
resource federatedCredential 'Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials@2023-01-31' = { parent: managedIdentity name: 'aksFederatedCredential' properties: { audiences: [ 'api://AzureADTokenExchange' ] issuer: aksCluster.properties.oidcIssuerProfile.issuerUrl subject: 'system:serviceaccount:${namespace}:${serviceAccount}' } } ```
- 1.Validate service account configuration: Add validation in deployment pipelines to check service account labels and annotations.
- 2.Document the trust chain: Clearly document which service accounts map to which managed identities and Azure resources.
- 3.Test workload identity after cluster changes: When upgrading AKS or changing cluster configuration, verify workload identity still works.
- 4.Monitor authentication failures: Set up alerts for authentication failures in your applications and Azure activity logs.
- 5.Use consistent naming conventions: Establish naming patterns for service accounts, managed identities, and federated credentials to make the relationships clear.
Related Articles
- [Technical troubleshooting: Fix Azure Aks Pod Crashloopbackoff Issue in Azure](azure-aks-pod-crashloopbackoff)
- [Technical troubleshooting: Fix Azure Api Management Policy Expression Runtime](azure-api-management-policy-expression-runtime-error)
- [Technical troubleshooting: Fix Azure App Configuration Feature Flag Not Refre](azure-app-configuration-feature-flag-not-refreshing)
- [Technical troubleshooting: Fix Azure App Service 503 Always On Disabled Issue](azure-app-service-503-always-on-disabled)
- [Technical troubleshooting: Fix Azure Application Gateway Err SSL Unrecognized](azure-application-gateway-err-ssl-unrecognized-name-alert)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Azure AKS Workload Identity Not Authenticating", "description": "Resolve Azure AKS workload identity authentication failures by checking federated credentials, managed identity configuration, and pod labeling.", "url": "https://www.fixwikihub.com/fix-azure-aks-workload-identity-not-authenticating", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-01-23T06:03:37.352Z", "dateModified": "2026-01-23T06:03:37.352Z" } </script>