Files
Florian-netz/docs/reference/authentik-setup.md
Claude f2578cedab feat(auth): Admin-Zugang über Authentik-Gruppe steuern
Statt manuell gesetzter DB-Rolle erhalten Mitglieder der Authentik-Gruppe
AUTHENTIK_ADMIN_GROUP (Default floriannetz-admins) beim SSO-Login automatisch
platform_admin; Nicht-Mitglieder werden abgewiesen. Erstes Seeding entfällt.

- auth.config.ts: Scope 'openid email profile groups' anfordern
- lib/auth/authentik.ts: reine Helfer extractGroups/isAdminGroupMember (+ 7 Unit-Tests)
- auth.ts: signIn wertet groups-Claim aus, upsert (idempotent) als platform_admin
  mit stabiler users.id für Audit/FKs
- env.ts/.env.example: AUTHENTIK_ADMIN_GROUP
- docs/reference/authentik-setup.md: Provider-/Gruppen-/Scope-Setup

Verifiziert offline: tsc OK; lint sauber; vitest 240 passed / 7 skipped.
Wehr-Konten bleiben lokale Accounts (kein Authentik).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 09:39:13 +02:00

2.5 KiB

Authentik-Integration & Admin-Zugang (FlorianNetz)

FlorianNetz nutzt Authentik als OIDC-Identitätsanbieter. Der Admin-Zugang (platform_admin) wird zentral über eine Authentik-Gruppe gesteuert — nicht über manuell gesetzte DB-Rollen.

Wie es funktioniert

  • Anmeldung über Authentik (OIDC). FlorianNetz fordert die Scopes openid email profile groups an.
  • Im signIn-Callback (src/auth.ts) wird der groups-Claim ausgewertet:
    • Mitglied der Admin-Gruppe (AUTHENTIK_ADMIN_GROUP, Standard floriannetz-admins) → wird (idempotent) als platform_admin in users angelegt/aktualisiert und eingeloggt.
    • Kein Mitglied → Login wird abgewiesen (return false).
  • Folge: Admins werden in Authentik verwaltet (Gruppenmitgliedschaft), nicht per seed-auth. Ein erstes manuelles Seeding entfällt (kein Henne-Ei-Problem).
  • Wehr-Konten (wehr_admin/wehr_read) bleiben lokale App-Konten (E-Mail+Passwort), die Wehr-Admins selbst anlegen — sie nutzen NICHT Authentik.

Einrichtung in Authentik

  1. Gruppe anlegen: z. B. floriannetz-admins; gewünschte Admin-Benutzer hinzufügen. (Muss exakt AUTHENTIK_ADMIN_GROUP entsprechen.)
  2. Provider anlegen: OAuth2/OpenID Provider
    • Redirect-URI: https://<APP_HOST>/api/auth/callback/authentik
    • Signing Key wie üblich; Client-Typ „Confidential".
  3. Scopes/Property-Mappings: dem Provider die Scope-Mappings openid, email, profile und das Gruppen-Mapping zuweisen, das den groups-Claim liefert (Authentik-Standard: „authentik default OAuth Mapping: OpenID 'groups'"). Ohne dieses Mapping enthält das Token keine groups und niemand erhält Admin-Zugang.
  4. Application anlegen und mit dem Provider verknüpfen; Slug muss zum AUTHENTIK_ISSUER passen (…/application/o/<slug>/).
  5. Client-ID/-Secret aus dem Provider übernehmen.

Umgebungsvariablen

AUTHENTIK_ISSUER=https://auth.example.at/application/o/floriannetz/
AUTHENTIK_CLIENT_ID=…
AUTHENTIK_CLIENT_SECRET=…
AUTHENTIK_ADMIN_GROUP=floriannetz-admins

Prüfen

  • Mitglied von floriannetz-admins meldet sich an → landet als Admin in /admin; in users existiert eine Zeile authTyp='authentik', rolle='platform_admin'.
  • Nicht-Mitglied meldet sich an → Login abgewiesen (zurück zu /login).
  • groups-Claim fehlt (Mapping nicht zugewiesen) → alle SSO-Logins abgewiesen (erwartetes Fail-safe-Verhalten: kein Claim ⇒ kein Admin).