docs: correct Grafana Authentik SSO facts

The vault claimed the fork property-mapping evaluator was broken and userinfo
returned only sub, so email could never reach Grafana (outcome unverified). That
was a misdiagnosis: the real causes were the NULL authorization_flow (the
NoneType.slug crash) and the email scope mapping returning a bare string rather
than a dict. Record the four verified causes and fixes, point to the repair
script and the new landing spec, and drop the unverified caveat.
This commit is contained in:
Frank committed 2026-10-20 20:40:15 -07:00
1 parent 200039d589
commit afe72781bc
2 files changed
+50 -32

No files matched your search

@@ -81,7 +81,7 @@ Two provisioning rules, each verified live by an outage:
appears. Create the Application with `provider_id` set (the UI does this
automatically; raw API/ORM drives must do it explicitly).
## OAuth2 relying-party quirks (this fork, verified live 2026-08-31)
## OAuth2 relying-party quirks (this fork; corrected live 2026-10-20)
The Grafana RP provider (`grafana`, pk 9, confidential client) was created and
verified end-to-end via `ak shell` ORM drives. This fork's OAuth2 provider
@@ -100,23 +100,32 @@ implementation diverges from upstream in ways that bit us; all verified live:
- **Provider resolution is by `client_id` query param** on the global
`/application/o/authorize/` route; per-slug authorize paths do not exist in
this build. Token/userinfo live at `/application/o/token/` and
`/application/o/userinfo/?api=1`.
- **Property-mapping evaluator is broken → userinfo returns `sub` only.**
`PropertyMappingEvaluator.evaluate(*args, **kwargs)` forwards kwargs to
`BaseEvaluator.evaluate(expression_source)`, so the first context kwarg
becomes the *expression source* instead of the context; every call raises a
swallowed `PropertyMappingExpressionException` and the claim is skipped.
Scope-grant filtering has the same class of bug: `ScopeMapping` has no
provider FK (linkage lives in the `ProviderPropertyMapping` through model)
so `filter(provider=...)` always yields an empty queryset and tokens asked
to carry scopes get zero. Net effect: userinfo/introspection answers with
`{sub}` only — email/groups/entitlements claims cannot be delivered by this
build until the evaluator is patched or upgraded. Clients consuming this
provider must key identity off `sub`.
- Scope mappings for this provider exist — `grafana-email-scope` and
`grafana-profile-scope` are both rows in `authentik_core_propertymapping`
(read-only `SELECT`, 2026-10-18) — and will start emitting claims the moment
the evaluator bug is fixed; no config change is needed then.
`/application/o/userinfo/` — do **not** append `?api=1` to a Grafana API URL.
- **NULL `authorization_flow` → authorize 500, `AttributeError: 'NoneType'
object has no attribute 'slug'`.** A provider created via raw `ak shell`
`create()` leaves `authorization_flow` unset; the authorize view then crashes
building the flow planner (`flows/planner.py`) and returns "Server Error —
Powered by authentik" before any claim is built. This was previously
mis-attributed to a broken evaluator; the crash is the missing flow. Fix: set
`authorization_flow = default-provider-authorization-implicit-consent` (the
flow every other provider in this instance already uses).
- **A scope mapping that returns a non-dict emits no claim.** authentik merges a
granted scope mapping's evaluated result into the token **as a mapping**: a
dict contributes its keys as claims; a bare string is keyed under the
mapping's NAME, so nothing usable appears. `grafana-email-scope` returned the
bare string `user.email`, so no `email` claim landed — the evaluator was
never broken (the dict-valued `grafana-profile-scope` mapping has always
delivered, and the stock OpenID mappings return dicts). Fix:
`return {"email": user.email, "email_verified": True}`. With no email, Grafana
v13 falls back to GET `<api_url>/emails`; authentik 404s it → "Login failed:
InternalError".
- **Claims ride in the id_token.** `include_claims_in_id_token` is on for this
provider and Grafana reads identity from it (`USE_ID_TOKEN=true`).
- **Net (2026-10-20):** the evaluator is fine; email/profile claims reach RP
clients. Both IdP fixes are idempotent in `scripts/authentik-grafana-sso-fix.sh`
(re-run after an ak-shell re-creation of the provider or a blueprint import,
which revert them). Grafana's half + the verified outcome (Viewer,
`login = <sub hex>`, email present) are in [[Grafana]].
## LDAP provider objects (provisioned via `ak shell` ORM)