Issue
This question concerns kubernetes v1.24 and up
So I can create tokens for service accounts with
kubectl create token myserviceaccount
The created token works and serves the purpose, but what I find confusing is that when I kubectl get sa
SECRETS field of myserviceaccount is still 0. The token doesn't appear in kubectl get secrets
either.
I've also seen that I can pass --bound-object-kind
and --bound-object-name
to kubectl create token
but this doesn't seem to do anything (visible) either...
Is there a way to see created token? And what is the purpose of --bound.. flags?
Solution
Thanks to the docs link I've stumbled upon today (I don't know how I've missed it when asking the question because I've spent quite some time browsing through the docs...) I found the information I was looking for. I feel like providing this answer because I find v1d3rm3's answer incomplete and not fully accurate.
The kubernetes docs confirm v1d3rm3's claim (which is btw the key to answering my question):
The created token is a signed JSON Web Token (JWT).
Since the token is JWT token the server can verify if it has signed it, hence no need to store it. JWTs expiry time is set not because the token is not associated with an object (it actually is, as we'll see below) but because the server has no way of invalidating a token (it would actually need to keep track of invalidated tokens because tokens aren't stored anywhere and any token with good signature is valid). To reduce the damage if a token gets stolen there is an expiry time.
Signed JWT token contains all the necessary information inside of it.
The decoded token (created with kubectl create token test-sa
where test-sa is service account name) looks like this:
{
"aud": [
"https://kubernetes.default.svc.cluster.local"
],
"exp": 1666712616,
"iat": 1666709016,
"iss": "https://kubernetes.default.svc.cluster.local",
"kubernetes.io": {
"namespace": "default",
"serviceaccount": {
"name": "test-sa",
"uid": "dccf5808-b29b-49da-84bd-9b57f4efdc0b"
}
},
"nbf": 1666709016,
"sub": "system:serviceaccount:default:test-sa"
}
Contrary to v1d3rm3 answer, This token IS associated with a service account automatically, as the kubernets docs link confirm and as we can also see from the token content above.
Suppose I have a secret I want to bind my token to (for example kubectl create token test-sa --bound-kind Secret --bound-name my-secret
where test-sa is service account name and my-secret is the secret I'm binding token to), the decoded token will look like this:
{
"aud": [
"https://kubernetes.default.svc.cluster.local"
],
"exp": 1666712848,
"iat": 1666709248,
"iss": "https://kubernetes.default.svc.cluster.local",
"kubernetes.io": {
"namespace": "default",
"secret": {
"name": "my-secret",
"uid": "2a44872f-1c1c-4f18-8214-884db5f351f2"
},
"serviceaccount": {
"name": "test-sa",
"uid": "dccf5808-b29b-49da-84bd-9b57f4efdc0b"
}
},
"nbf": 1666709248,
"sub": "system:serviceaccount:default:test-sa"
}
Notice that binding happens inside the token, under kubernetes.io key and if you describe my-secret you will still not see the token. So the --bound-... flags weren't visibly (from secret object) doing anything because binding happens inside the token itself...
Instead of decoding JWT tokens, we can also see details in TokenRequest object with
kubectl create token test-sa -o yaml
Answered By - golder3 Answer Checked By - Candace Johnson (WPSolving Volunteer)