Assume an AWS IAM Role from Kubernetes pod using OIDC
Ever wondered how an application running in a kubernetes pod, can access AWS resources like S3 bucket? Well this is not straight forward…
Assume an AWS IAM Role from Kubernetes pod using OIDC
Ever wondered how an application running in a kubernetes pod, can access AWS resources like S3 bucket? Well this is not straight forward. Even though both EKS and S3 are AWS resources, they don’t get a free pass to access each other. In this case Kubernetes pod need to be allowed to access S3 bucket.
There are different ways to get it done. Here I will focus on a method called IRSA(IAM Role for Service Accounts). If I have to explain it in one line then what it means is that a ServiecAccount in the pod will assume a role in IAM using OIDC and that allows the pod(or any application in that pod) to access AWS resources. Phew…Thats one line but one heck of a long line!!!
NOTE: There is another way to achieve this and thats by using “EKS Pod Identity”
Now Lets get into details of how to configure it.
IdP Configuration in EKS
- When EKS cluster is configured, it automatically is configured to be an IdP(Identity Provider)
- Go to EKS cluster and note down OpenID Connect provider URL
Configure EKS as a Web Identity Provider on AWS
Web Identity Providers allow the system to receive an authentication token, and then use or exchange that token for temporary security credentials in AWS. These temporary security credentials map to an IAM role with permissions to use the resources in your AWS account
- Go to IAM and click on “Identity Providers”
- Select the Add provider button.
- In the Configure provider section, select OpenID Connect.
- Set the Provider URL that was collected from EKS console above, to the corresponding text field. The Provider URL is the secure OpenID Connect URL used for authentication requests.
- Set the Audience as sts.amazonaws.com. The audience is the client ID issued by the Identity provider for your app.
- Select the Add provider button.
Create an Identity and Access Management (IAM) role
We need to configure a role in AWS, which can be assumed by pod serviceAccount, which in turn access resources from bitbucket pipeline
- Access AWS Identity and Access Management (IAM).
- Select Roles under the Access management heading on the left sidebar.
- Select Create role.
- Select Web identity as the type of trusted entity.
- Select the Identity provider dropdown and choose the identity provider created from your configuration above.
- Select the Audience dropdown and choose the audience created from your configuration above.
- Select Next: Permissions.
- Select the permission policy or policies from the list of permission policies to attach to you new role. You may need to search for the policy, if you do not see it on the current list.
- On the Create role page, enter Role name as developer
- Select Create role.
- Go to trust relationship tab of the role. It should look something like below. Note that you can control who can assume this role by the value in Condition/StringEquals. Below example checks the value of the aud attribute and sub attribute. If this value doesn’t match, then bitbucket user will not be allowed to assume role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<ACCOUNT ID>:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/66F55B6D3C5C3E1C1441D99DDD141522"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-2.amazonaws.com/id/66F55B6D3C5C3E1C1441D99DDD141522:aud": "sts.amazonaws.com",
"oidc.eks.us-west-2.amazonaws.com/id/66F55B6D3C5C3E1C1441D99DDD141522:sub": "system:serviceaccount:<APPLICATION NAMESPACE>:<APPLICATION NAME>"
}
}
}
]
}
Service Account Annotation
- Deploy a ServiceAccount and annotate with the ARN of the AWS IAM role created above
- A ServiceAccount would look like this. Annotation eks.amazonaws.com/role-arn is important
apiVersion: v1
items:
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2024-05-06T21:20:56Z"
name: default
namespace: <YOUR NAME SPACE>
resourceVersion: "23247740"
uid: ff94b1fe-c49c-401e-8815-30b4c523d612
- apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: <ARN OF ROLE CREATED ABOVE>
creationTimestamp: "2025-04-01T16:46:56Z"
labels:
app.kubernetes.io/instance: <APPLICATION NAME>
app.kubernetes.io/name: <APPLICATION NAME>
app.kubernetes.io/version: 02.03.000
name: <APPLICATION NAME>
namespace: <APPLICATION NAME SPACE>
Pod Configuration
- Configure your Kubernetes Pod to use this annotated Service Account.
- In deployment template refer above ServiceAccount
serviceAccount: <SERVICE ACCOUNT>
serviceAccountName: <SERVICE ACCOUNT NAME>
- After a pod is deployed you should see below env variables
- name: AWS_ROLE_ARN
value: <ARN OF ROLE set in ServiceAccount above>
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
Token Exchange
- When the pod needs to access an AWS resource, the AWS SDKs within the pod automatically detect the OIDC token issued by Kubernetes, inside AWS_WEB_IDENTITY_TOKEN_FILE and exchange it with AWS STS (Security Token Service) for temporary AWS credentials by calling
sts:AssumeRoleWithWebIdentity.
Resource Access:
- The pod then uses these temporary AWS credentials to access the designated AWS resources, such as S3 buckets or EC2 instances, according to the permissions defined in the IAM role.
Following picture gives an overview of the assuming role using IRSA

메타데이터
- post_id
- ec09c998b72f
- slug
- assume-an-aws-iam-role-from-kubernetes-pod-using-oidc-ec09c998b72f
- url
- https://medium.com/@rabisankar_19947/assume-an-aws-iam-role-from-kubernetes-pod-using-oidc-ec09c998b72f
- canonical_url
- https://medium.com/@rabisankar_19947/assume-an-aws-iam-role-from-kubernetes-pod-using-oidc-ec09c998b72f
- author_url
- https://medium.com/@rabisankar_19947
- status
- ok
- fetched_at
- 2026-07-23 01:15:00