gwoe-antragspruefer/docs/adr/0005-keycloak-sso-with-dev-bypass.md
Dotty Dotter f0f1c39911 Docs: Feld-Mapping-Tabelle pro Adapter + ADR 0005 + Auth-Tests
Adapter-Capabilities-Matrix (#93) erweitert um detailliertes Feld-
Mapping: Pro Adapter welches API-/HTML-/JSON-Feld zu welchem
Drucksache-Feld wird (title, datum, fraktionen, drucksache, link, typ)
mit konkreten Beispielwerten. 12 Adapter-Sektionen.

ADR 0005: Keycloak SSO mit Dev-Bypass — dokumentiert die Entscheidung
für Read/Write-Trennung (GET offen, POST mit JWT) und den Dev-Modus
(Auth deaktiviert wenn KEYCLOAK_URL nicht gesetzt).

Auth-Tests: 7 neue Tests für Token-Extraction, Auth-Enabled-Detection,
_pick_best_title (letztere skipped wenn slowapi nicht installiert).

201 passed, 5 skipped.
2026-04-10 16:29:28 +02:00

81 lines
2.8 KiB
Markdown

# 0005 — Keycloak SSO mit Dev-Bypass für Read/Write-Trennung
| | |
|---|---|
| **Status** | accepted |
| **Datum** | 2026-04-10 |
| **Refs** | Issue #43, Commit 7159240 + 303b30f, app/auth.py |
## Kontext
Die Webapp soll öffentlich durchsuchbar sein (Assessments lesen, PDFs
ansehen, Auswertungen), aber Analyse-Aktionen (Antrag bewerten, Programme
indexieren) nur authentifizierten Nutzern erlauben. Der User betreibt
bereits einen Keycloak-Server unter `sso.toppyr.de` mit Realm `collaboration`.
## Optionen
### Option A — Keycloak-only mit hartem 401
Alle POST-Endpoints erfordern JWT. Ohne Keycloak-Server läuft nichts.
**Vorteile:** Klar, sicher.
**Nachteile:** Lokale Entwicklung blockiert ohne Keycloak-Instanz.
### Option B — Dev-Bypass: Auth nur wenn ENV gesetzt
Wenn `KEYCLOAK_URL` leer ist → ALLE Endpoints offen (Dev-Modus).
Wenn gesetzt → POST-Endpoints erfordern JWT, GET bleibt offen.
**Vorteile:** Lokale Dev ohne Keycloak. Prod sofort sicher per ENV.
**Nachteile:** Versehentlich Prod ohne ENV = alles offen.
### Option C — API-Key statt Keycloak
Einfacher API-Key-Header für POST-Endpoints.
**Vorteile:** Zero-Dependency.
**Nachteile:** Kein SSO, kein User-Identity, keine Gruppen/Rollen.
## Entscheidung
**Option B.** Dev-Bypass ermöglicht reibungslose lokale Entwicklung und
Batch-Skripte (die keinen JWT haben). Prod-Absicherung über die drei
ENV-Vars in docker-compose.yml. Die Keycloak-Client-Registrierung in
`sso.toppyr.de` ist ein einmaliger manueller Schritt.
## Implementation
- `app/auth.py`: JWKS-Cache (1h TTL), `get_current_user` (optional),
`require_auth` (pflicht), `keycloak_login_url` (für Browser-Redirect)
- POST-Endpoints (`/analyze`, `/api/analyze-drucksache`,
`/api/programme/index`): `user: dict = Depends(require_auth)`
- GET-Endpoints: unverändert offen
- Frontend: `initAuth()` prüft `/api/auth/me`, steuert
"Jetzt prüfen"-Button (disabled + Tooltip wenn nicht eingeloggt)
und "Anmelden"-Button im Header
## Konsequenzen
### Positiv
- Read-Only für alle, Write nur mit Login — klare Trennung
- Batch-Skripte und auto-Re-Analyse im Container laufen im Dev-Modus
(KEYCLOAK_URL nicht gesetzt), keine Auth-Hürde für Maintenance
- Keycloak-Rollen über `realm_access.roles` im JWT verfügbar für
künftige Gruppen-Features (#94 Bookmarks/Kommentare)
### Negativ
- Dev-Modus ist unsicher — wenn jemand KEYCLOAK_URL in Prod vergisst
zu setzen, ist alles offen. Mitigation: Health-Endpoint oder
Startup-Warning wenn ENV fehlt.
- JWKS-Cache (1h) bedeutet: nach Key-Rotation dauert es bis zu 1h bis
alte Tokens abgelehnt werden. Für dieses Projekt akzeptabel.
### Folgen für andere ADRs
- #94 Bookmarks/Kommentare baut auf der User-Identity aus dem JWT auf
(`sub`, `email`, `realm_access.roles`).
- #95 Queuing könnte Auth-User priorisieren.