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

54 lines
2.5 KiB
Markdown

# 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).