Amazon EKS — IRSA — IAM Roles for Service Accounts
IRSA — IAM Roles for Service Accounts
IRSA lets Kubernetes pods assume AWS IAM roles without using node-level credentials. This is the recommended way to give pods access to AWS services.
How IRSA Works
IRSA Flow
┌────────────────────────────────────────────────────────────┐
│ │
│ 1. Create IAM role with trust policy for EKS OIDC │
│ 2. Create K8s ServiceAccount annotated with IAM role ARN │
│ 3. Pod uses ServiceAccount │
│ 4. AWS SDK in pod automatically gets temporary credentials │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Pod │───▶│ ServiceAcct │───▶│ IAM Role │ │
│ │ (aws-sdk)│ │ (annotated) │ │ (S3 access, etc) │ │
│ └──────────┘ └──────────────┘ └──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ STS AssumeRoleWithWebIdentity ◀──── EKS OIDC Provider │
│ │ │
│ ▼ │
│ Temporary credentials injected into pod as env vars │
│ (AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE) │
└────────────────────────────────────────────────────────────┘
Set Up IRSA
Step 1: Enable OIDC Provider
$ eksctl utils associate-iam-oidc-provider --cluster demo --approve
Step 2: Create IAM Role + ServiceAccount
$ eksctl create iamserviceaccount \
--cluster demo \
--name s3-reader \
--namespace default \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve
Step 3: Use in Pod
apiVersion: v1
kind: Pod
metadata:
name: s3-app
spec:
serviceAccountName: s3-reader # References IRSA ServiceAccount
containers:
- name: app
image: amazon/aws-cli
command: ["aws", "s3", "ls"]
Why Not Use Node IAM Role?
| Method | Security | Blast Radius |
|---|---|---|
| Node IAM role | Low | ALL pods on the node get same permissions |
| IRSA | High | Only pods with the ServiceAccount get permissions |
| Access keys in secrets | Very Low | Keys can be leaked, never expire |
Always use IRSA. Never attach AWS policies to the node IAM role for application access.
Common Mistakes
| Mistake | Impact |
|---|---|
| Using node IAM role for S3/DynamoDB access | All pods on node can access those services |
| Forgetting to enable OIDC provider | IRSA doesn’t work |
| Too broad IAM policies | Pod has more permissions than needed |
| Not testing credentials in pod | Hard to debug later |
Quick Reference
# Enable OIDC
$ eksctl utils associate-iam-oidc-provider --cluster demo --approve
# Create IRSA
$ eksctl create iamserviceaccount --cluster demo --name my-sa \
--attach-policy-arn <policy-arn> --approve
# Verify
$ kubectl describe sa my-sa
# Should show: Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::...
What’s Next?
Kubernetes authorization: Kubernetes RBAC.