Andreas Foteas
Andreas Foteas

Reputation: 452

Accessing Kubernetes api via Bearer Token Authorization

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?

Upvotes: 1

Views: 3200

Answers (3)

If you’re using a Kubernetes cluster with RBAC enabled, the service account may not be authorized to access the API server. The simplest way to allow you to query the API server is to work around RBAC by running the following command:

kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts

This gives all service accounts (we could also say all pods) cluster-admin privileges, allowing them to do whatever they want. PLEASE NOTE: Obviously, doing this is dangerous and should never be done on production clusters. For test purposes, it’s fine.

Upvotes: 0

Andreas Foteas
Andreas Foteas

Reputation: 452

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

Upvotes: 0

hoque
hoque

Reputation: 6471

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": []
}

Upvotes: 3

Related Questions