Problem Statement:
While using Kubernetes authentication method to authenticate with Vault, errors are often noticed related to JWT tokens. Identifying the root cause and validating the JWT token can be a time-consuming process. Additionally, decoding the JWT token sometimes fails to reveal its expiration time, and there have been instances where JWT tokens have been flagged with an Invalid Signature
when decoding.
Solution:
To verify the validity of a JWT token, create a TokenReview
resource by creating a file token.yaml
and include the JWT token formatted as follows.
kind: TokenReview
apiVersion: authentication.k8s.io/v1
metadata:
name: test
spec:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkdReVpnWXFsc0lxVjFfM25xbkRHQ2tkZlVHUGtqWnBfbFlFVHBIbFIzYW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5ODI3MDEwLCJpYXQiOjE2ODk4MjY0MTAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNhLXRlc3QiLCJ1aWQiOiJhZjQyZWY1Yy0xOTUyLTQ5OGEtOTEyNy0zYzZhOTc1MTU0OWQifX0sIm5iZiI6MTY4OTgyNjQxMCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2EtdGVzdCJ9.mWwnxow3kWJwiBpOkUOB8rQ9W3XapgJ0V3bT5Mfrr6XxAFYIIu_yNvxsIm4qwDjaRt9BKGUTJT_K3Rk7zDdDMj-tREA71I83w5yOAb8-KgdyvTXOF462RgTTMyK4q6aDVeM8dfg3kPOU9cQB5NanV9hh99yJ2tuRzbCMehwyQBKmpFj9IZX-4s6GTtjzwr16LRAIwJIRM2HUYhzZIqRNzJyyNJcs9N0oXCha8ubWrMnEEeooKqeRkkwiUEg0cKxLLBdYOG6_zVSNFPA6Yn4ubkmcvnihRwud8w8I_iOdmkX_G18EBZtWw04zshkqhDvOlAHV_0SFE0nNWnGaM2rwPw
Once the file has been created, validate the request as indicated below.
$ kubectl apply -o yaml -f token.yaml
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"authentication.k8s.io/v1","kind":"TokenReview","metadata":{"annotations":{},"name":"test"},"spec":{"token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IkdReVpnWXFsc0lxVjFfM25xbkRHQ2tkZlVHUGtqWnBfbFlFVHBIbFIzYW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5ODI3MDEwLCJpYXQiOjE2ODk4MjY0MTAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNhLXRlc3QiLCJ1aWQiOiJhZjQyZWY1Yy0xOTUyLTQ5OGEtOTEyNy0zYzZhOTc1MTU0OWQifX0sIm5iZiI6MTY4OTgyNjQxMCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2EtdGVzdCJ9.mWwnxow3kWJwiBpOkUOB8rQ9W3XapgJ0V3bT5Mfrr6XxAFYIIu_yNvxsIm4qwDjaRt9BKGUTJT_K3Rk7zDdDMj-tREA71I83w5yOAb8-KgdyvTXOF462RgTTMyK4q6aDVeM8dfg3kPOU9cQB5NanV9hh99yJ2tuRzbCMehwyQBKmpFj9IZX-4s6GTtjzwr16LRAIwJIRM2HUYhzZIqRNzJyyNJcs9N0oXCha8ubWrMnEEeooKqeRkkwiUEg0cKxLLBdYOG6_zVSNFPA6Yn4ubkmcvnihRwud8w8I_iOdmkX_G18EBZtWw04zshkqhDvOlAHV_0SFE0nNWnGaM2rwPw"}}
creationTimestamp: null
name: test
spec:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkdReVpnWXFsc0lxVjFfM25xbkRHQ2tkZlVHUGtqWnBfbFlFVHBIbFIzYW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5ODI3MDEwLCJpYXQiOjE2ODk4MjY0MTAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNhLXRlc3QiLCJ1aWQiOiJhZjQyZWY1Yy0xOTUyLTQ5OGEtOTEyNy0zYzZhOTc1MTU0OWQifX0sIm5iZiI6MTY4OTgyNjQxMCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2EtdGVzdCJ9.mWwnxow3kWJwiBpOkUOB8rQ9W3XapgJ0V3bT5Mfrr6XxAFYIIu_yNvxsIm4qwDjaRt9BKGUTJT_K3Rk7zDdDMj-tREA71I83w5yOAb8-KgdyvTXOF462RgTTMyK4q6aDVeM8dfg3kPOU9cQB5NanV9hh99yJ2tuRzbCMehwyQBKmpFj9IZX-4s6GTtjzwr16LRAIwJIRM2HUYhzZIqRNzJyyNJcs9N0oXCha8ubWrMnEEeooKqeRkkwiUEg0cKxLLBdYOG6_zVSNFPA6Yn4ubkmcvnihRwud8w8I_iOdmkX_G18EBZtWw04zshkqhDvOlAHV_0SFE0nNWnGaM2rwPw
status:
error: '[invalid bearer token, service account token has expired]'
user: {}
An expired JWT token results in an invalid bearer token
error within the status stanza.
An invalid JWT token results in a different error invalid bearer token, square/go-jose: error in cryptographic primitive
.
A valid token returns the following.
$ kubectl apply -o yaml -f token.yaml
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"authentication.k8s.io/v1","kind":"TokenReview","metadata":{"annotations":{},"name":"test"},"spec":{"token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IkdReVpnWXFsc0lxVjFfM25xbkRHQ2tkZlVHUGtqWnBfbFlFVHBIbFIzYW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5ODI3MDEwLCJpYXQiOjE2ODk4MjY0MTAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNhLXRlc3QiLCJ1aWQiOiJhZjQyZWY1Yy0xOTUyLTQ5OGEtOTEyNy0zYzZhOTc1MTU0OWQifX0sIm5iZiI6MTY4OTgyNjQxMCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2EtdGVzdCJ9.mWwnxow3kWJwiBpOkUOB8rQ9W3XapgJ0V3bT5Mfrr6XxAFYIIu_yNvxsIm4qwDjaRt9BKGUTJT_K3Rk7zDdDMj-tREA71I83w5yOAb8-KgdyvTXOF462RgTTMyK4q6aDVeM8dfg3kPOU9cQB5NanV9hh99yJ2tuRzbCMehwyQBKmpFj9IZX-4s6GTtjzwr16LRAIwJIRM2HUYhzZIqRNzJyyNJcs9N0oXCha8ubWrMnEEeooKqeRkkwiUEg0cKxLLBdYOG6_zVSNFPA6Yn4ubkmcvnihRwud8w8I_iOdmkX_G18EBZtWw04zshkqhDvOlAHV_0SFE0nNWnGaM2rwPw"}}
creationTimestamp: null
name: test
spec:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkdReVpnWXFsc0lxVjFfM25xbkRHQ2tkZlVHUGtqWnBfbFlFVHBIbFIzYW8ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5ODI3MDEwLCJpYXQiOjE2ODk4MjY0MTAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNhLXRlc3QiLCJ1aWQiOiJhZjQyZWY1Yy0xOTUyLTQ5OGEtOTEyNy0zYzZhOTc1MTU0OWQifX0sIm5iZiI6MTY4OTgyNjQxMCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2EtdGVzdCJ9.mWwnxow3kWJwiBpOkUOB8rQ9W3XapgJ0V3bT5Mfrr6XxAFYIIu_yNvxsIm4qwDjaRt9BKGUTJT_K3Rk7zDdDMj-tREA71I83w5yOAb8-KgdyvTXOF462RgTTMyK4q6aDVeM8dfg3kPOU9cQB5NanV9hh99yJ2tuRzbCMehwyQBKmpFj9IZX-4s6GTtjzwr16LRAIwJIRM2HUYhzZIqRNzJyyNJcs9N0oXCha8ubWrMnEEeooKqeRkkwiUEg0cKxLLBdYOG6_zVSNFPA6Yn4ubkmcvnihRwud8w8I_iOdmkX_G18EBZtWw04zshkqhDvOlAHV_0SFE0nNWnGaM2rwPw
status:
audiences:
- https://kubernetes.default.svc.cluster.local
authenticated: true
user:
groups:
- system:serviceaccounts
- system:serviceaccounts:default
- system:authenticated
uid: af42ef5c-1952-498a-9127-3c6a9751549d
username: system:serviceaccount:default:sa-test
A valid JWT token returns authenticated: true
in the status stanza, which indicates successful authentication and ensures validity of the JWT token.
References: