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.
2.8 KiB
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.rolesim 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.