<p>I am new to AWS and was a bit stumped with a particular error. I have looked around but haven't found a good answer yet.</p>
<p>I have a Kubernetes EKS cluster and am trying to read from an S3 bucket within a Pod. After executing <code>aws s3 ls</code>, I get the following error:</p>
<pre><code>An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity
</code></pre>
<p>When I run <code>sudo aws s3 ls</code>, I do see all the files from the S3 bucket.</p>
<p>The Pod where I am running this from looks like the following:</p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/psp: eks.privileged
  creationTimestamp: &quot;2022-03-08T02:22:14Z&quot;
  generateName: k8sray-cloud-head-
  labels:
    cluster.ray.io/component: k8sray-cloud-ray-head
    ray-cluster-name: k8sray-cloud
    ray-file-mounts-contents: da39a3ee5e6b4b0d3255bfef95601890afd80709
    ray-launch-config: 9c53947fee819b4275ae8211895b80d2566b60f4
    ray-node-name: k8sray-cloud-head
    ray-node-status: up-to-date
    ray-node-type: head
    ray-node-uuid: 9a6be68f-d342-4be0-b430-4a4897a4b102
    ray-runtime-config: 4221eb98d4ff536b31e5e087d599091ccbbb488d
    ray-user-node-type: head-node
  name: k8sray-cloud-head-c58v8
  namespace: example
  ownerReferences:
  - apiVersion: cluster.ray.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: RayCluster
    name: k8sray-cloud
    uid: a63d636c-fe59-4119-b86b-33dbd490e77e
  resourceVersion: &quot;149506313&quot;
  selfLink: /api/v1/namespaces/ds7/pods/k8sray-cloud-head-c58v8
  uid: 8520596a-0919-4533-84aa-f179c4274314
spec:
  containers:
  - args:
    - 'trap : TERM INT; touch /tmp/raylogs; tail -f /tmp/raylogs; sleep infinity &amp;
      wait;'
    command:
    - /bin/bash
    - -c
    - --
    env:
    - name: AWS_DEFAULT_REGION
      value: &lt;region&gt;
    - name: AWS_REGION
      value: &lt;region&gt;
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::&lt;appropriate id&gt;:role/&lt;role&gt;
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    image: &lt;image&gt;
    imagePullPolicy: IfNotPresent
    name: ray-node
    ports:
    - containerPort: 6379
      protocol: TCP
    - containerPort: 10001
      protocol: TCP
    - containerPort: 8265
      protocol: TCP
    - containerPort: 8000
      protocol: TCP
    resources:
      limits:
        cpu: &quot;2&quot;
        memory: 4Gi
        nvidia.com/gpu: &quot;0&quot;
      requests:
        cpu: &quot;2&quot;
        ephemeral-storage: 1Gi
        memory: 4Gi
        nvidia.com/gpu: &quot;0&quot;
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /dev/shm
      name: dshm
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: k8sva-01-token-w55qf
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: &lt;left-blank&gt;
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext:
    fsGroup: 65534
  serviceAccount: k8sva-01
  serviceAccountName: k8sva-01
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: aws-iam-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
  - emptyDir:
      medium: Memory
    name: dshm
  - name: k8sva-01-token-w55qf
    secret:
      defaultMode: 420
      secretName: k8sva-01-token-random
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: &quot;2022-03-08T02:22:14Z&quot;
    status: &quot;True&quot;
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: &quot;2022-03-08T02:22:16Z&quot;
    status: &quot;True&quot;
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: &quot;2022-03-08T02:22:16Z&quot;
    status: &quot;True&quot;
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: &quot;2022-03-08T02:22:14Z&quot;
    status: &quot;True&quot;
    type: PodScheduled
  containerStatuses:
  - containerID: docker://0c10ab356dbc042aaf88b45c357d9f0882a03eff062c3da9fa2db65f7fcaae84
    image: &lt;some-image&gt;
    imageID: &lt;some-image-id&gt;
    lastState: {}
    name: ray-node
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: &quot;2022-03-08T02:22:15Z&quot;
</code></pre>
<p>The service account that is linked looks like:</p>
<pre><code>apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::&lt;appropriate-name&gt;:role/&lt;role&gt;
  creationTimestamp: &quot;2022-03-08T01:11:56Z&quot;
  name: k8sva-01
  namespace: example
  resourceVersion: &quot;149488496&quot;
  selfLink: /api/v1/namespaces/ds7/serviceaccounts/k8sva-01
  uid: 019fe48c-cfec-4961-824c-31bc867b59f8
secrets:
- name: k8sva-01-token-random
</code></pre>
<p>The IAM role that is linked has a trust policy of:</p>
<pre><code>{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: {
                &quot;Service&quot;: &quot;ec2.amazonaws.com&quot;
            },
            &quot;Action&quot;: &quot;sts:AssumeRole&quot;
        }
    ]
}
</code></pre>
<p>I've tried something like the following:</p>
<pre><code>{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: {
                &quot;Service&quot;: &quot;ec2.amazonaws.com&quot;
            },
            &quot;Action&quot;: &quot;sts:AssumeRole&quot;
        },
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: {
                &quot;Federated&quot;: &quot;arn:aws:iam::&lt;appropriate-name&gt;:oidc-provider/&lt;oidc-provider&gt;&quot;
            },
            &quot;Action&quot;: &quot;sts:AssumeRoleWithWebIdentity&quot;,
            &quot;Condition&quot;: {
                &quot;StringEquals&quot;: {
                    &quot;&lt;oidc-provider&gt;:sub&quot;: &quot;system:serviceaccount:*&quot;,
                    &quot;&lt;oidc-provider&gt;:aud&quot;: &quot;sts.amazonaws.com&quot;
                }
            }
        }
    ]
}
</code></pre>
<p>How can I resolve this error?</p>

Kun Hwi Ko
<p>You should try to use trust policy only with :sub condition, without :aud. Like:</p>
<pre><code>{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: {
                &quot;Federated&quot;: &quot;arn:aws:iam::&lt;appropriate-name&gt;:oidc-provider/&lt;oidc-provider&gt;&quot;
            },
            &quot;Action&quot;: &quot;sts:AssumeRoleWithWebIdentity&quot;,
            &quot;Condition&quot;: {
                &quot;StringEquals&quot;: {
                    &quot;&lt;oidc-provider&gt;:sub&quot;: &quot;system:serviceaccount:&lt;namespace&gt;:&lt;sa&gt;&quot;
                }
            }
        }
    ]
}
</code></pre>
<p>And please note that if you are using wildcards, you should use &quot;StringLike&quot; operator, not &quot;StringEquals&quot;</p>
