From 6f442a14a32100f248b6990972e0500c270770c3 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 20 Oct 2026 20:41:36 -0700 Subject: [PATCH] fix(observability): repair Grafana Authentik OAuth2 relying-party login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Authentik SSO button returned "Server Error" (500): the grafana provider had a NULL authorization_flow and the authorize view crashed building a None flow planner. After that, the login failed with "InternalError" — no email claim reached Grafana, so it fell back to GET /emails, which authentik 404s. Unit env: request authentik real scopes (openid email profile, not the GitLab user:email that crashes the authorize view); standard userinfo API_URL with no ?api=1 (Grafana v13 turns ?api=1 into a /emails 403); email/sub/preferred_username attribute paths; ALLOW_SIGN_UP=true since the Anubis->Authentik guard fronts the callback. scripts/authentik-grafana-sso-fix.sh idempotently re-applies the two IdP-side causes (NULL authorization_flow; grafana-email-scope returning a bare string instead of {"email":..}). Verified end to end: RP login lands on / and /api/user answers 200 with the real email, user provisioned as Viewer. --- dankclaw/observability/quadlet/grafana.container | 11 ++++++----- scripts/authentik-grafana-sso-fix.sh | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dankclaw/observability/quadlet/grafana.container b/dankclaw/observability/quadlet/grafana.container index 8eefb6f..112b724 100644 --- a/dankclaw/observability/quadlet/grafana.container +++ b/dankclaw/observability/quadlet/grafana.container @@ -47,11 +47,12 @@ Environment=GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=${GRAFANA_OAUTH_CLIENT_SECRET} # client_id query parameter — /application/o//authorize/ does not exist. Environment=GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://auth.franksdank.cloud/application/o/authorize/ Environment=GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://auth.franksdank.cloud/application/o/token/ -# Read claims from the signed ID token. Grafana v13 always appends /emails to -# API_URL and GETs it as a userinfo endpoint (authentik has no such path and -# 404s it, failing the login). USE_ID_TOKEN makes Grafana take sub/email/name -# from the id_token, which authentik fills from the openid/email/profile scopes. -Environment=GF_AUTH_GENERIC_OAUTH_USE_ID_TOKEN=true +# Standard OIDC userinfo. Grafana v13 fetches /emails for the address +# ONLY when the token carries no `email` claim (authentik has no /emails path and +# 404s it, failing the login) — so the claim must actually be there: the fix is +# the grafana-email-scope mapping (see scripts/authentik-grafana-sso-fix.sh), +# not a Grafana flag. Do NOT append ?api=1 to this URL: Grafana then GETs +# <...>/userinfo/?api=1/emails, a 403. Environment=GF_AUTH_GENERIC_OAUTH_API_URL=https://auth.franksdank.cloud/application/o/userinfo/ # authentik's scopes are openid/email/profile. `user:email` (a GitLab-ism) is # not a known scope here; requesting it makes the authorize view crash. diff --git a/scripts/authentik-grafana-sso-fix.sh b/scripts/authentik-grafana-sso-fix.sh index 19077c7..d31ce8b 100755 --- a/scripts/authentik-grafana-sso-fix.sh +++ b/scripts/authentik-grafana-sso-fix.sh @@ -29,8 +29,8 @@ # facts and the symptom returns verbatim. Re-run this after any such rebuild. # Every step is idempotent. # -# Grafana's own half — SCOPES="openid email profile", USE_ID_TOKEN=true, no -# `?api=1` on the API URL, ALLOW_SIGN_UP=true — lives in +# Grafana's own half — SCOPES="openid email profile", a standard userinfo API_URL +# with no `?api=1`, and ALLOW_SIGN_UP=true — lives in # dankclaw/observability/quadlet/grafana.container and deploys normally. # # Usage: authentik-grafana-sso-fix.sh (override host: AUTHENTIK_HOST=…)