Phase 09 — Authentik + Admin-SSO
Dauer: 1.5 Wochen (Wall-Clock — sequenziell, da nur 2 Tasks mit harter Abhängigkeit), ca. 8-10 Personentage Aufwand
Tasks: 2
Ziel: Eine eigene, self-hosted Identity-Provider-Instanz (Authentik) auf dem Hetzner-Server hochziehen und das Admin-Panel der Boilerplate (https://admin.{domain}) auf OIDC-basiertes SSO gegen diese Authentik-Instanz umstellen. Email/Passwort-Login für Admins bleibt nur noch als gekapselter Notfall-Fallback hinter einem Env-Flag bestehen. Diese Phase legt zusätzlich das Fundament für den späteren Customer-Tenant-SSO (Backlog-Item #66), der dieselbe Authentik-Instanz mit einem zweiten OIDC-Provider-Definition nutzen wird.
Warum diese Phase jetzt
- Admin-Konten sind das attraktivste Angriffsziel der Plattform — sie haben Tenant-übergreifende Sichtbarkeit, Impersonation-Rechte und Zugriff auf Audit-Logs. Eine zweite Schutzschicht (zentrale IdP mit MFA-Pflicht + zentralem Lifecycle-Management) reduziert das Risiko deutlich gegenüber einem einfachen Email/Passwort-Login.
- Phase 02 (Observability) ist Voraussetzung, weil die Authentik-Container ebenfalls Logs + Sentry-Events absetzen sollen. Ohne self-hosted Sentry wären Authentik-Fehler nicht zentral sichtbar.
- Phase 01 (TOTP-Konsolidierung) ist Voraussetzung, weil die zweite, App-interne MFA-Schicht (für sensible Actions wie Impersonation) auf der konsolidierten otpauth-Variante aufsetzt. Wir wollen nicht beide TOTP-Implementierungen mit OIDC-Code mischen.
- Backlog-Item #66 (Customer-Tenant-SSO) lebt von der hier hochgezogenen Authentik-Instanz. Wenn wir das Tenant-SSO später aktivieren, ist der Großteil der Infra schon da — wir brauchen dann nur noch eine zweite OIDC-Provider-Definition in Authentik + den Tenant-Client in der Web-App.
- Self-hosted statt SaaS (Auth0/Clerk/WorkOS) — Begründung wie bei Sentry: DSGVO-Profil, Hetzner-Server vorhanden, keine US-Cloud-Abhängigkeit für Identity-Daten.
Hetzner-Staging-Kontext
Authentik wird als zusätzlicher Coolify-managed Docker-Compose-Stack auf dem bestehenden Hetzner-Staging-Server deployed (siehe ../AGENT-INSTRUCTIONS.md §Regel 6 + ../archive/STAGING-ACCESS.md). Eigene Subdomain auth.<staging-domain> mit TLS-Termination via Traefik/Caddy (Coolify-Default). Die Web-App reicht ihre Admin-OIDC-Flows direkt an diese lokale Instanz weiter — kein Daten-Egress.
Für Production wird empfohlen, Authentik auf einem separaten, gehärteten Server zu betreiben (kein Co-Hosting mit der App-DB, eigene Firewall-Zone), um Compromise-Blast-Radius klein zu halten. Das Setup-Doku (docs/operations/authentik-setup.md) deckt beide Varianten ab (Coolify-Single-Server + dedizierter Hetzner-Server).
Task-Reihenfolge
| Reihenfolge | Task-ID | Datei | Aufwand | Parallelisierbar mit |
|---|---|---|---|---|
| 1 | #81 | authentik-setup.md |
2-3d | — (Infra-Voraussetzung für #82) |
| 2 | #82 | admin-oidc-login.md |
~1 Woche (5-7d) | — (braucht #81 fertig) |
Dependency-Graph (intern + extern)
[Phase 01: totp-consolidation #26] ─┐
│
[Phase 02: sentry-selfhost #29] ────┤
▼
#81 authentik-setup
│
▼
#82 admin-oidc-login
│
▼
[Phase 11 Backlog: customer-tenant-sso #66]
(entblockt — gleiche Authentik-Instanz, zweiter Provider)
Praktisch parallelisierbar (Multi-Agent-Setup): kaum sinnvoll innerhalb der Phase, da #82 hart auf einer laufenden Authentik-Instanz aus #81 aufbaut (OIDC-Discovery-Endpoint, Provider-IDs, Group-Mappings müssen real existieren). Ein Agent kann jedoch parallel an docs/operations/admin-sso.md arbeiten, während ein anderer #81 implementiert.
Phase Done-Definition
Diese Phase ist completed wenn:
- Alle 2 Tasks
completedinPROGRESS.md - Authentik auf Staging-Hetzner unter
https://auth.<staging-domain>erreichbar, Admin-Login mit MFA funktioniert - Zwei OIDC-Provider-Definitions in Authentik existieren:
toolctrl-admin-panel(live) undtoolctrl-tenant-sso(Platzhalter, deaktiviert) - Authentik-Groups
toolctrl-admin+toolctrl-staffexistieren, MFA (TOTP) ist fürtoolctrl-adminPflicht (Authentik-Policy) - Admin-Login über
/auth/admin/loginführt komplett durch (Authorize → Callback → Session-Cookie → Admin-Dashboard sichtbar) - JIT-Provisioning erstellt einen
AdminUser-Record beim ersten Login mit korrekt gemappter Rolle - Logout via
/auth/admin/logoutkillt lokale Session UND triggert Authentik-End-Session-Endpoint - Email/Passwort-Fallback nur aktiv bei
ADMIN_FALLBACK_LOGIN_ENABLED=true, in.env.exampledefaults auffalse - App-interne MFA-Schicht (otpauth aus #26) ist als zweiter Layer für sensible Actions verdrahtet (z.B. Impersonation, Tenant-Löschung)
- Audit-Events
admin.login.sso.success,admin.login.sso.failure,admin.login.fallback.success,admin.logout.ssowerden inAuditEventgeschrieben pnpm lint,pnpm typecheck,pnpm testglobal gründocs/operations/authentik-setup.md(Deploy + Backup + Update + Health-Checks) angelegtdocs/operations/admin-sso.md(Group-Setup + Fallback-Recovery + Operator-Runbook) angelegt.env.exampleenthält neue Keys:AUTHENTIK_ISSUER_URL,AUTHENTIK_ADMIN_CLIENT_ID,AUTHENTIK_ADMIN_CLIENT_SECRET,AUTHENTIK_ADMIN_REDIRECT_URI,AUTHENTIK_END_SESSION_URL,ADMIN_FALLBACK_LOGIN_ENABLED,ADMIN_FALLBACK_LOGIN_EMAILS(allowlist)gsd-code-reviewer-Subagent hat alle Phase-09-Commits reviewed; Findings adressiert- Backup-Restore-Drill für Authentik-Postgres erfolgreich (mind. 1x manuell durchgespielt)
- Phase-Summary in dieser README.md ergänzt
Phase Summary
(Wird nach Abschluss der Phase vom ausführenden Agent ergänzt.)
Lessons Learned
(Wird nach Abschluss ergänzt.)
Verweise
- Detail-MD-Template:
../DETAIL-MD-TEMPLATE.md - Agent-Workflow:
../AGENT-INSTRUCTIONS.md - Execution-Order:
../00-execution-order.md - Live-Status:
../PROGRESS.md - Vorgänger-Phasen:
../01-tech-debt-foundation/README.md,../02-observability/README.md - Folgendes Backlog-Item (entblockt durch diese Phase):
../11-backlog/customer-tenant-sso.md(#66)