Reputation: 14018
I have the following api-test
service account in the default namespace:
$ 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
The api-test
service account has role pod-reader
through the following rolebinding:
$ 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
The pod-reader
has access to pod
resources and the get
verb:
$ 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
However, the following kubectl get pods ...
command fails in the default namespace, using user impersonation --as=api-test
:
$ 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"
Checking the authorizations for api-test
reveals that it has get
access to /api/*
:
$ 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]
Why can't my api-test
service account be used to retrieve information about pods in the default namespace?
Indeed, the URL output by kubectl
matches the wildcard path /api/*
:
https://kubernetes.docker.internal:6443/api/v1/namespaces/default/pods?limit=500
Any ideas?
Upvotes: 2
Views: 863
Reputation: 4250
You should use --as=system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)
to authenticate to the API server.
In your example, that is --as=system:serviceaccount:default:api-test
.
The details are available in the Kubernetes documentation:
Service accounts authenticate with the username
system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)
, and are assigned to the groupssystem:serviceaccounts
andsystem:serviceaccounts:(NAMESPACE)
.
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens
Upvotes: 4
Reputation: 44657
Command to create role and rolebinding
kubectl create role pod-reader --resource=pods --verb=get,list,watch --namespace=default
kubectl create rolebinding pod-reader-role-binding --role=pod-reader --serviceaccount=default:api-test -n default
Command to check permission should be
kubectl auth can-i get pods -n default --as=system:serviceaccount:api-test:default
yes
Access the resource
kubectl get pods --as=system:serviceaccount:default:api-test -n default
Upvotes: 3