This commit is contained in:
Bastian Wagner
2026-07-20 17:01:16 +02:00
parent 2f84a109e8
commit aa7758c9dd
38 changed files with 1129 additions and 134 deletions

View File

@@ -0,0 +1,63 @@
# Administratoren über OIDC
HausPilot synchronisiert die globale lokale Systemrolle mit dem stabilen Schlüssel `ADMIN` bei
jedem erfolgreichen vollständigen OIDC-Login. Die Reihenfolge der Anmeldungen spielt keine Rolle;
der frühere Mechanismus „erster Benutzer wird Administrator“ existiert nicht mehr.
## Konfiguration
```env
OIDC_ADMIN_ROLE=hauspilot-admin
OIDC_ROLES_CLAIM=roles
OIDC_ROLE_MATCH_CASE_SENSITIVE=true
```
`OIDC_ADMIN_ROLE` enthält den exakten externen Rollennamen und hat bewusst keinen Standardwert.
`OIDC_ROLES_CLAIM` unterstützt einfache und verschachtelte Pfade wie `roles`, `groups`,
`realm_access.roles` oder `resource_access.hauspilot.roles`. Der Claim darf ein String oder ein
Array aus Strings sein; Leerwerte und Duplikate werden entfernt.
Ist `OIDC_ADMIN_ROLE` leer oder nicht gesetzt, protokolliert der Start eine Warnung. HausPilot
fügt dann keine OIDC-Administratorzuweisung hinzu und entfernt auch keine bestehende. Ein gesetztes
`OIDC_ADMIN_ROLE` ohne gültiges `OIDC_ROLES_CLAIM` führt zu einem Startfehler.
## Synchronisierung und Fail-Safe-Verhalten
Nach Signatur-, Issuer-, Audience- und Nonce-Prüfung des ID Tokens werden dessen Claims mit der
subject-geprüften UserInfo zusammengeführt. Enthält der lesbare Rollenclaim `OIDC_ADMIN_ROLE`, wird
die Quelle `OIDC` für die lokale Administratorrolle sichergestellt. Fehlt die Rolle in einer
gültigen Rollenliste, wird nur diese OIDC-Quelle entfernt.
Fehlt der konfigurierte Claim technisch oder hat er ein ungültiges Format, wird keine Zuweisung
verändert und der Login fail-safe abgebrochen. Tokens und vollständige Claims werden weder
protokolliert noch zusätzlich gespeichert. Die Synchronisierung geschieht vor dem Erzeugen der
Session. Es gibt derzeit keinen Token-Refresh mit erneuter Claim-Validierung; Änderungen werden
beim nächsten vollständigen Login wirksam.
## Quellenmodell und Migration
`user_role_assignments` speichert für Benutzer, Rolle und Quelle eine eindeutige Zuweisung mit den
Quellen `MANUAL`, `OIDC` und `SYSTEM`. `user_roles` bleibt die effektive Projektion für bestehende
Berechtigungsabfragen. Die Migration übernimmt alle vorhandenen Zuordnungen als `MANUAL`; keine
bestehende Administratorrolle wird rückwirkend als OIDC interpretiert. Ein Unique Constraint
verhindert doppelte Quellen bei parallelen Logins.
Die Benutzerverwaltung zeigt die Herkunft an. Eine reine OIDC-Zuweisung lässt sich lokal nicht
entfernen; die externe Rolle muss im Identity Provider entzogen werden. Bei `MANUAL + OIDC` kann
die manuelle Quelle separat entfernt werden. Projektrollen und der Zugriff auf private Projekte
bleiben unverändert.
## Erstkonfiguration und Recovery
1. Im Identity Provider eine Adminrolle anlegen und mindestens zwei Recovery-fähigen Benutzern geben.
2. `OIDC_ADMIN_ROLE` und `OIDC_ROLES_CLAIM` in der Serverumgebung setzen.
3. Migrationen kontrolliert mit `npm run migration:run` ausführen und die Anwendung neu starten.
4. Benutzer vollständig neu anmelden.
Änderungen des Rollennamens werden pro Benutzer beim nächsten Login wirksam. Wird die Variable
geleert, bleiben bestehende OIDC-Zuweisungen bewusst erhalten. Für Notfälle kann eine kontrollierte
Datenbankoperation oder ein separater, nicht öffentlicher CLI-Prozess eine `MANUAL`-Zuweisung
setzen. Es gibt keine öffentliche Recovery-Route und keinen First-User-Fallback.
Tatsächliche Änderungen werden als `OIDC_ADMIN_ASSIGNED` beziehungsweise `OIDC_ADMIN_REMOVED`
auditiert; der externe Rollenname darf erscheinen, niemals Tokens oder vollständige Claims.