---
title: "Implementing Workload Identity in AKS"
description: "Implement Microsoft Entra Workload ID in AKS to replace static pod credentials with federated identity and managed identity access."
canonical: "https://adamtheautomator.com/implementing-workload-identity-aks/"
---

# Implementing Workload Identity in AKS

> Implement Microsoft Entra Workload ID in AKS to replace static pod credentials with federated identity and managed identity access.

Source: https://adamtheautomator.com/implementing-workload-identity-aks/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Implementing Workload Identity in AKS](https://adamtheautomator.com/wp-content/uploads/2026/06/26997-implementing-workload-identity-aks-codex.webp)

# Implementing Workload Identity in AKS

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)15 June 20265 min. read

Categories: [Cloud](/category/cloud/)

Tags:[AKS](/tag/aks/)[Azure](/tag/azure/)[Kubernetes](/tag/kubernetes/)[Microsoft Entra](/tag/microsoft-entra/)

Table of Contents

*   [Prerequisites](#prerequisites)
*   [Why Workload Identity Matters](#why-workload-identity-matters)
*   [Enable Workload Identity on AKS](#enable-workload-identity-on-aks)
*   [Create a User-Assigned Managed Identity](#create-a-user-assigned-managed-identity)
*   [Create the Kubernetes Service Account](#create-the-kubernetes-service-account)
*   [Create the Federated Identity Credential](#create-the-federated-identity-credential)
*   [Deploy a Pod That Uses the Identity](#deploy-a-pod-that-uses-the-identity)
*   [Verify the Pod Can Use Azure Without a Secret](#verify-the-pod-can-use-azure-without-a-secret)
*   [Troubleshoot Common Failures](#troubleshoot-common-failures)
*   [Replace Static Secrets Gradually](#replace-static-secrets-gradually)
*   [Clean Up the Demo](#clean-up-the-demo)
*   [Stop Shipping Passwords in Pods](#stop-shipping-passwords-in-pods)

Static credentials are easy to create and hard to defend. One secret lands in a Kubernetes manifest, another gets copied into a pipeline variable, and before long nobody can tell which workload still needs which password.

Azure Kubernetes Service (AKS) has a better pattern: Microsoft Entra Workload ID. Instead of storing long-lived client secrets in pods, a Kubernetes service account can exchange a projected token for a Microsoft Entra access token. The workload gets the Azure access it needs, and you stop treating Kubernetes Secrets like a password vault.

In this tutorial, you’ll configure workload identity for an AKS workload, connect it to a user-assigned managed identity, and verify the pod can access Azure without a static secret.

## Prerequisites

To follow along, you’ll need:

*   An Azure subscription where you can create or modify an AKS cluster.
*   Azure CLI installed and authenticated with `az login`.
*   `kubectl` configured for your AKS cluster.
*   Permission to create managed identities and federated identity credentials.
*   An AKS cluster that supports workload identity.

Related: [Microsoft Entra Workload ID for AKS](https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview)

## Why Workload Identity Matters

A Kubernetes pod often needs to talk to Azure services. It might read a secret from Key Vault, write to a Storage account, or query a database. The old shortcut was to put a client ID and client secret somewhere the pod could read.

That shortcut creates three problems:

*   Secrets are copied into too many places.
*   Rotation becomes an outage risk.
*   Incident response gets harder because nobody knows which pod used which credential.

Workload identity changes the trust model. The pod proves who it is through its Kubernetes service account. Microsoft Entra trusts that service account through a federated identity credential. Azure returns a token without the workload ever storing a password.

| Old pattern | Workload identity pattern |
| --- | --- |
| Store client secret in Kubernetes | Project a short-lived service account token |
| Rotate secret manually | Let token exchange handle credential freshness |
| Hard to map secret to workload | Bind identity to namespace and service account |
| Secret leak can persist | Trust is scoped and revocable |

The goal is not just fewer secrets. The goal is a clearer identity boundary.

## Enable Workload Identity on AKS

If you are creating a new cluster, enable workload identity and the OIDC issuer during cluster creation.

```bash
az aks create \
  --resource-group rg-aks-demo \
  --name aks-workload-demo \
  --enable-oidc-issuer \
  --enable-workload-identity \
  --generate-ssh-keys
```

For an existing cluster, enable both features.

```bash
az aks update \
  --resource-group rg-aks-demo \
  --name aks-workload-demo \
  --enable-oidc-issuer \
  --enable-workload-identity
```

Then retrieve the OIDC issuer URL. You’ll need this URL when creating the federated identity credential.

```bash
AKS_OIDC_ISSUER=$(az aks show \
  --resource-group rg-aks-demo \
  --name aks-workload-demo \
  --query oidcIssuerProfile.issuerUrl \
  --output tsv)

echo $AKS_OIDC_ISSUER
```

If this command returns an empty value, stop. The issuer is not enabled correctly, and the token exchange will not work.

## Create a User-Assigned Managed Identity

Next, create the Azure identity your pod will use.

```bash
az identity create \
  --resource-group rg-aks-demo \
  --name id-aks-reader
```

Capture the identity values.

```bash
IDENTITY_CLIENT_ID=$(az identity show \
  --resource-group rg-aks-demo \
  --name id-aks-reader \
  --query clientId \
  --output tsv)

IDENTITY_PRINCIPAL_ID=$(az identity show \
  --resource-group rg-aks-demo \
  --name id-aks-reader \
  --query principalId \
  --output tsv)

echo $IDENTITY_CLIENT_ID
```

Assign the identity the smallest role it needs. For a quick read-only test, scope the role to a resource group.

```bash
SUBSCRIPTION_ID=$(az account show --query id --output tsv)

az role assignment create \
  --assignee $IDENTITY_PRINCIPAL_ID \
  --role Reader \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/rg-aks-demo
```

Do not assign Contributor just because it makes the demo easier. Workload identity removes static secrets, but it does not fix over-permissioned roles.

## Create the Kubernetes Service Account

A workload identity binding starts in Kubernetes with a service account. Create a namespace and service account annotated with the managed identity client ID.

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: workload-demo
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: workload-reader
  namespace: workload-demo
  annotations:
    azure.workload.identity/client-id: "REPLACE_WITH_CLIENT_ID"
```

Save the file as `service-account.yaml`, replace `REPLACE_WITH_CLIENT_ID`, and apply it.

```bash
kubectl apply -f service-account.yaml
```

The service account name and namespace matter. Microsoft Entra will trust this exact subject string later:

```
system:serviceaccount:workload-demo:workload-reader
```

If the namespace or service account name changes, the federated credential must change too.

## Create the Federated Identity Credential

The federated identity credential connects Microsoft Entra to the Kubernetes service account.

```bash
az identity federated-credential create \
  --resource-group rg-aks-demo \
  --identity-name id-aks-reader \
  --name fic-workload-reader \
  --issuer $AKS_OIDC_ISSUER \
  --subject system:serviceaccount:workload-demo:workload-reader \
  --audience api://AzureADTokenExchange
```

This command says: tokens issued by this AKS OIDC issuer for this Kubernetes service account can be exchanged for tokens as this managed identity.

That is the core trust relationship. Everything else is just getting the pod to use it.

Related: [Configure workload identity federation](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation)

## Deploy a Pod That Uses the Identity

Now create a test pod. The important parts are the service account and the workload identity label.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: azure-cli-test
  namespace: workload-demo
  labels:
    azure.workload.identity/use: "true"
spec:
  serviceAccountName: workload-reader
  containers:
    - name: azure-cli
      image: mcr.microsoft.com/azure-cli:latest
      command: ["/bin/sh", "-c"]
      args:
        - sleep 3600
```

Apply the pod.

```bash
kubectl apply -f pod.yaml
kubectl wait --for=condition=Ready pod/azure-cli-test -n workload-demo --timeout=120s
```

The label tells the workload identity webhook to inject the environment variables and token file the Azure SDK and CLI expect.

## Verify the Pod Can Use Azure Without a Secret

Exec into the pod and sign in with the managed identity.

```bash
kubectl exec -n workload-demo -it azure-cli-test -- /bin/sh
```

Inside the container, run:

```bash
az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" \
  --service-principal \
  --username $AZURE_CLIENT_ID \
  --tenant $AZURE_TENANT_ID

az group show --name rg-aks-demo --query name --output tsv
```

If the role assignment is correct, the command returns the resource group name. No client secret was mounted. No password was copied into a Kubernetes Secret. The workload authenticated through the federated service account token.

## Troubleshoot Common Failures

Workload identity has a few predictable failure modes. Use the table below before changing random pieces.

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `AZURE_FEDERATED_TOKEN_FILE` is missing | Pod label or service account binding is missing | Add `azure.workload.identity/use: "true"` and confirm `serviceAccountName` |
| Token exchange fails | Federated credential subject does not match | Check namespace and service account name exactly |
| Azure command returns authorization error | Identity authenticated but lacks permissions | Fix the Azure RBAC role assignment |
| OIDC issuer is blank | Cluster was not enabled correctly | Enable OIDC issuer and workload identity on the AKS cluster |
| Works in one namespace only | Federated credential is scoped to one service account | Create another credential or use the correct service account |

A good troubleshooting order is:

```bash
kubectl get pod azure-cli-test -n workload-demo -o yaml
kubectl get serviceaccount workload-reader -n workload-demo -o yaml
az identity federated-credential list \
  --resource-group rg-aks-demo \
  --identity-name id-aks-reader
az role assignment list --assignee $IDENTITY_PRINCIPAL_ID --all
```

If the Kubernetes objects look right, check the federated credential. If the credential looks right, check Azure RBAC.

## Replace Static Secrets Gradually

Do not migrate every workload in one sprint. Start with one pod that reads one Azure service. Prove the identity path, then repeat the pattern.

For each workload, document:

*   Namespace and service account name.
*   Managed identity name.
*   Federated identity credential name.
*   Azure role assignment and scope.
*   Azure service the workload accesses.

That list becomes your ownership map. It also makes incident response easier because you can revoke one workload’s trust without hunting for leaked secrets.

## Clean Up the Demo

When you are done testing, remove the demo resources.

```bash
kubectl delete namespace workload-demo

az identity delete \
  --resource-group rg-aks-demo \
  --name id-aks-reader
```

If you created the AKS cluster just for this tutorial, remove the resource group.

```bash
az group delete --name rg-aks-demo --yes --no-wait
```

## Stop Shipping Passwords in Pods

Workload identity is not just another AKS feature to toggle on. It is a better boundary between Kubernetes workloads and Azure resources.

The pattern is simple: enable the OIDC issuer, create a managed identity, bind it to a Kubernetes service account with a federated identity credential, and assign the identity only the Azure permissions it needs. After that, the pod can get Azure tokens without carrying a static client secret.

Start with one workload. Remove one stored secret. Prove the token exchange. Then repeat until static credentials become the exception instead of the default.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fimplementing-workload-identity-aks%2F&text=Implementing%20Workload%20Identity%20in%20AKS)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fimplementing-workload-identity-aks%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fimplementing-workload-identity-aks%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2026/06/featured_image-22.png)

### [Implement Workload Identity in AKS](/implement-workload-identity-aks/)

A deep dive into replacing vulnerable service account credentials with Microsoft Entra Workload Identity in Azure Kubernetes Service (AKS). The post covers federated identity configuration, managed

![](https://adamtheautomator.com/wp-content/uploads/2026/04/featured_image-9.webp)

### [Entra Workload Identity on AKS: No More Secrets](/entra-workload-identity-aks-no-more-secrets/)

Learn how to eliminate Kubernetes secrets by configuring Entra Workload Identity on AKS using OIDC federation, with Bicep and Terraform IaC examples.

![](https://adamtheautomator.com/wp-content/uploads/2026/02/featured_image-23-scaled.webp)

### [Build Auto-Migration Systems for Azure Spot VMs in AKS](/azure-spot-vm-migration-aks/)

Build automated migration systems to handle Azure Spot VM evictions in AKS, keeping workloads running within the 30-second window.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
