Deployed workloads within Kubernetes clusters necessitate Azure AD application credentials or managed identities for accessing Azure AD protected resources, like Azure Key Vault and Microsoft Graph. Azure AD Pod Identity, previously offered a means to circumvent the requirement for such secrets through the utilization of Azure managed identities.The open source Azure AD pod-managed identity in AKS has been deprecated and the project will be archived soon. Azure AD workload identity replaces pod-managed identity.
In contrast, Azure AD Workload Identity for Kubernetes seamlessly incorporates the Kubernetes capabilities to establish federation with external identity providers. This method is much more simpler and removes the complexity of AAD Pod Identities.
Authentication Sequence using OIDC
How to deploy and configure AKS cluster
Microsoft Docs - workload-identity-deploy-cluster
How to retrieve the OIDC Issuer URL
1
az aks show -n myAKSCluster -g "${RESOURCE_GROUP}" --query "oidcIssuerProfile.issuerUrl" -otsv
By default, the Issuer is set to use the base URL https://{region}.oic.prod-aks.azure.com/{uuid} where the value for {region} matches the location the AKS cluster is deployed in. The value {uuid} represents the OIDC key.
OIDC Endpoints
{IssuerURL}/.well-known/openid-configuration Also known as the OIDC discovery document. This contains the metadata about the issuer’s configurations.
{IssuerURL}/openid/v1/jwks This contains the public signing key(s) that AAD uses to verify the authenticity of the service account token.
Create Federated identity credential
1
az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --issuer "${AKS_OIDC_ISSUER}" --subject system:serviceaccount:"${SERVICE_ACCOUNT_NAMESPACE}":"${SERVICE_ACCOUNT_NAME}" --audience api://AzureADTokenExchange
Service Account token mount location
The azure identity token is mounted at below location by default but this can be changed in the pod manifests.
1
/var/run/secrets/azure/tokens/azure-identity-token
The regular kubernetes serviceaccount token is mounted at: /var/run/secrets/kubernetes.io/serviceaccount
Environment Variables
- AZURE_AUTHORITY_HOST The Azure Active Directory (AAD) endpoint.
- AZURE_CLIENT_ID The client ID of the AAD application or user-assigned managed identity.
- AZURE_TENANT_ID The tenant ID of the registered AAD application or user-assigned managed identity.
- AZURE_FEDERATED_TOKEN_FILE The path of the projected service account token file.
Volume injected by the webhook
- azure-identity-token The projected service account volume.
These values can be verified by running kubectl describe pod command
Jump pod manifest for verifying Kubernetes service account token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: jump
namespace: ${NAMESPACE}
spec:
containers:
- image: smallstep/step-cli
name: step-cli
command:
- /bin/sh
- -c
- cat /var/run/secrets/tokens/test-token | step crypto jwt inspect --insecure
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: test-token
serviceAccountName: ${SERVICE_ACCOUNT_NAME}
volumes:
- name: test-token
projected:
sources:
- serviceAccountToken:
path: test-token
expirationSeconds: 3600
audience: test
EOF
The jump pod logs will contain the decoded JWT.
Note that the values like audience, expirationSeconds etc can be customized in the manifest while the azure-identity-token behaviour can be modified adding custom labels on the pod.
Jump pod for verifying access token
1
2
3
kubectl run az-cli -n default -l "azure.workload.identity/use=true" --image=mcr.microsoft.com/azure-cli -i --tty --rm --command /usr/bin/env --overrides='{"spec": { "serviceAccount": "workload-identity-sa" }}' -- sh
az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID
az account get-access-token
How to check the pod is labeled
1
kubectl get pods -A -o json | jq -r '["Namespace", "Pod-Name"], (.items[] | select(.metadata.labels."azure.workload.identity/use" == "true") | [.metadata.namespace, .metadata.name]) | @tsv' | column -t
Get all deployments with the labels on
1
kubectl get deployments --all-namespaces -o json | jq -r '.items[] | select(.spec.template.metadata.labels."azure.workload.identity/use" == "true") | "\(.metadata.namespace) \(.metadata.name)"'
Token comparison
Displayed below are three decoded tokens arranged side by side: the first is a standard service account token, the middle one represents an Azure identity token, and the third corresponds to an Azure access token.
Limitations
- You can only have 20 federated identity credentials per managed identity.