<p>I have the following <code>api-test</code> service account in the default namespace:</p>

<pre><code>$ kubectl get serviceaccount api-test -n default -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-03-05T17:15:40Z"
  name: api-test
  namespace: default
  resourceVersion: "27599"
  selfLink: /api/v1/namespaces/default/serviceaccounts/api-test
  uid: dd51ae9e-9729-4084-9e1e-b5421861b215
secrets:
- name: api-test-token-kz796
</code></pre>

<p>The <code>api-test</code> service account has role <code>pod-reader</code> through the following rolebinding:    </p>

<pre><code>$ kubectl get rolebinding api-test:pod-reader -n default -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"api-test:pod-reader","namespace":"default"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"Role","name":"pod-reader"},"subjects":[{"kind":"ServiceAccount","name":"api-test"}]}
  creationTimestamp: "2020-03-17T11:03:36Z"
  name: api-test:pod-reader
  namespace: default
  resourceVersion: "374396"
  selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/api-test:pod-reader
  uid: 5df0d84e-1d64-4750-9e3c-4026ec8193a4
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- kind: ServiceAccount
  name: api-test
</code></pre>

<p>The <code>pod-reader</code> has access to <code>pod</code> resources and the <code>get</code> verb:</p>

<pre><code>$ kubectl get role pod-reader -n default -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pod-reader","namespace":"default"},"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["get","watch","list"]}]}
  creationTimestamp: "2020-03-17T10:47:39Z"
  name: pod-reader
  namespace: default
  resourceVersion: "373233"
  selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/pod-reader
  uid: 19463c6a-3e68-4127-9c0a-ca1f7749af24
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - watch
  - list
</code></pre>

<p>However, the following <code>kubectl get pods ...</code> command fails in the default namespace, using user impersonation <code>--as=api-test</code>:</p>

<pre><code>$ kubectl get pods --as=api-test -n default -v6
I0317 12:52:34.116634   63031 loader.go:359] Config loaded from file:  /Users/nlykkei/.kube/config
I0317 12:52:34.139588   63031 round_trippers.go:438] GET https://kubernetes.docker.internal:6443/api/v1/namespaces/default/pods?limit=500 403 Forbidden in 15 milliseconds
I0317 12:52:34.139857   63031 helpers.go:199] server response object: [{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods is forbidden: User \"api-test\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
}]
F0317 12:52:34.139901   63031 helpers.go:114] Error from server (Forbidden): pods is forbidden: User "api-test" cannot list resource "pods" in API group "" in the namespace "default"
</code></pre>

<p>Checking the authorizations for <code>api-test</code> reveals that it has <code>get</code> access to <code>/api/*</code>:</p>

<pre><code>$ kubectl auth can-i --list --as=api-test -n default
Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
                                                [/api/*]            []               [get]
                                                [/api]              []               [get]
                                                [/apis/*]           []               [get]
                                                [/apis]             []               [get]
                                                [/healthz]          []               [get]
                                                [/healthz]          []               [get]
                                                [/openapi/*]        []               [get]
                                                [/openapi]          []               [get]
                                                [/version/]         []               [get]
                                                [/version/]         []               [get]
                                                [/version]          []               [get]
                                                [/version]          []               [get]
</code></pre>

<p>Why can't my <code>api-test</code> service account be used to retrieve information about pods in the default namespace?</p>

<p>Indeed, the URL output by <code>kubectl</code> matches the wildcard path <code>/api/*</code>:</p>

<p><a href="https://kubernetes.docker.internal:6443/api/v1/namespaces/default/pods?limit=500" rel="nofollow noreferrer">https://kubernetes.docker.internal:6443/api/v1/namespaces/default/pods?limit=500</a></p>

<p>Any ideas?</p>

Shuzheng
<p>You should use <code>--as=system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)</code> to authenticate to the API server. </p>

<p>In your example, that is <code>--as=system:serviceaccount:default:api-test</code>.</p>

<p>The details are available in the Kubernetes documentation:</p>

<blockquote>
  <p>Service accounts authenticate with the username
  <code>system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)</code>, and are assigned
  to the groups <code>system:serviceaccounts</code> and
  <code>system:serviceaccounts:(NAMESPACE)</code>.</p>
</blockquote>

<p><a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens" rel="nofollow noreferrer">https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens</a></p>
