From bb0bd4ca90ccbca66d05aa7c758dd4dbf75e0ae0 Mon Sep 17 00:00:00 2001 From: Nikholas Pcenicni <82239765+nikpcenicni@users.noreply.github.com> Date: Thu, 14 May 2026 19:15:47 -0400 Subject: [PATCH] Update OIDC configuration in Headlamp documentation and Talos config to use preferred_username claim instead of email. Added troubleshooting steps for "Unauthorized" errors related to OIDC token validation. --- clusters/noble/bootstrap/headlamp/README.md | 9 +++++++++ talos/talconfig.with-longhorn.yaml | 3 ++- talos/talconfig.yaml | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/clusters/noble/bootstrap/headlamp/README.md b/clusters/noble/bootstrap/headlamp/README.md index 47e6a03..916688c 100644 --- a/clusters/noble/bootstrap/headlamp/README.md +++ b/clusters/noble/bootstrap/headlamp/README.md @@ -29,6 +29,15 @@ kubectl -n headlamp create token headlamp --duration=48h Paste the printed JWT into Headlamp’s token field at **`https://headlamp.apps.noble.lab.pcenicni.dev`**. +## OIDC: still “Unauthorized” while pod logs look fine + +Headlamp logs like **“Request completed successfully”** for **`/plugins`** or static assets do **not** prove cluster API auth. After SSO, calls such as **`/clusters/main/version`** or **`…/selfsubjectrulesreviews`** use your **OIDC id_token**; **kube-apiserver** must validate it ([Kubernetes OIDC](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens)). + +1. **Confirm API server flags** match **`talos/talconfig.yaml`** (same **`oidc-issuer-url`** and **`oidc-client-id: headlamp`** as Secret **`headlamp-oidc`** / Authentik app **headlamp**). On Talos, apply regenerated control-plane machine configs and roll nodes so **`kube-apiserver`** actually picks up **`oidc-*`** extraArgs. +2. **Inspect the id_token** (browser devtools → Headlamp storage / network, or Authentik “Preview”): **`aud`** must include **`headlamp`**; for this repo’s **`oidc-noble-admins-clusterrolebinding.yaml`**, **`groups`** must list **`noble-admins`** exactly (if missing, see **`noble_authentik_headlamp_oidc_scopes`** and **`ansible/roles/noble_authentik/README.md`**). +3. **API server logs** often spell out the failure (**invalid bearer token**, wrong **audience**, unknown **issuer**). Check **`kube-apiserver`** logs on a control-plane node if steps 1–2 look correct. +4. **`oidc: email not verified`**: with **`oidc-username-claim: email`**, the API server rejects **`email_verified: false`**. Either set **`oidc-username-claim`** to a non-email claim (this repo uses **`preferred_username`** in **`talos/talconfig.yaml`**) or make Authentik issue **`email_verified: true`** for that user. + To use another duration (cluster `spec.serviceAccount` / admission limits may cap it): ```bash diff --git a/talos/talconfig.with-longhorn.yaml b/talos/talconfig.with-longhorn.yaml index 2f93693..bc668c9 100644 --- a/talos/talconfig.with-longhorn.yaml +++ b/talos/talconfig.with-longhorn.yaml @@ -103,5 +103,6 @@ patches: extraArgs: oidc-issuer-url: https://auth.apps.noble.lab.pcenicni.dev/application/o/headlamp/ oidc-client-id: headlamp - oidc-username-claim: email + # Not "email": kube-apiserver rejects tokens when email_verified is false; Authentik often emits that. + oidc-username-claim: preferred_username oidc-groups-claim: groups diff --git a/talos/talconfig.yaml b/talos/talconfig.yaml index 2f93693..bc668c9 100644 --- a/talos/talconfig.yaml +++ b/talos/talconfig.yaml @@ -103,5 +103,6 @@ patches: extraArgs: oidc-issuer-url: https://auth.apps.noble.lab.pcenicni.dev/application/o/headlamp/ oidc-client-id: headlamp - oidc-username-claim: email + # Not "email": kube-apiserver rejects tokens when email_verified is false; Authentik often emits that. + oidc-username-claim: preferred_username oidc-groups-claim: groups