Amazon EKS — IRSA — IAM Roles for Service Accounts

1 minute read

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.