---
# System prepended metadata

title: Does the call to TokenReview need a specific role?

---

# Does the call to TokenReview need a specific role?

I thought it was possible to use a token without any role to perform the [TokenReview](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#tokenreview-v1-authentication-k8s-io) call to the Kubernetes API server.

But no: for the TokenReview call, the service account associated to the token used to authenticate (i.e., the `Ahtorization: Bearer token` HTTP header) must have the role `system:auth-delegator`.

On the other side, the token within the TokenReview doesn't need to have any role attached.

First, let us create a token with no role attached:

```shell
token=$(kubectl create --raw /api/v1/namespaces/default/serviceaccounts/default/token -f- <<EOF | jq -r '.status.token'
{
  "apiVersion": "authentication.k8s.io/v1",
  "kind": "TokenRequest",
  "spec": {
    "audiences": ["https://kubernetes.default.svc.cluster.local"]
  }
}
EOF
)
```

Now, let us use the TokenReview API to check that same token:

```shell
curl -sS -X POST $(kubectl config view --minify --flatten -ojson | jq '.clusters[0].cluster.server' -r)/apis/authentication.k8s.io/v1/tokenreviews \
  --cacert <( kubectl config view --minify --flatten -ojson | jq '.clusters[0].cluster."certificate-authority-data"' -r | base64 -d) \
  -H "Authorization: Bearer $token" \
  -H "Content-Type: application/json" \
  -d@- <<EOF
 {
  "apiVersion": "authentication.k8s.io/v1",
  "kind": "TokenReview",
  "spec": {
    "token": "$token",
    "audiences": ["https://kubernetes.default.svc.cluster.local"]
  }
}
EOF
```

gives:

```yaml
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "tokenreviews.authentication.k8s.io is forbidden: User \"system:serviceaccount:default:default\" cannot create resource \"tokenreviews\" in API group \"authentication.k8s.io\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "group": "authentication.k8s.io",
    "kind": "tokenreviews"
  },
  "code": 403
}
```

To fix that:

```shell
kubectl apply -f- <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tokenreview
  namespace: default
subjects:
- kind: ServiceAccount
  namespace: default
  name: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
EOF
```

And now it works.

## Testing TokenRequest for PR 

```shell
kubectl run foo -n cert-manager --image=alpine/k8s:1.22.15 --restart=Never --overrides='{"spec":{"serviceAccountName": "cert-manager"}}' -q --rm -it -- bash

# And then, inside the container:
kubectl create --raw /api/v1/namespaces/sandbox/serviceaccounts/vault-issuer/token -f- <<EOF | jq -r '.status.token'
{
  "apiVersion": "authentication.k8s.io/v1",
  "kind": "TokenRequest",
  "spec": {
    "audiences": ["https://kubernetes.default.svc.cluster.local"],
    "expirationSeconds": 600
  }
}
EOF
```
