<p>I have a Java code running in an EKS container. The code is getting the AWS credentials from the Amazon EC2 Instance Metadata Service (software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider#create).</p>
<p>The code tries to invoke the get/read job API on the EKS it is running on but gets a 403 Forbidden error.</p>
<p>How can I allow the code to invoke K8S APIs?</p>
<p>The response I get is:</p>
<pre><code>{&quot;kind&quot;:&quot;Status&quot;,&quot;apiVersion&quot;:&quot;v1&quot;,&quot;metadata&quot;:{},&quot;status&quot;:&quot;Failure&quot;,&quot;message&quot;:&quot;jobs.batch \&quot;my-k8s-job\&quot; is forbidden: User \&quot;system:node:ip-10-176-13-105.eu-central-1.compute.internal\&quot; cannot get resource \&quot;jobs\&quot; in API group \&quot;batch\&quot; in the namespace \&quot;default\&quot;&quot;,&quot;reason&quot;:&quot;Forbidden&quot;,&quot;details&quot;:{&quot;name&quot;:&quot;my-k8s-job&quot;,&quot;group&quot;:&quot;batch&quot;,&quot;kind&quot;:&quot;jobs&quot;},&quot;code&quot;:403}

                ... 38 more
        Caused by: io.kubernetes.client.openapi.ApiException:
                at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:973) ~[client-java-api-12.0.0.jar:?]
                at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:885) ~[client-java-api-12.0.0.jar:?]
                at io.kubernetes.client.openapi.apis.BatchV1Api.readNamespacedJobWithHttpInfo(BatchV1Api.java:3010) ~[client-java-api-12.0.0.jar:?]
                at io.kubernetes.client.openapi.apis.BatchV1Api.readNamespacedJob(BatchV1Api.java:2980) ~[client-java-api-12.0.0.jar:?]
...
</code></pre>
<p>Thanks.</p>

MosheElisha
<p>Once you deploy some application into Kubernetes cluster, it will <a href="https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume" rel="nofollow noreferrer">mount</a> the service account token into your pod as a volume. It will give you possibility to work with kubernetes API inside the pod.</p>
<p>You may run <code>kubectl describe pod &lt;podname&gt;</code> command to get the description of the pod. In the volumes section you will find the secret, which is created automatically for ServiceAccount in particular namespace (Please, see the log below)</p>
<pre><code>home-pc$ kubectl describe pod kctl --context kind-test1
Name:         kctl
Namespace:    default
Priority:     0
Node:         test1-control-plane/172.18.0.2
Start Time:   Thu, 18 Mar 2021 14:56:40 +0200
Labels:       run=kctl
Annotations:  &lt;none&gt;
Status:       Running
IP:           10.244.0.5
IPs:
  IP:  10.244.0.5
Containers:
  kctl:
    Container ID:  containerd://4cbfa744471b36f442f6b59f62aa8fdc444cfc8e2c8bf11e40714ba0b3496c55
    Image:         bitnami/kubectl
    Image ID:      docker.io/bitnami/kubectl@sha256:3d6f0d61bff29d873327d80ca17fe32a31b6ddeffac1e894955c2acedb96c6a1
    Port:          &lt;none&gt;
    Host Port:     &lt;none&gt;
    Command:
      sleep
      5000
    State:          Running
      Started:      Thu, 18 Mar 2021 14:57:02 +0200
    Ready:          True
    Restart Count:  0
    Environment:    &lt;none&gt;
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qjdpp (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-qjdpp:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-qjdpp
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  &lt;none&gt;
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                          Message
  ----    ------     ----  ----                          -------
  Normal  Scheduled  43s   default-scheduler             Successfully assigned default/kctl to test1-control-plane
  Normal  Pulling    42s   kubelet, test1-control-plane  Pulling image &quot;bitnami/kubectl&quot;
  Normal  Pulled     22s   kubelet, test1-control-plane  Successfully pulled image &quot;bitnami/kubectl&quot; in 20.3423277s
  Normal  Created    21s   kubelet, test1-control-plane  Created container kctl
  Normal  Started    21s   kubelet, test1-control-plane  Started container kctl
</code></pre>
<pre><code>home-pc$ kubectl get secrets --context kind-test1
NAME                  TYPE                                  DATA   AGE
default-token-qjdpp   kubernetes.io/service-account-token   3      5m39s
</code></pre>
<p>Obviously, your pod will have the same number of permissions as your ServiceAccount.</p>
<p>ServiceAccount bound with specific Role (ClusterRole) through the RoleBinding (ClusterRoleBinding).</p>
<p>At the same time, Role (or ClusterRole) is the place where you might want to add more permissions for specific resource</p>
<p>Please follow <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#referring-to-resources" rel="nofollow noreferrer">this document</a> for more information.</p>
<p>Hope it will help.</p>
<p>UPD:
For your particular case you need to add possibility to work with Jobs, so your Role should be the next:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: your-namespace
  name: job-watcher
rules:
- apiGroups: [&quot;batch&quot;]
  resources: [&quot;jobs&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;update&quot;, &quot;delete&quot;, &quot;create&quot;]
</code></pre>
