authentik: Passkey-only Login für Home Assistant und NetBird #115

Merged
k.renner merged 2 commits from feat/authentik-passkey-stepup into master 2026-07-07 07:14:15 +00:00
Owner

Was

Neuer Authorization-Flow passkey-stepup-authorization (Flow + WebAuthn-only Authenticator-Validation-Stage + Binding) als zweiter Blueprint-Key passkey-stepup.yaml in der bestehenden Blueprints-ConfigMap. Die OAuth2-Provider Homeassistant und Provider for Netbird werden per Blueprint auf diesen Flow umgehängt.

Warum Authorization-Flow (nicht Authentication-Flow)

Der Authorization-Flow läuft bei jedem interaktiven Authorize des Providers — eine bestehende Passwort-SSO-Session aus einer anderen App kommt damit nicht ohne Passkey in HA/NetBird. Ein Authentication-Flow würde nur greifen, wenn noch gar keine Session existiert.

Live-Verifikation (2026-07-07, read-only via CNPG-psql)

  • WebAuthn-Devices enrolled: akadmin (2), k.renner (4), s.renner (4), i.birzer (1) — g.renner (0)
  • App-Zugriff: homeassistant → Gruppe Homeassistant (g.renner, k.renner, s.renner); netbird → Infrastructure Admins (k.renner), Netbird Users (s.renner)
  • Beide Provider hingen auf default-provider-authorization-implicit-consent (0 Stages)
  • Stage default-authenticator-webauthn-setup existiert (wird für Inline-Enrollment referenziert)

Entscheidungen

  • not_configured_action: configure statt deny: g.renner hat HA-Zugriff aber keinen Passkey — deny wäre ein Hard-Lockout. configure erzwingt beim ersten Login das Enrollment eines Passkeys und validiert ihn danach. Passkey-only bleibt gewahrt.
  • last_auth_threshold: hours=8: kein Doppel-Touch unmittelbar nach Passkey-Login; NetBirds Dashboard-Silent-Reauth (/silent-auth, prompt=none) schlägt innerhalb des Fensters nicht fehl. Auf seconds=0 stellen, wenn jeder Authorize einen Touch erfordern soll.
  • Die beiden Provider waren bisher UI-managed. Da der Blueprint-Import den vollen Serializer validiert, spiegeln invalidation_flow, client_type und redirect_uris den Live-Stand — ab Merge besitzt Git diese Felder, UI-Änderungen daran werden beim nächsten Apply-Zyklus zurückgesetzt.

Rollback

git revert genügt — der Blueprint hängt die Provider beim nächsten Apply wieder auf den Default-Flow. Keine Datenmigration.

Validierung nach Merge

  1. Worker-Log: Blueprint Passkey step-up authorization (homelab) applied ohne Fehler
  2. NetBird-Login (k.renner): Passkey-Prompt erscheint, Login klappt
  3. HA-Login (k.renner): dito
  4. Danach g.renner-Login auf HA beobachten: Enrollment-Flow statt Lockout

🤖 Generated with Claude Code

## Was Neuer Authorization-Flow **`passkey-stepup-authorization`** (Flow + WebAuthn-only Authenticator-Validation-Stage + Binding) als zweiter Blueprint-Key `passkey-stepup.yaml` in der bestehenden Blueprints-ConfigMap. Die OAuth2-Provider **Homeassistant** und **Provider for Netbird** werden per Blueprint auf diesen Flow umgehängt. ## Warum Authorization-Flow (nicht Authentication-Flow) Der Authorization-Flow läuft bei **jedem** interaktiven Authorize des Providers — eine bestehende Passwort-SSO-Session aus einer anderen App kommt damit nicht ohne Passkey in HA/NetBird. Ein Authentication-Flow würde nur greifen, wenn noch gar keine Session existiert. ## Live-Verifikation (2026-07-07, read-only via CNPG-psql) - WebAuthn-Devices enrolled: akadmin (2), k.renner (4), s.renner (4), i.birzer (1) — **g.renner (0)** - App-Zugriff: `homeassistant` → Gruppe *Homeassistant* (g.renner, k.renner, s.renner); `netbird` → *Infrastructure Admins* (k.renner), *Netbird Users* (s.renner) - Beide Provider hingen auf `default-provider-authorization-implicit-consent` (0 Stages) - Stage `default-authenticator-webauthn-setup` existiert (wird für Inline-Enrollment referenziert) ## Entscheidungen - **`not_configured_action: configure`** statt `deny`: g.renner hat HA-Zugriff aber keinen Passkey — `deny` wäre ein Hard-Lockout. `configure` erzwingt beim ersten Login das Enrollment eines Passkeys und validiert ihn danach. Passkey-only bleibt gewahrt. - **`last_auth_threshold: hours=8`**: kein Doppel-Touch unmittelbar nach Passkey-Login; NetBirds Dashboard-Silent-Reauth (`/silent-auth`, prompt=none) schlägt innerhalb des Fensters nicht fehl. Auf `seconds=0` stellen, wenn jeder Authorize einen Touch erfordern soll. - Die beiden Provider waren bisher UI-managed. Da der Blueprint-Import den vollen Serializer validiert, spiegeln `invalidation_flow`, `client_type` und `redirect_uris` den Live-Stand — **ab Merge besitzt Git diese Felder**, UI-Änderungen daran werden beim nächsten Apply-Zyklus zurückgesetzt. ## Rollback `git revert` genügt — der Blueprint hängt die Provider beim nächsten Apply wieder auf den Default-Flow. Keine Datenmigration. ## Validierung nach Merge 1. Worker-Log: Blueprint `Passkey step-up authorization (homelab)` applied ohne Fehler 2. NetBird-Login (k.renner): Passkey-Prompt erscheint, Login klappt 3. HA-Login (k.renner): dito 4. Danach g.renner-Login auf HA beobachten: Enrollment-Flow statt Lockout 🤖 Generated with [Claude Code](https://claude.com/claude-code)
k.renner added 1 commit 2026-07-07 06:57:27 +00:00
Neuer Authorization-Flow `passkey-stepup-authorization` mit einer
WebAuthn-only Authenticator-Validation-Stage, per Blueprint auf die
OAuth2-Provider von Home Assistant und NetBird gebunden. Login in
diese Apps erfordert damit einen Passkey — auch mit bestehender
SSO-Session aus einem Passwort-Login.

- not_configured_action: configure — g.renner (HA-Zugriff, kein
  Passkey enrolled) wird beim ersten Login zur Enrollment geführt
  statt ausgesperrt
- last_auth_threshold hours=8 — kein Doppel-Touch direkt nach
  Passkey-Login; NetBirds /silent-auth (prompt=none) bleibt innerhalb
  des Fensters funktionsfähig
- Provider-Pflichtfelder (invalidation_flow, redirect_uris,
  client_type) spiegeln den Live-Stand vom 2026-07-07; ab jetzt
  besitzt Git diese Felder

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
k.renner added 1 commit 2026-07-07 07:09:35 +00:00
Ergänzt den Step-up um den eigentlichen Kern: einen passwortlosen
Authentication-Flow (Identification ohne Password-Stage → WebAuthn →
Login), per authentication_flow an beide Provider gebunden. Frische
Logins in HA/NetBird zeigen damit kein Passwortfeld mehr; der
Authentik-eigene Login (Default-Brand-Flow) bleibt unverändert.

Sicherheitsdetail: die Validation-Stage im Authentication-Flow ist
eine SEPARATE Stage mit not_configured_action: deny — `configure`
wäre hier eine Account-Übernahme (User ist nur identifiziert, nicht
authentifiziert). Inline-Enrollment bleibt exklusiv im Authorization-
Step-up mit require_authenticated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
k.renner merged commit 1d5fdce85d into master 2026-07-07 07:14:15 +00:00
Sign in to join this conversation.