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