Authentication answered who; it granted nothing. Before it
answers, the apiserver checks RBAC: the group the token carried,
prefixed to okta:app-k8s-admins, must appear as a
ClusterRoleBinding subject.
Call sequence
{ "kind": "NodeList", "apiVersion": "v1", "items": [ { "metadata": { "name": "k3s-control" } } ] }
The binding RBAC evaluates
resolved identity okta:lab-admin@authlab.app okta:app-k8s-admins
RBAC binding — ClusterRoleBinding
cat okta-cluster-admins.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: okta-cluster-admins subjects: - kind: Group name: okta:app-k8s-admins apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
subjects[0].name
≡ "okta:" + token.groups[0] — the prefixed group the
apiserver resolved in step 2
Without this binding the identity authenticates and can do nothing — authN and authZ are separate gates.
Same OIDC mechanics as the workload track, a different consumer: who validates the token is the variable.