AKS Microsoft Entra Workload ID: OIDC Federation Without Stored Secrets
Configure AKS workload federation with projected service-account tokens, exact issuer-subject-audience trust, safe webhook rollout, and identity diagnostics.
Microsoft Entra Workload ID lets an application in Azure Kubernetes Service exchange a projected Kubernetes service-account token for a Microsoft Entra access token. The design removes the need to place a client secret or certificate in a Pod for supported federation scenarios, but it does not make identity configuration automatic or eliminate authorization policy. The cluster issuer, federated identity credential, service account, Pod template, webhook, client library, and Azure role assignment must agree.
AKS Standard operators enable the OIDC issuer and workload identity features as part of cluster configuration; AKS Automatic has different defaults. Confirm the cluster offering and current configuration before applying commands copied from a generic tutorial. The identity flow described here is Pod-to-Azure-resource authentication. It is distinct from the identity used by an administrator to access the Kubernetes API, the control-plane identity, and the kubelet identity used for node operations.
Follow the token exchange
Kubernetes issues a short-lived service-account token with an audience selected for federation. The AKS workload identity mutating webhook injects a projected token volume and environment variables into eligible Pods. An Azure Identity library reads the token file, presents it to Microsoft Entra ID, and requests a token for the federated identity. Entra validates the issuer’s OIDC discovery and signing-key endpoints, then returns an access token representing the target application or user-assigned managed identity. Azure RBAC or the target service’s own authorization rules still decide what that identity can do.
The federation trust is an exact match across issuer, subject, and audience. The issuer must be the OIDC issuer URL for the specific cluster. The subject is usually system:serviceaccount:<namespace>:<service-account>. For direct workload identity federation, the audience is normally api://AzureADTokenExchange. A typo in namespace, service-account name, issuer URL, or audience fails token exchange even if every resource exists and the webhook injected a token.
For standard Microsoft Entra federated identity credentials, the subject must match exactly; wildcard characters are not supported. Create a credential for each intended service-account subject rather than assuming a namespace-wide subject pattern will work. AKS documents a limit of 20 federated identity credentials per managed identity, so assess the separately documented identity-bindings preview for large-scale designs instead of broadening a standard credential. Combine narrow federation with Kubernetes RBAC, admission policy, and resource-specific Azure role assignments. A federated credential only authenticates a Kubernetes principal; it does not grant access to Key Vault, Storage, or Graph by itself.
Enable the cluster capabilities
Use an approved Azure CLI version and a reviewed cluster change to enable the OIDC issuer and workload identity on AKS Standard. The exact command syntax and flags can vary by CLI release, so check the current AKS procedure and inspect the cluster after the operation. Treat issuer URLs as configuration data: capture the value returned by the cluster API rather than reconstructing it from a guessed pattern.
az aks show \
--resource-group "$RESOURCE_GROUP" \
--name "$AKS_CLUSTER" \
--query '{oidcIssuer:oidcIssuerProfile.issuerUrl,workloadIdentity:securityProfile.workloadIdentity.enabled}' \
--output json
The command is read-only and assumes the shell variables name the intended subscription, group, and cluster. Set and verify the Azure subscription before running it. If either property is missing or disabled, follow Microsoft’s current cluster deployment instructions; do not infer success from an old portal screenshot or from a Kubernetes annotation alone.
Create or select a user-assigned managed identity or application registration according to the resource access model. Then create a federated identity credential whose issuer, subject, and audience match the cluster and service account. Assign the identity only the Azure role and scope required by the workload. For example, a read-only secret-fetching process should not inherit subscription-wide contributor permissions just because the first test returned a token successfully.
Make the workload opt in
The service account annotation identifies the Entra client ID used by the workload. The Pod template needs the workload identity label so the webhook mutates the Pod. The injected token-file path is an implementation detail; applications should read AZURE_FEDERATED_TOKEN_FILE through a supported Azure Identity library rather than hard-coding a mount location.
apiVersion: v1
kind: ServiceAccount
metadata:
name: report-reader
namespace: finance
annotations:
azure.workload.identity/client-id: "00000000-0000-0000-0000-000000000000"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: report-exporter
namespace: finance
spec:
replicas: 1
selector:
matchLabels:
app: report-exporter
template:
metadata:
labels:
app: report-exporter
azure.workload.identity/use: "true"
spec:
serviceAccountName: report-reader
containers:
- name: exporter
image: example.invalid/finance/exporter@sha256:REPLACE_WITH_APPROVED_DIGEST
command: ["/app/export"]
Replace the placeholder client ID and image digest with approved values. The label belongs on the Pod template, not only on the Deployment’s top-level metadata, because the admission webhook processes Pods. Ensure the API version and webhook installation match the supported AKS procedure. Avoid copying a mount path into an application config; the webhook can change implementation details and multiple projected tokens may be present in more advanced federation designs.
Validate from inside the actual Pod
Start with a controlled diagnostic Pod that uses the same namespace, service account, workload identity label, and network policy as the application. Verify the webhook injected expected variables and a readable projected token file without printing the token contents. Check that the token’s issuer, subject, and audience match the federated credential. JWT decoding for inspection does not verify a signature; rely on Entra’s exchange result for cryptographic issuer validation.
Next use the same Azure Identity library version and authentication chain as the application. DefaultAzureCredential can attempt multiple credential sources; a developer environment variable or mounted secret can cause it to authenticate as an unintended principal. In production, remove unused credential sources and log only the resolved tenant and client identity metadata that the library exposes safely. Do not log access tokens, assertions, or request headers containing bearer credentials.
Verify authorization separately. A successful token acquisition proves federation, not permission to retrieve a named secret or access a storage container. Make one least-privilege request to the real resource and inspect its authorization logs if it fails. Azure RBAC propagation may take time; distinguish a federation error from an access-denied response by checking the exact error code and token audience. Avoid repeatedly widening role assignments until a request succeeds, because that hides which permission was actually missing.
Roll out and rotate with failure modes in mind
Deploy the webhook and cluster features through the supported AKS workflow, then canary an application replica before migrating all workloads. AKS’s cluster certificate auto-rotation operation rotates the workload identity webhook certificate; monitor webhook availability and certificate health during that operation. Since the webhook mutates Pod creation, existing Pods do not necessarily acquire newly configured projected volumes until they are recreated. Use a controlled rollout and verify new replicas before scaling down the old credential path.
Kubernetes refreshes the projected service-account token in place. Application code that reads the token directly must reopen the file before each exchange rather than caching its bytes indefinitely. Azure access tokens have a separate lifetime and refresh lifecycle handled by the SDK. If the Pod’s projected token is renewed but the client continues to use stale process state, failures can appear only after the first token expires; test beyond the initial token’s lifetime in a non-production environment.
If a workload is configured for identity bindings or another federation mechanism, be explicit about token audience. A projected token has a single audience; using a token intended for one exchange endpoint with a different federated credential can return a seemingly mysterious issuer or audience mismatch. Keep direct federation and preview identity-binding paths distinct in manifests and runbooks. Preview features should not be treated as baseline production prerequisites.
A practical troubleshooting sequence
First confirm the Pod is newly created after the service-account and label changes. Then inspect its service-account name, injected environment variable names, projected volume mount, and webhook events. Next compare the OIDC issuer URL from AKS with the configured federated credential, and compare the exact namespace/service-account subject and token audience. Check that the target identity is enabled and the Pod uses its client ID. Only after federation works should you investigate Azure role scope and target resource authorization.
For a Pod with no injection, check the required azure.workload.identity/use: "true" label, namespace labels or exemptions, webhook health, and whether the Pod was created before configuration was installed. For an authentication failure, inspect issuer discovery reachability and federated credential matching. For a resource denial, capture the target resource, tenant, principal, role assignment scope, and service-specific access model. Keep diagnostics free of bearer material and use the shortest-lived test identity possible.
Workload ID is a federation contract across two control planes, not a secret-free shortcut around access review. Keep the Kubernetes principal narrow, manage issuer and subject values as critical config, test token refresh and role authorization independently, and retain a rollback path until telemetry confirms the migration.
Related:
- Azure Kubernetes Service: Managed Control Plane, Node Pools, Identity, and Networking
- Kubernetes ServiceAccount Token Projection: Audience, Rotation, and Trust Boundaries
Sources: