Skip to content

How do I use IRSA in Amazon EKS to restrict access to an Amazon S3 bucket?

6 minute read
1

I want to restrict Amazon Simple Storage Service (Amazon S3) bucket access at the Pod level in Amazon Elastic Kubernetes Service (Amazon EKS). I also want to keep minimum permissions for my application with AWS Identity and Access Management (IAM) roles for service accounts (IRSA).

Resolution

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.

Prerequisites: Create an IAM OpenID Connect (OIDC) provider for your cluster.

Create an IAM policy and role

Complete the following steps:

  1. Create a JSON file named iam-policy.json. Example policy:
    {    
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket"
                ],
                "Resource": "arn:aws:s3:::YOUR_BUCKET"
            },
            {
                "Sid": "List",
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion"
                ],
                "Resource": "arn:aws:s3:::YOUR_BUCKET/*"
            }
        ]
    }
    Note: Replace YOUR_BUCKET with your S3 bucket name. The preceding example policy restricts Amazon S3 permissions so that IAM users can only list and retrieve objects from a S3 bucket.
  2. To create the IAM policy, run the following create-policy AWS CLI command:
    aws iam create-policy \
        --policy-name YOUR_IAM_POLICY_NAME \
        --policy-document file://iam-policy.json
    Note: Replace YOUR_IAM_POLICY_NAME with your policy name.
  3. Create an IAM role and associate it with your cluster service AWS account.
  4. Confirm that you correctly configured the IAM policy and role.
  5. (Optional) To get the role name, run the following command:
    kubectl get sa SERVICE_ACCOUNT_NAME -n NAMESPACE_NAME -o yaml | grep eks.amazonaws.com/role-arn | cut -d '/' -f 3
    Note: Replace SERVICE_ACCOUNT_NAME with your service account name and NAMESPACE_NAME with your namespace name.
    Example output:
    eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE

Create an Amazon EKS Pod

Confirm that your Pod can assume the IAM role with the correct permissions. Complete the following steps to replace your application with an official image in the AWS CLI:

  1. Create a YAML file named aws-cli-pod.yaml. Example file:
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli
      namespace: NAMESPACE_NAME
    spec:
      serviceAccountName: SERVICE_ACCOUNT_NAME
      containers:
      - name: aws-cli
        image: amazon/aws-cli:latest
        command:
          - sleep
          - "3600"
        imagePullPolicy: IfNotPresent
      restartPolicy: Always
    Note: Replace NAMESPACE_NAME with your namespace and SERVICE_ACCOUNT_NAME with your Kubernetes service account name.
  2. To create an Amazon EKS pod, run the following command:
    kubectl apply -f ./aws-cli-pod.yaml

Test your Amazon EKS Pod

Note: In the following example, the Pod can list and get objects from the YOUR_BUCKET S3 bucket.

To confirm that your Pod uses the correct IAM role and actions for Amazon S3, complete the following steps:

  1. To find the IAM role that uses the credentials, run the following command:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws sts get-caller-identity

    Note: Replace NAMESPACE_NAME with your namespace name.
    Example output:

    {   
        "UserId": "AIDACKCEVSQ6C2EXAMPLE:botocore-session-123456789012",
        "Account": "123456789012",
        "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012"
    }
  2. Verify that your Pod has the correct permissions for your S3 bucket.
    To verify that your Pod has s3:ListBuckets permissions, run the following command:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3 ls s3://YOUR_BUCKET

    Note: Replace NAMESPACE_NAME with your namespace name and YOUR_BUCKET with your bucket.
    Example output:

    2025-03-25 22:28:06         14 hello_s3.txt

    To verify that your Pod has s3:GetObject permissions, run the following command:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3api get-object --bucket YOUR_BUCKET --key DIR/S3_OBJECT_FILE S3_FILE_NAME_LOCAL

    Note: Replace NAMESPACE_NAME with your namespace name and YOUR_BUCKET with your bucket. Also, replace DIR/S3_OBJECT_FILE with the directory and object file name and S3_FILE_NAME_LOCAL with the new local Amazon S3 object.
    Example output:

    {
        "AcceptRanges": "bytes",
        "LastModified": "2025-03-14T01:49:38+00:00",
        "ContentLength": 19,
        "ETag": "\"678b33365329cce6cd2bb1882e62fe3a\"",
        "ContentType": "text/plain",
        "ServerSideEncryption": "AES256",
        "Metadata": {}
    }
  3. To verify that your Pod doesn't have s3:DeleteObject permissions, run the following command:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3 rm s3://YOUR_BUCKET/DEMO_TEST_FILE

    Note: Replace NAMESPACE_NAME with your namespace name and YOUR_BUCKET with your bucket. Also, replace DEMO_TEST_FILE with your Amazon S3 object file.
    If the Pod doesn't have s3:DeleteObject permissions, then you receive the following Access Denied error in the output:

    delete failed: s3://YOUR_BUCKET/DEMO_TEST_FILE An error occurred (AccessDenied) when calling the DeleteObject operation: User: arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012 is not authorized to perform: s3:DeleteObject on resource: "arn:aws:s3:::YOUR_BUCKET/DEMO_TEST_FILE" because no identity-based policy allows the s3:DeleteObject action
    command terminated with exit code 1

Troubleshoot issues

Important: Always create new Pods after you make changes. Amazon EKS reflects updates only in newly created Pods, not in the existing ones.

NoSuchBucket error

If you can't find the S3 bucket because it doesn't exist, then you receive the following error:

"An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist command terminated with exit code 254"

To troubleshoot this issue, make sure that you use the correct S3 bucket name in your commands.

NoSuchKey error

If you can't download from a specific S3 bucket path, then you receive the following error:

"An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist."

To troubleshoot this issue, verify that the Amazon S3 path and file name exist in your AWS account.

AccessDenied errors

If you don't have permissions to perform an action on the S3 bucket, then you receive an error. For example, the following error occurs if you can't run the ListObjectsV2 action:

"An error occurred (AccessDenied) when calling the ListObjectsV2 operation: User: arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012 is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::YOUR_BUCKET" because no identity-based policy allows the s3:ListBucket action command terminated with exit code 254"

To troubleshoot this issue, make sure that you added the permission to your IAM role policy.

If there's an error in the IAM identity provider, then you receive the following error:

"An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity command terminated with exit code 254"

To troubleshoot this issue, confirm the following configurations:

InvalidIdentityToken error

If Amazon EKS can't find the OIDC provider your account, then you receive the following error:

"An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: No OpenIDConnect provider found in your account for https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE command terminated with exit code 254"

To troubleshoot this issue, verify that the identity provider for the OIDC exists in IAM.

Related information

IAM policy testing with the IAM policy simulator

Actions, resources, and condition keys for AWS services

AWS OFFICIALUpdated 9 months ago