EKS Pod Identity

Applications running in pods can use an AWS SDK or the AWS CLI to make API requests to AWS services using IAM permissions. Until recently, IRSA (IAM Roles for Service Accounts) using OpenID Connect was the standard authentication mechanism for pods.
EKS Pod Identity was introduced to simplify this process. It enables mapping a Kubernetes ServiceAccount directly to an AWS IAM role, simplifying configuration and enabling IAM role reuse across clusters.
Configuring Pod Identity
- Install the EKS Pod Identity agent add-on
- Create an IAM role with a Pod Identity trust policy and assign necessary permissions
- Create a Pod Identity association on the EKS cluster
- Configure the application to use the configured ServiceAccount
Scenario
Your pod must be able to list and retrieve objects from an S3 bucket. The Pod Identity agent is already installed on the EKS cluster. The application runs in the example namespace using ServiceAccount exampleserviceaccount.
Create an IAM role
Create an IAM role with the Pod Identity trust policy below. Attach the necessary S3 permissions and name the role pod-id-example-role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEksAuthToAssumeRoleForPodIdentity",
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
Associate the ServiceAccount with the role
Navigate to AWS Console → EKS cluster → Access tab → Create Pod Identity association. Specify the role, namespace, and ServiceAccount name.

Deploy the application
Create the ServiceAccount in the example namespace and configure the app to use it. The pod below has the AWS CLI pre-installed for testing.
cat >example.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: example
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: exampleserviceaccount
namespace: example
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: dvawscli
name: dvawscli
namespace: example
spec:
replicas: 1
selector:
matchLabels:
app: dvawscli
template:
metadata:
labels:
app: dvawscli
spec:
serviceAccountName: exampleserviceaccount
containers:
- image: dennysv/dvawscli
name: dvawscli
resources: {}
EOF
Apply and test:
kubectl apply -f example.yaml
# Exec into the pod and verify S3 access
kubectl exec -it deployment/dvawscli -n example -- bash
aws s3 ls s3://eks-automation/
Pod Identity vs IRSA comparison
Pod Identity and IRSA are both methods for granting pods access to AWS resources on EKS. Pod Identity is more flexible — it works across clusters, requires no ServiceAccount annotations, and enables IAM role reuse. It behaves similarly to an EC2 instance profile.
| Pod Identity | IRSA |
|---|---|
| No external authentication provider needed | Requires an OIDC provider to be configured |
| ServiceAccount name maps to the role | Requires a ServiceAccount annotation with the IAM role ARN |
| Works across clusters | Bound to a single OIDC provider |
| IAM role can be reused across clusters | IAM role trust policy is tied to a specific OIDC configuration |
Terraform example
Creates an IAM role with Pod Identity trust policy, attaches S3 read-only access, and associates it with a namespace and ServiceAccount.
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["pods.eks.amazonaws.com"]
}
actions = [
"sts:AssumeRole",
"sts:TagSession"
]
}
}
resource "aws_iam_role" "example" {
name = "eks-pod-identity-example"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
resource "aws_iam_role_policy_attachment" "example_s3" {
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
role = aws_iam_role.example.name
}
resource "aws_eks_pod_identity_association" "example" {
cluster_name = aws_eks_cluster.example.name
namespace = "example"
service_account = "exampleserviceaccount"
role_arn = aws_iam_role.example.arn
}