~/cred-visualizer

Resolve RBAC

Authentication answered who; it granted nothing. The apiserver now evaluates RBAC: does any binding name this identity? The group the token carried — prefixed to okta:app-k8s-admins — must literally appear as a ClusterRoleBinding subject for the human to be able to do anything at all.

what actually happens
  • The apiserver maps claims to identityemail + prefix → username, groups + prefix → group subjects.
  • RBAC matches the group — a ClusterRoleBinding names okta:app-k8s-admins and grants cluster-admin.
input · from step 2
authenticated as okta:lab-admin@authlab.app groups okta:app-k8s-admins resolved in step 2 →

Claim → cluster identity

The mapping the --oidc-* flags configured in step 2, applied. Hover for why.

email lab-admin@authlab.app okta:lab-admin@authlab.app
groups[0] app-k8s-admins okta:app-k8s-admins
resolved identity okta:lab-admin@authlab.app okta:app-k8s-admins

The payoff

$ kubectl auth can-i '*' '*'
yes

$ kubectl get nodes
NAME          STATUS   ROLES                  AGE
k3s-control   Ready    control-plane,master   112d

A human, a browser sign-in, MFA at the IdP, a short-lived signed assertion — and not a single credential file on disk.

The binding RBAC evaluates

authN resolved the identity; this is the authZ half.

RBAC binding — ClusterRoleBinding

kind: ClusterRoleBinding
metadata: { name: okta-cluster-admins }
subjects:
- kind: Group
name: okta:app-k8s-admins
"okta:" + token.groups[0] — the prefixed group the apiserver resolved in step 2
roleRef:
kind: ClusterRole · name: cluster-admin

Without this binding the identity authenticates and can do nothing — authN and authZ are separate gates.

End of track

Same OIDC mechanics as the workload track — different consumer, different failure modes, same lesson: who validates the token is the variable.

Back to the track picker or revisit the workload track.