Accessing Kubernetes api via Bearer Token Authorization

5/14/2020

I am trying to access a kubernetes cluster using the rest api. I followed the instructions of this but i wanted to get the pods of the cluster.

APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)

curl $APISERVER/api/v1/pods --header "Authorization: Bearer $TOKEN" --insecure

the result is:

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403

I tried the same (curl localhost:8001/api/v1/pods) by running the command:

kubectl proxy --address='0.0.0.0' --disable-filter=true

at the master node of the cluster and now it works as desired.

How can I make the Athorization Bearer work in the same manner?

-- Andreas Foteas
kubernetes

2 Answers

5/16/2020

In order to be able to get the pods for all the namespaces then you have to define a cluster-role and a cluster-role-binding, instead of a role/role-binding pair

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: get-pods
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: get-pods-binding
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: get-pods
  apiGroup: rbac.authorization.k8s.io

You may save this to a file named for example get_pods_role.yaml and execute kubectl create -f get_pods_role.yaml. Then you will be able to get the desired output by this:

APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)

curl $APISERVER/api/v1/pods --header "Authorization: Bearer $TOKEN" --insecure
-- Andreas Foteas
Source: StackOverflow

5/14/2020

You are using default service account to get pods. default serviceaccount don't have that permission. You can check an action is allowed or not by running

$ kubectl auth can-i get pods --as system:serviceaccount:default:default
no

"message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" at the cluster scope",

as can be seen above the default service account cannot list pods

but when given proper role and role binding like below

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: demo-role
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: demo-binding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: demo-role
subjects:
- kind: ServiceAccount
  name: default
  namespace: default

Now if you check

$ kubectl auth can-i get pods --as system:serviceaccount:default:default
yes

If you want to list pods of default namespace using api then run

$ APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
$ SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
$ TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)

$ curl $APISERVER/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "1589"
  },
  "items": []
}
-- hoque
Source: StackOverflow