Permissions for a Pod in kubernetes are managed via Service Accounts, and these come with a JWT issued by the cluster. If the Pods need to authenticate to an external service, it would be reasonable to use this JWT, so let’s see how to get it and verify it.
This JWT can also be used to call the Kubernetes API, as described very well in this article. I definitely recommend reading that, as I won’t be going into so much detail on the ServiceAccount and RBAC part.
Setup
Make sure you have a cluster (e.g. minikube) setup, and kubectl authenticated.
Create a new namespace and service account:
Start an image in the namespace with the service account and open bash into it. Then install curl and jq:
Get the token in a Pod
Now that we have the shell into a container, let’s find the token. Based on the docs all we have to do is:
This is a great start, as it shows that the /var/run/secrets/kubernetes.io/serviceaccount/token file holds the JWT token, and the /var/run/secrets/kubernetes.io/serviceaccount/ca.crt holds the ca cert used by the Kubernetes API server.
Getting the certificate to verify the JWT
Unfortunately the ca.crt. file is not the certificate used for the JWT. To get that, we need to hit the /.well-known/openid-configuration endpoint. Based on the previous example:
jq is used only to pretty-print the json. This will return something like:
The jwks_uri holds the JSON Web Key Sets. Calling that URL with the same bearer token:
When calling the URLs make sure not to use double / (e.g. https://kubernetes.default.svc//.well-known/openid-configuration) as that can lead to permission errors.
JWT content
The JWT has a payload, similar to:
This contains both the namespace and the service account names, which can be used for authorization.
Code example
Live demo (tends to timeout due to imports, so you might need to run it multiple times)