Validate at the apiserver

kubectl presents the id_token to the kube-apiserver. Every failure on the workload track was token-side; here the token is flawless, and whether it gets 401 or authenticates depends entirely on the apiserver's own config.

Call sequence

human browser kubectl kubelogin plugin okta dev-12345678.okta.com kube-apiserver k3s-control:6443 step 1 GET /authorize sign in · MFA 302 → ?code POST /token id_token step 2 1 GET /api/v1/nodes 2 GET discovery 3 GET JWKS
  • kubectl get nodes: kubectl sends the id_token as a Bearer header on every request
  • the cluster host is illustrative; the cluster side of this track is not a capture
  • the JWT payload (purple) is shortened here for brevity; the header and signature are complete
  • only with --oidc-issuer-url set: the apiserver reads Okta's discovery document
  • with no --oidc-* flags there is no OIDC authenticator, and this flawless token gets 401
  • the key matching the token's kid verifies the signature; then iss and aud must match the flags
  • authenticated as okta:lab-admin@authlab.app, group okta:app-k8s-admins; nothing granted yet
request GET
curl https://k3s-control:6443/api/v1/nodes \
    -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ing5S3FMbUE0dVZyUDBlVDJzQm42Q3dEeUVmR2hKaUtsTW5PcFFyU3RVdlciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2Rldi0xMjM0NTY3OC5va3RhLmNvbSIsImF1ZCI6IjBvYThxMmxtdjNSdFl3SGNLNWQ3Iiwic3ViIjoiMDB1NWZqOXF4MlRuV2JWckE1ZDciLCJlbWFpbCI6ImxhYi1hZG1pbkBhdXRobGFiLmFwcCIsImdyb3VwcyI6WyJhcHAtazhzLWFkbWlucyJdLCJhbXIiOlsi….anonymized-signature-not-valid-for-cryptographic-use'
request GET
curl https://dev-12345678.okta.com/.well-known/openid-configuration
request GET
curl https://dev-12345678.okta.com/oauth2/v1/keys
apiserver config same token, two configs — switch to compare

The validator

cat /etc/rancher/k3s/config.yaml
cat: /etc/rancher/k3s/config.yaml: No such file or directory
# no --oidc-* flags — no OIDC authenticator registered
# the apiserver has never heard of this issuer
cat /etc/rancher/k3s/config.yaml
kube-apiserver-arg:
  - "oidc-issuer-url=https://dev-12345678.okta.com"  # ≡ token.iss (JWKS fetched here)
  - "oidc-client-id=0oa8q2lmv3RtYwHcK5d7"  # ≡ token.aud
  - "oidc-username-claim=email"  # token.email → username
  - "oidc-username-prefix=okta:"  # → okta:lab-admin@authlab.app
  - "oidc-groups-claim=groups"  # token.groups → groups
  - "oidc-groups-prefix=okta:"  # → okta:app-k8s-admins

What the apiserver checks

iss
token.iss ∅ not configured --oidc-issuer-url
aud
token.aud ∅ not configured --oidc-client-id
groups
token.groups[] ∅ not configured --oidc-groups-claim + okta: prefix

Nothing to check against — the authenticator that would read these claims was never registered. The token is not even parsed.

Every row now has a target. Signature verified against the issuer's JWKS, claims mapped to a cluster identity.

HTTP/1.1 401 Unauthorized same token · every claim valid · no validator configured
authenticated as okta:lab-admin@authlab.app · groups: okta:app-k8s-admins