← Back to list

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…

Rabisankar · 2025-08-01 18:50 · 0 claps · 3.1 min read
#aws-eks #kubernetes #assume-role #oidc #pods
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud 🏃 · Running & Endurance

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

  1. When EKS cluster is configured, it automatically is configured to be an IdP(Identity Provider)
  2. 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

  1. Go to IAM and click on “Identity Providers”
  2. Select the Add provider button.
  3. In the Configure provider section, select OpenID Connect.
  4. 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.
  5. Set the Audience as sts.amazonaws.com. The audience is the client ID issued by the Identity provider for your app.
  6. 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

  1. Access AWS Identity and Access Management (IAM).
  2. Select Roles under the Access management heading on the left sidebar.
  3. Select Create role.
  4. Select Web identity as the type of trusted entity.
  5. Select the Identity provider dropdown and choose the identity provider created from your configuration above.
  6. Select the Audience dropdown and choose the audience created from your configuration above.
  7. Select Next: Permissions.
  8. 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.
  9. On the Create role page, enter Role name as developer
  10. Select Create role.
  11. 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

  1. Deploy a ServiceAccount and annotate with the ARN of the AWS IAM role created above
  2. 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

  1. Configure your Kubernetes Pod to use this annotated Service Account.
  2. In deployment template refer above ServiceAccount
serviceAccount: <SERVICE ACCOUNT>
serviceAccountName: <SERVICE ACCOUNT NAME>
  1. 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

  1. 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:

  1. 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