K8S TokenRequest API
Table of Contents
A common way for users to authenticate Kubernetes clusters is through an API that issues JSON Web Tokens (JWT). These tokens can be used to identify a Kubernetes user or service account and grant them access to the environment. While this is not a new feature, Kubernetes 1.24 adds a command that allows users to create these tokens more easily using the TokenRequest API.
-
We can use JWT to authenticate Kubernetes users and service accounts.
-
The new Kubernetes version makes it easier to create JWT tokens.
-
Creating JWT tokens using the TokenRequest API is easier than ever.
In the K8s version before 1.24, every time we would create a service account, a non-expiring secret token (Mountable secrets & Tokens) was created by default. However, from version 1.24 onwards, it was disbanded and no secret token is created by default when we create a service account. However, we can create it when need be. Now let us take a look at the service account token in a bit more depth.
Service Account Token
Kubernetes supports two types of tokens from version 1.22 onwards.
- Long-Lived Token
- Time Bound Token
Long-Lived Token
As its name indicates, a long-lived token is one that never expires. Hence, it is less secure and discouraged to use.
Creating Long-Lived Token
Before K8s version 1.24, whenever a service account was created, a secret object was also created that contains the secret token. These token would be long-lived token, which means it has no expiry. However, In Kubernetes version 1.24, it was disbanded due to security and scalability concerns.
Although not recommended, K8s allows us to create a long-lived token. It is achieved in two different steps:
- Create a service account
- Create a secret and specify the name of the service account as annotations within the metadata section.
kubect create serviceaccount my-sa
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: my-long-lived-secret
annotations:
kubernetes.io/service-account.name: my-sa
type: kubernetes.io/service-account-token
EOF
Time Bound Token
From version 1.22 onwards, Kubernetes introduced TokenRequest
API. A token generated through this API is a time-bound token that expires after a time. It applies to both — the default service account and the custom-defined service accounts.
Creating a time-bound token
We can create a time-bound token using the below command:
echo '{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest", "spec": {"audiences": ["https://kubernetes.default.svc.cluster.local"], "expirationSeconds": 3600}' \
| kubectl create -f- --raw /api/v1/namespaces/default/serviceaccounts/my-sa/token
echo '{
"apiVersion": "authentication.k8s.io/v1",
"kind": "TokenRequest",
"spec": {
"audiences": [
"https://kubernetes.default.svc.cluster.local"
],
"expirationSeconds": 3600
}
}' \
| kubectl create -f- --raw /api/v1/namespaces/default/serviceaccounts/my-sa/token
In the following sections, we will see a completed example using various methods, from creating a ServiceAccount to creating a Token, using Token, TokenReview
Create ServiceAccount
To create a ServiceAccount in Kubernetes, follow these steps:
- go
- yaml
- bash
1 |
|
Create Role
To create a Role in Kubernetes, follow these steps:
- go
- yaml
- bash
1 |
|
This will create the Role in the default
namespace.
That’s it! You have now created a Role in Kubernetes.
Create RoleBinding
In Kubernetes, RoleBinding is used to bind a role to a user, group, or service account in a given namespace. The RoleBinding grants the permissions defined in the role to the subject.
To create a RoleBinding, follow these steps:
- go
- yaml
- bash
1 |
|
This will create the RoleBinding in the default
namespace.
That’s it! You have now created a RoleBinding in Kubernetes.
Get a user bearer token
To successfully make HTTP requests to the Kubernetes API a bearer token must be included as an authorization header. Below is an example command one could run to get the bearer token for a user named admin-user in the namespace of kube-system. This same command could apply to any other user or namespace.
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
TokenRequest
The TokenRequest API allows you to request a token for a ServiceAccount in Kubernetes. To use TokenRequest, follow these steps:
- go
- yaml
- bash
1 |
|
This will create the TokenRequest and return the token for the specified ServiceAccount.
That’s it! You have now used TokenRequest to request a token for a ServiceAccount in Kubernetes.
Get Pods
Use the generated token to communicate with APIServer to obtain the Pods of default namespace:
- go
- bash
1 |
|
TokenReview
The TokenReview API allows you to validate a token for a ServiceAccount in Kubernetes. To use TokenReview, follow these steps:
- go
- bash
1 |
|
This will display the status of the TokenReview request, including whether the token is valid or not.
Complete code
- go
1 |
|
References
- https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/
- https://www.programmingwithwolfgang.com/use-the-tokenrequest-api-to-create-tokens-in-kubernetes/
- https://securitylabs.datadoghq.com/articles/kubernetes-tokenrequest-api/
- https://medium.com/@th3b3ginn3r/understanding-service-accounts-in-kubernetes-e9d2abe19df8
- https://jpweber.io/blog/a-look-at-tokenrequest-api/