Amazon EKS offers two ways to give a pod an IAM role: IAM Roles for Service Accounts (IRSA) and EKS Pod Identity. From the AWS side, how does each wire the pod's Kubernetes ServiceAccount to an IAM role, and what does Pod Identity change operationally?
answer
- two ways to give a pod a role
- one trusts an issuer, one trusts a service
- the trust policy names the cluster, or not
- adding a cluster should not edit IAM
- agent add-on versus OIDC provider
basics
~20 sIRSA registers the cluster's OIDC issuer as an IAM identity provider and each role trusts that provider with a condition on the service account subject. Pod Identity instead trusts the pods.eks.amazonaws.com service principal and maps roles through an association, so roles need no per-cluster trust edits.
solid answer
~50 sWith **IRSA**, you register the cluster's OIDC issuer as an IAM OIDC identity provider, annotate the ServiceAccount with `eks.amazonaws.com/role-arn`, and write a role trust policy whose `Federated` principal is that provider, with conditions pinning the token's subject to `system:serviceaccount:<namespace>:<name>` and its audience to `sts.amazonaws.com`. The pod gets a projected token and the SDK calls `sts:AssumeRoleWithWebIdentity`. With **EKS Pod Identity**, you install the Pod Identity Agent add-on and create an association linking a cluster, namespace and service account to a role; the role's trust policy simply allows the `pods.eks.amazonaws.com` service principal to `sts:AssumeRole` and `sts:TagSession`, and the agent serves credentials through the container credentials endpoint. Operationally the difference is trust-policy churn: IRSA ties every role to a specific cluster's issuer, so N clusters means N trust-policy entries and eventual size limits, while a Pod Identity role is cluster-agnostic and reusable, with the mapping managed through the EKS API and session tags available for ABAC.
code
json · 10 lines{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": ["sts:AssumeRole", "sts:TagSession"]
}
]
}go deeper
Know that on EKS a pod can be given its own IAM role instead of a static key, and that letting workloads use the node's role means every pod shares the same permissions.
Explain the wiring of each: an OIDC identity provider plus an annotated ServiceAccount and a conditioned trust policy for IRSA, versus an agent add-on plus an association and a service-principal trust policy for Pod Identity.
Show the operational judgment — trust-policy churn and size limits across clusters, where the mapping is audited and revoked, and the prerequisites that decide whether Pod Identity is usable for a given workload.
Own the workload-identity standard for the estate: one mechanism by default, a role-per-workload rule with no node-profile fallback, and a migration plan that does not require every team to rewrite trust policies at once.
## The shared goal Both mechanisms exist so a pod can hold an IAM role instead of a static access key, and so that role can be scoped per workload rather than per node. Without either, every pod on a node inherits the node instance profile — which means the log shipper's permissions and the payments service's permissions are the same set, and there is no boundary at all. ## IRSA: federation through the cluster's OIDC issuer Every EKS cluster publishes an OIDC issuer URL. IRSA setup has four pieces: 1. Register that issuer in IAM as an **OIDC identity provider** — one per cluster. 2. Annotate the ServiceAccount: `eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/orders`. 3. Write the role's trust policy against that provider: ```json { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:orders:orders-api", "oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com" } } } ``` 4. An admission webhook in the cluster injects `AWS_ROLE_ARN` and `AWS_WEB_IDENTITY_TOKEN_FILE` into pods using that ServiceAccount, along with a projected token volume. The SDK's web-identity provider reads the file and calls `sts:AssumeRoleWithWebIdentity`. The fence is precise — subject and audience conditions pin the role to one service account in one namespace of one cluster. Omitting the `:sub` condition is a real and serious misconfiguration: any service account in that cluster could then take the role. ## Pod Identity: a service principal and an association Pod Identity moves the wiring out of the trust policy: 1. Install the **EKS Pod Identity Agent** add-on, which runs as a DaemonSet. 2. Create a **Pod Identity association** — cluster, namespace, service account name, role ARN — through the EKS API, CLI, or IaC. 3. The role's trust policy is short and cluster-agnostic: ```json { "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": ["sts:AssumeRole", "sts:TagSession"] } ``` 4. The agent serves credentials on a local endpoint; the SDK finds it through the container credentials environment variables EKS injects, the same provider ECS tasks use. No ServiceAccount annotation, no per-cluster IAM OIDC provider, no trust-policy edit when a new cluster appears. ## What actually changes operationally - **Reuse across clusters.** An IRSA role's trust policy names one issuer; adding the same workload in a second cluster means editing that policy. Trust policies also have a document size limit, so a role shared across many clusters eventually cannot grow further. A Pod Identity role is written once and associated as many times as needed. - **Where the mapping lives.** IRSA's mapping is split between an IAM trust policy and a Kubernetes annotation, edited by two different teams with two different tools. Pod Identity keeps it in one EKS API object, which is easier to enumerate, audit and revoke — deleting the association immediately stops new credentials. - **Session tags.** Pod Identity's `sts:TagSession` lets EKS attach cluster, namespace and service-account tags to the session, usable in ABAC policy conditions. - **Prerequisites.** Pod Identity needs the agent add-on running on the node, and reasonably recent AWS SDK versions that support the container credentials provider variables it uses. IRSA needs no in-cluster agent beyond the identity webhook EKS already runs. - **Coverage.** As of 2025, Pod Identity covers pods on EC2 nodes; IRSA remains the mechanism for pods running on Fargate, and remains fully supported — this is not a deprecation. IRSA's OIDC federation is also the pattern you already use for GitHub Actions and other external identity providers, so teams often keep it for consistency. ## How to answer the choice New clusters, many workloads, roles shared across clusters: Pod Identity, because it removes the trust-policy churn and centralises the mapping. Existing IRSA estates, Fargate pods, or a strong reason to express the trust in IAM itself: keep IRSA. Either way the point an interviewer is checking is that no pod carries a static key and no workload rides on the node instance profile.
- What breaks if an IRSA role's trust policy omits the :sub condition?The role becomes assumable by any service account in that cluster, because the only remaining constraint is the OIDC provider itself. Any workload that can read a projected token — including a compromised sidecar in an unrelated namespace — can take the role. The subject condition pinning system:serviceaccount:<namespace>:<name> is what makes IRSA a per-workload boundary rather than a per-cluster one.
- Why would a platform team still standardise on IRSA despite Pod Identity's advantages?Three reasons: an existing estate of roles already wired to cluster issuers that is not worth churning; pods running on Fargate, which Pod Identity does not cover; and consistency with the OIDC federation pattern already used for GitHub Actions and other external identity providers, so one mental model covers every workload identity in the account.
- How do you revoke a workload's AWS access quickly under each mechanism?Under Pod Identity, delete the association — the mapping lives in one EKS API object and new credential requests stop immediately. Under IRSA, you edit the role's trust policy or remove the ServiceAccount annotation, touching two systems. In both cases already-issued temporary credentials remain valid until they expire, so a hard cutoff means attaching a deny policy or deleting the role.
saying these in an interview costs you the question
- Saying pods just use the node's instance profile
- Writing an IRSA trust policy without the subject condition
- Assuming Pod Identity deprecates and replaces IRSA
- Thinking a single IRSA role works across clusters unchanged
- Expecting Pod Identity to work without the agent add-on installed