Topic 5.5
Workload Identity: Cloud Access Without Stored Keys
In one line
Pods often need cloud APIs: S3 for uploads, SQS for orders, Secrets Manager for credentials. Instead of storing long-lived access keys in Secrets, workload identity maps a Kubernetes ServiceAccount to a cloud role. The pod gets short-lived credentials automatically: on EKS through IRSA or EKS Pod Identity, on GKE through Workload Identity Federation, on AKS through Microsoft Entra Workload ID. Each workload gets only its own permissions, and nothing long-lived can leak.
Think of it like this
A hotel guest's room key versus a master key copy. Instead of giving staff a copy of the master key (stored access keys), the front desk issues each person a card that works only for their rooms and expires at the end of the shift (temporary credentials).
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Workload identity
- Giving a pod a cloud identity through its ServiceAccount instead of stored keys.
- IRSA
- IAM Roles for Service Accounts: EKS's OIDC-based way to map ServiceAccounts to IAM roles.
- EKS Pod Identity
- A newer EKS mechanism mapping ServiceAccounts to IAM roles through an agent and API associations.
- Temporary credentials
- Cloud credentials that expire automatically, typically after an hour.
- Trust policy
- The part of a cloud role saying who is allowed to assume it.
- IMDS
- The instance metadata service (169.254.169.254) that gives a VM its own credentials.
Step by step
01From stored keys to a role
The uploads service used an IAM user's access key in a Secret. The team replaces it with EKS Pod Identity: a role with S3 permissions for one bucket prefix, associated with the uploads ServiceAccount.
02The pod gets credentials automatically
The Deployment just names the ServiceAccount. No keys anywhere in Kubernetes. The AWS SDK in the pod finds the injected credential endpoint and assumes the role.
spec:
serviceAccountName: uploads # mapped to IAM role tiffin-uploads
containers:
- name: uploads
image: ghcr.io/tiffin-team/uploads:1.4.0
# no AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY env vars at all03Closing the node-role back door
Without care, any pod can call the instance metadata service and get the node's IAM role, which usually has broad permissions. Setting the metadata hop limit to 1 in the node launch template blocks pods (one network hop away) from reaching it.
Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Every pod uses the node's role
Workloads were given permissions by adding policies to the node group's IAM role 'for simplicity'.
Myth vs fact
Myth
Storing access keys in a Kubernetes Secret is fine if the Secret is encrypted.
Fact
Encryption protects them at rest, but the keys still never expire, get copied into many places, and give long-lived access if leaked. Short-lived credentials remove that risk.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Use condition keys in role policies to narrow further, for example restricting an S3 role to one prefix and requiring the request to come from your VPC endpoint (
aws:SourceVpce).
Remember this
- 1
The old way: an IAM user's access key and secret in a Kubernetes Secret. They never expire, are often over-privileged, get copied around, and are hard to rotate.
- 2
The new way: the pod's ServiceAccount token (a signed, short-lived JWT) is exchanged with the cloud for temporary credentials for one specific role. SDKs do this automatically.
- 3
EKS: IRSA (an IAM OIDC provider plus a role trust policy naming the ServiceAccount, and an annotation on the ServiceAccount) or the newer EKS Pod Identity (an agent DaemonSet and a 'pod identity association' API, no OIDC setup per cluster).
- 4
GKE: Workload Identity Federation lets a Kubernetes ServiceAccount act as an IAM principal. AKS: Microsoft Entra Workload ID uses federated credentials.
- 5
Least privilege per workload: the uploads service's role can write to one S3 prefix, and the orders worker's role can read one SQS queue. A compromised pod gets only its own small set of permissions, for a short time.
- 6
Block pods from using the node's instance role (IMDS hop limit 1 or blocking 169.254.169.254), or every pod inherits the node's permissions.
Explain it without notes
How does a pod get cloud credentials without stored keys?
Why block pods from the instance metadata service?
Practice
Configure IRSA or Pod Identity for one workload and verify its identity.
Find workloads still using static cloud keys.
Trade-offs
- ↔
Workload identity removes long-lived keys and gives per-workload permissions, but requires per-cloud setup (OIDC providers, associations, trust policies). Static keys are quick to set up and much riskier to operate.
Done when you can
My pods use workload identity, not stored cloud keys.
Each workload has its own least-privilege role.
Pods can't use the node's IAM role.