Access Kubernetes APIs using Token

We will try to access kubernetes resources residing in particular namespace, through APIs provided by kubernetes. We would require to use token for this.

Create service account

sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-sa
  namespace: learning

Create service account using above definition,

k create -f sa.yaml

It should create service account in namespace learning. This is the namespace that we are making accessible through APIs requests.

Create Roles and Role Bindings

We need to assign role with appropriate permissions to service account nginx-sa. We can use rbac, where we need to create role and bind service account to this role.

developer.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: learning
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["list"]

Let’s create binding now,

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: learning
subjects:
  - kind: ServiceAccount
    name: nginx-sa
    namespace: learning
roleRef:
  name: developer
  kind: Role
  apiGroup: rbac.authorization.k8s.io

Service account nginx-sa can be used to list pods in namespace learning.

Generating Token

We have service account and roles in place, let’s generate token that we can use with API requests. Following command can be used to generate token,

kubectl create token nginx-sa -n learning

where nginx-sa is the service account name. This should generate token

eyJhbGciOiJSUzI1NiIsImtpZCI6InBPN092SHJHdnJONVdKZkthTk5CaE5ycTBKNjc2YmRHNXFWNndTMUc1UGMifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQ3MDYwOTc0LCJpYXQiOjE3NDcwNTczNzQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiNThmMmY4ZjgtMzc2My00ZjAxLWEwMGMtOTkwNWU3ZTY3NWY1Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJsZWFybmluZyIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJuZ2lueC1zYSIsInVpZCI6IjMxYTQxN2UyLTg5ZWQtNDUzOC04MWEzLTljOWJlOGZjNjdhMiJ9fSwibmJmIjoxNzQ3MDU3Mzc0LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bGVhcm5pbmc6bmdpbngtc2EifQ.jZ4rfoYdl1khI9NNxpLJYEH6ekuGHrhTYBTZXzSmDMQwxaru53crZ-CpCO_br4Wm9sOqi6Xd8bAq90FcTg3Y0VtTylKATTOQoBiMfnkHXQMhLcO4nPkPDE7XNNQi9tl-Dwr_BonGH3HCTmyp_chmWWdU64si8dl_3RXMFRZc0MR9i0RFc5445P4yDj0c9H5vptKM6_VaBGVsQ8JPEkhmvJ0SRslXiHmkRKvEE5fphRNt-NbLdljyrBmJZuWI29_tVbS7DQ0cmChLZOC5hSsjbrtUndLzxSRn7OKmNxTbXNatrxGgpw13qLYapPBFghyhAcNHFFiLACsGgO2GtB4e7g

And if decode it on jwt website, it gives following content.

{
  "aud": [
    "https://kubernetes.default.svc.cluster.local"
  ],
  "exp": 1747060974,
  "iat": 1747057374,
  "iss": "https://kubernetes.default.svc.cluster.local",
  "jti": "58f2f8f8-3763-4f01-a00c-9905e7e675f5",
  "kubernetes.io": {
    "namespace": "learning",
    "serviceaccount": {
      "name": "nginx-sa",
      "uid": "31a417e2-89ed-4538-81a3-9c9be8fc67a2"
    }
  },
  "nbf": 1747057374,
  "sub": "system:serviceaccount:learning:nginx-sa"
}

By default the expiration time of token is 1 hour. We can specify custom expiry using --duration flag as shown below,

 k create token nginx-sa -n learning --duration 2h

For convenience, let’s store this token in variable,

TOKEN=$(kubectl create token nginx-sa -n learning)

Using token

We have token with permission to list pods in namespace learning, let’s try and use it to list pods.

Before that we need to get server address, that we can get using following command,

KUBE_SERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"kube\")].cluster.server}")

where kube is kubernetes cluster name.

Let’s send request to kube server.

➤ curl -s -X GET $KUBE_SERVER/api/v1/namespaces/learning/pods -H "Authorization: Bearer $TOKEN" --insecure | jq ".items[0].metadata.name"

"secret-volume"

This give result secret-volume in the list of pods.