electric-horses-infra/docs/adr/0006-silent-sso-launch-url.md
Benjamin Weinlich 88c541c9ed docs(adr): mirror 6 ADRs from M7.1 into repo
Adds the Architecture Decision Records that were written during the
Forgejo deployment (M7.1) as part of moving docs from the iCloud folder
into this versioned repository.

Includes:
- ADR-0001: Forgejo vs Gitea (non-profit stewardship)
- ADR-0002: ai-apps placement (no separate VM)
- ADR-0003: Native OIDC, not ForwardAuth
- ADR-0004: Subdomain code.sdda.eu
- ADR-0005: Volume mount on /data (lesson learned)
- ADR-0006: Silent SSO via OAuth2 launch URL (lesson learned)

Plus a docs/adr/README.md that explains the ADR format, lists the
current ADRs, and provides a template for future entries.

Refs OP#1118
2026-04-11 22:26:05 +02:00

82 lines
4.5 KiB
Markdown

# ADR-0006: Silent SSO via OAuth2-Initiate-Launch-URL
**Status:** Accepted (Lesson Learned)
**Datum:** 2026-04-11
**Entscheider:** Benjamin Weinlich
**Phase:** M7.1 — Forgejo Deployment (Post-Launch Fix)
## Kontext
Nach dem Go-Live von Forgejo stellte Benjamin fest: Wenn man im Authentik-Dashboard (welcome.sdda.eu) auf die Forgejo-Kachel klickt, wird man auf `https://code.sdda.eu/` weitergeleitet — und muss dort **erneut auf "Anmelden mit authentik"** klicken. Das fühlt sich an wie "zweimal einloggen", auch wenn der zweite Klick technisch nur den OIDC-Flow triggert.
Technisch korrekt, aber UX-Fail: Das Versprechen von SSO ist "einmal einloggen, überall drin sein". Ein Extra-Klick ist kein Single-Sign-On.
## Root Cause
Die Application `forgejo` in Authentik hatte `meta_launch_url=https://code.sdda.eu/`. Das ist die Forgejo-Startseite. Wenn der User keine Forgejo-Session hat (erster Besuch), zeigt Forgejo die Login-Seite an — und der User muss manuell den OIDC-Button klicken.
Forgejo hat **keine Config-Option** "redirect to OIDC statt Login-Seite zeigen" (wie z.B. GitLab's `auto_sign_in_with_provider`). Der OIDC-Flow wird nur bei Klick auf den Button oder bei direktem Aufruf der Route `/user/oauth2/<name>` getriggert.
## Entscheidung
**Launch-URL in Authentik auf `https://code.sdda.eu/user/oauth2/authentik` ändern.**
Das ist die Forgejo-Route die den OIDC-Flow initiiert. Wenn der User schon eine Authentik-Session hat, läuft der Flow "silent" durch (ohne User-Interaktion) und landet direkt auf der Forgejo-Startseite.
## Flow-Vergleich
### Vorher (zwei Klicks)
```
[Dashboard: Klick "Forgejo"]
↓ GET https://code.sdda.eu/
[Forgejo Login-Seite erscheint]
↓ [Klick "Anmelden mit authentik"]
↓ GET https://code.sdda.eu/user/oauth2/authentik
↓ GET https://welcome.sdda.eu/application/o/authorize/ (Auth OK, silent)
↓ GET https://code.sdda.eu/user/oauth2/authentik/callback?code=...
[Forgejo Startseite]
```
### Nachher (ein Klick)
```
[Dashboard: Klick "Forgejo"]
↓ GET https://code.sdda.eu/user/oauth2/authentik
↓ GET https://welcome.sdda.eu/application/o/authorize/ (Auth OK, silent)
↓ GET https://code.sdda.eu/user/oauth2/authentik/callback?code=...
[Forgejo Startseite]
```
Die Zwischenseite mit dem Login-Form fällt komplett weg.
## Umsetzung
Via REST API (weil Authentik-MCP keine `update_application` hat):
```bash
TOKEN=<akadmin-api>
curl -X PATCH 'http://localhost:9000/api/v3/core/applications/forgejo/' \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"meta_launch_url": "https://code.sdda.eu/user/oauth2/authentik"}'
```
## Zusätzlich behoben: must_change_password
Bei der Gelegenheit fiel auf, dass Benjamins User (`bw`) den Flag `must_change_password=true` hatte. Grund: Ich hatte während des initialen Setups `forgejo admin user change-password --username bw --password <random>` aufgerufen, um den leeren Passwort-Slot zu füllen — Forgejo markiert das User-Konto dann als "muss Passwort wechseln". Für reine OIDC-User ist das unpassend, der User hat nie ein Passwort nötig.
**Fix:**
```sql
UPDATE "user"
SET must_change_password = false, passwd = '', salt = '', passwd_hash_algo = ''
WHERE lower_name = 'bw';
```
Damit ist bw ein echter password-less OIDC-User: Login geht ausschließlich via Authentik.
## Konsequenzen
- **UX:** Authentik-Dashboard → Forgejo = ein Klick, keine Zwischenseite mehr.
- **Template aktualisiert:** `../Authentik/howto-oauth2-provider.md` hat jetzt eine explizite Warnung und Launch-URL-Beispiele für Forgejo, OpenProject, Nextcloud, Grafana.
- **Gilt für alle zukünftigen OIDC-Apps:** Die Launch-URL muss immer auf die OAuth2-Initiate-Route zeigen, nicht auf die App-Startseite. Merkhilfe: Wenn der Nutzer die App-Startseite ohne Login sieht und dort klicken muss, ist es falsch konfiguriert.
## Gotcha: Direkter Zugriff via `code.sdda.eu` bleibt unverändert
Wer `https://code.sdda.eu/` direkt in den Browser eingibt (ohne den Umweg über Authentik-Dashboard), sieht weiter die Forgejo-Login-Seite mit dem manuellen OIDC-Button. Das ist OK so: Bookmark-User die direkt auf Forgejo gehen, bekommen das Login-UI — Dashboard-User kriegen silent SSO.
Man kann das noch weiter optimieren (z.B. via `[service] DEFAULT_USER_VISIBILITY=limited` + Redirect-Magic), aber dafür gibt's keinen sauberen Konfig-Pfad in Forgejo. Current state ist guter Trade-off.
## Related
- `0003-native-oidc-not-forwardauth.md` — Warum wir nativ OIDC machen
- `../Authentik/howto-oauth2-provider.md` — Template für zukünftige Apps (jetzt mit Launch-URL-Hinweis)