docs(Phase 19): ADR 0012 DEBUG_AUTH_TOKEN-Bypass

Dokumentiert das gesamte Bypass-Pattern mit Optionen-Vergleich
(Service-Account vs. langes JWT vs. ENV-Secret), Härtungsstrategie
(prod-compose ignoriert ENV, Audit-Logging, wöchentliche Rotation)
und Folgen für ADR 0005 (Keycloak Dev-Bypass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dotty Dotter 2026-05-06 23:53:55 +02:00
parent 53f8d2cad5
commit c06de002ca
3 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,109 @@
# 0012 — DEBUG_AUTH_TOKEN-Bypass für Diagnose-Sessions
| | |
|---|---|
| **Status** | accepted |
| **Datum** | 2026-05-06 |
| **Refs** | commit `f8cfa42` (Bypass), `d853101` (Logging+Rotation), MEMORY/reference_debug_auth_bypass.md |
## Kontext
Bei UI-Bugs auf `gwoe-dev.toppyr.de` brauche ich (oder ein Diagnose-
Tool) Zugriff auf admin-only HTML-Pages und API-Endpoints. Der reguläre
Pfad ist Keycloak-Login mit User-Passwort — funktioniert für den User
selbst, aber nicht für headless Tests, die in CI oder im Background
laufen.
Vor Phase 11b war der einzige Weg: Browser-Console-Output vom User
abfragen. Das ist langsam (User muss DevTools öffnen, Screenshot
schicken, Kontext erklären) und unsicher (User muss erinnern, wo er
geklickt hat).
## Optionen
### Option A — User-Passwort fest hinterlegen
Service-Account mit festem Passwort, in `.env` gespeichert. Test-
Skripte loggen sich darüber ein.
- **Pro:** funktioniert mit echtem Keycloak-Flow.
- **Kontra:** Service-Account ist ein vollwertiger User in Keycloak,
Passwort-Rotation muss synchron mit Keycloak geschehen. Login-Flow
ist langsam (3 HTTP-Roundtrips).
### Option B — JWT mit langer Laufzeit pre-generieren
Keycloak-Admin-API generiert ein JWT mit z.B. 7 Tagen Laufzeit, in
`.env` ablegen. Tests senden es als Bearer-Header.
- **Pro:** kein Login-Flow nötig.
- **Kontra:** 7 Tage langes JWT widerspricht der Token-Lifecycle-
Idee. Bei Leak: Keycloak kennt das Token nicht und kann es nicht
invalidieren (außer durch Sessions-Revocation des Users).
### Option C — Eigenes ENV-Secret als Bypass-Token
Eine zusätzliche Header-/Query-Pruefung im `require_auth`-Pfad: wenn
`X-Debug-Token` (oder `?__debug_token=`) dem ENV-Secret entspricht,
wird ein Mock-Admin-User zurückgegeben.
- **Pro:** kein Keycloak-Roundtrip, einfach rotierbar (ENV-Update +
Container-Recreate), inactive bei leerem ENV.
- **Kontra:** parallele Auth-Pfad neben Keycloak — Risiko bei Audit-
Anfragen, ob das System tatsächlich nur über Keycloak authentifiziert.
## Entscheidung
**Option C** umgesetzt mit folgender Härtung:
1. **ENV-binär:** `DEBUG_AUTH_TOKEN=` (leer) → Bypass komplett aus.
Default in `docker-compose.dev.yml` ist `${DEBUG_AUTH_TOKEN:-}`
wenn nicht in `.env`, kein Bypass.
2. **Nur dev-compose** reicht die ENV durch. Prod-`docker-compose.yml`
referenziert sie nicht, der Container sieht sie nicht — selbst wenn
jemand sie auf vserver setzt.
3. **Mock-User-Rollen:** `["admin", "gwoe-admin"]` — keine echten
Keycloak-Rollen, sodass z.B. `audit_log` zwischen Bypass und
regulärem Login unterscheiden kann (sub=`debug-user` vs. echte UUID).
4. **Audit-Logging:** jeder Use schreibt in `auth_bypass_uses`
(`used_at`, `client_ip`, `path`, `user_agent`) plus
`logger.warning`. Best-Effort, schlägt unter keinen Umständen den
Request fehl.
5. **Rotation:** `scripts/rotate-debug-token.sh` läuft wöchentlich
(Sonntag 04:00 Cron) und generiert ein neues `secrets.token_urlsafe(32)`
in `.env` mit `docker compose up -d --force-recreate`.
6. **Manuelle Rotation** ist trivial:
```bash
NEW=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
ssh vserver "sed -i 's|^DEBUG_AUTH_TOKEN=.*|DEBUG_AUTH_TOKEN='$NEW'|' /opt/gwoe-antragspruefer-dev/.env"
```
## Konsequenzen
### Positiv
- Headless Smoketests (siehe `tests/e2e/test_smoke_browser.py`)
laufen ohne Keycloak-Setup. 9 Tests in 52 s gegen Live-System.
- Diagnose-Sessions (Playwright + Console-Hook) sind möglich, ohne
User-Passwort zu kennen oder zu erfragen.
- Bei Audit-Anfragen: `auth_bypass_uses`-Tabelle liefert vollständige
Use-Historie mit IP+Path.
### Negativ
- Parallele Auth-Pfad. Wenn das ENV-Secret leakt, hat der Angreifer
Admin-Zugang zu dev. Mitigation: nur dev, Rotation, Logging.
- Bypass-User hat keine echte Identität — manche Endpoints wie
Mail-Versand würden mit `email="debug@local"` arbeiten. Keine
echten Mails an reale Empfänger möglich (Tabu-Regel), aber
defensives Coding nötig.
### Folgen für andere ADRs
- **0005 Keycloak SSO mit Dev-Bypass-Fallback:** das war der
„kein-Keycloak-konfiguriert"-Bypass. ADR 0012 ergänzt einen
zweiten Bypass für **konfiguriertes** Keycloak — beide sind
orthogonal und nicht konkurrierend.
- **Folge-Issue:** wenn prod-Diagnose nötig wird, könnte ein
separater prod-Bypass mit eigener Kontrollebene (z.B.
HMAC-signierte Tokens, IP-Whitelist) sinnvoll sein.

View File

@ -28,6 +28,7 @@ und Konsequenzen. Format inspiriert von [Michael Nygard](https://cognitect.com/b
| [0009](0009-protokoll-parser-registry.md) | Plenarprotokoll-Parser-Registry pro Bundesland | accepted | 2026-04-28 | | [0009](0009-protokoll-parser-registry.md) | Plenarprotokoll-Parser-Registry pro Bundesland | accepted | 2026-04-28 |
| [0010](0010-stimmverhalten-gwoe-aggregat.md) | Stimmverhalten × GWÖ-Bewertung als JOIN-Aggregat (Heuchelei + Konsistenz) | accepted | 2026-05-06 | | [0010](0010-stimmverhalten-gwoe-aggregat.md) | Stimmverhalten × GWÖ-Bewertung als JOIN-Aggregat (Heuchelei + Konsistenz) | accepted | 2026-05-06 |
| [0011](0011-aktuelle-themen-pm-generator.md) | Aktuelle-Themen-Dashboard mit PM-Generator (Persona-Prompt + Versionierung) | accepted | 2026-05-06 | | [0011](0011-aktuelle-themen-pm-generator.md) | Aktuelle-Themen-Dashboard mit PM-Generator (Persona-Prompt + Versionierung) | accepted | 2026-05-06 |
| [0012](0012-debug-auth-token-bypass.md) | DEBUG_AUTH_TOKEN-Bypass für Diagnose-Sessions auf dev | accepted | 2026-05-06 |
## Wann ADR, wann nicht ## Wann ADR, wann nicht

View File

@ -29,6 +29,7 @@ nav:
- "0009 Protokoll-Parser-Registry": adr/0009-protokoll-parser-registry.md - "0009 Protokoll-Parser-Registry": adr/0009-protokoll-parser-registry.md
- "0010 Stimmverhalten×GWÖ-Aggregat": adr/0010-stimmverhalten-gwoe-aggregat.md - "0010 Stimmverhalten×GWÖ-Aggregat": adr/0010-stimmverhalten-gwoe-aggregat.md
- "0011 Aktuelle-Themen + PM-Generator": adr/0011-aktuelle-themen-pm-generator.md - "0011 Aktuelle-Themen + PM-Generator": adr/0011-aktuelle-themen-pm-generator.md
- "0012 DEBUG_AUTH_TOKEN-Bypass": adr/0012-debug-auth-token-bypass.md
- Reference: - Reference:
- API-Endpoints: reference/api.md - API-Endpoints: reference/api.md
- Adapter-Capabilities: reference/adapter-capabilities.md - Adapter-Capabilities: reference/adapter-capabilities.md