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
82 lines
4.5 KiB
Markdown
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)
|