112 lines
2.9 KiB
Markdown
112 lines
2.9 KiB
Markdown
# Benutzer-Lifecycle-Policy
|
|
|
|
Letzte Aktualisierung: 2026-02-22
|
|
|
|
## Ziel
|
|
|
|
Globale Regeln für automatische Benutzer-Deaktivierung und spätere Löschung.
|
|
|
|
- Stufe 1: Benutzer wird auf `inactive` gesetzt.
|
|
- Stufe 2: Inaktiver Benutzer wird nach weiterer Frist gelöscht (Hard Delete).
|
|
|
|
## Settings
|
|
|
|
Die Regeln werden in `settings` gespeichert:
|
|
|
|
- `user_inactivity_deactivate_days`
|
|
- `user_inactivity_delete_days`
|
|
|
|
Semantik:
|
|
|
|
- Wertebereich: `0..3650`
|
|
- `0` deaktiviert die jeweilige Regel
|
|
- Löschung wird nur angewendet, wenn Deaktivierung aktiv ist (`deactivate > 0`)
|
|
|
|
Defaults:
|
|
|
|
- Deaktivierung: `180`
|
|
- Löschung: `365` (ab Inaktivsetzung)
|
|
|
|
## Referenzdaten
|
|
|
|
- Deaktivierung basiert auf `COALESCE(last_login_at, created)`.
|
|
- Löschung basiert auf `active_changed_at` (nur wenn gesetzt).
|
|
|
|
## Privilegierte Benutzer (ausgenommen)
|
|
|
|
Automatische Lifecycle-Aktionen ignorieren Benutzer mit mindestens einer aktiven Rolle, die eine der Permissions hat:
|
|
|
|
- `settings.update`
|
|
- `tenants.update`
|
|
|
|
## Ausführung
|
|
|
|
### Manueller Run (Admin UI)
|
|
|
|
- Endpoint: `POST /admin/settings/run-user-lifecycle`
|
|
- Schutz: Login + `settings.update` + CSRF
|
|
- Verdrahtung: `SchedulerServicesFactory` erstellt `UserLifecycleService` instanzbasiert.
|
|
|
|
### Cron/CLI
|
|
|
|
- Bevorzugt über den zentralen Scheduler:
|
|
- Script: `bin/scheduler-run.php` (führt fällige Jobs aus, inkl. `user_lifecycle_run`)
|
|
- Beispiel (minütlich):
|
|
|
|
```bash
|
|
* * * * * docker compose exec php php bin/scheduler-run.php
|
|
```
|
|
|
|
Exit-Codes:
|
|
|
|
- `0` erfolgreich
|
|
- `1` Fehler/Lock-Konflikt
|
|
|
|
## Concurrency
|
|
|
|
Zur Vermeidung paralleler Runs wird ein MySQL-Lock verwendet:
|
|
|
|
- `GET_LOCK('user_lifecycle_maintenance', 0)`
|
|
- `RELEASE_LOCK('user_lifecycle_maintenance')`
|
|
|
|
## Session-Wirkung
|
|
|
|
Wenn ein bereits eingeloggter Benutzer automatisch deaktiviert wurde, greift die bestehende Session-Refresh-Logik beim nächsten Request und führt zum Logout.
|
|
|
|
## Audit-Log (Delete/Restore)
|
|
|
|
Lifecycle-Events werden in `user_lifecycle_audit_log` protokolliert.
|
|
|
|
- `deactivate`: erfolgreich ausgeführte automatische Deaktivierung
|
|
- `delete`: Löschversuch mit Snapshot
|
|
- `restore`: Wiederherstellung aus einem Delete-Event
|
|
|
|
Wichtige Regeln:
|
|
|
|
- Delete ist fail-closed: ohne erfolgreich gespeicherten Snapshot wird nicht gelöscht.
|
|
- Snapshot wird verschlüsselt in `snapshot_enc` gespeichert.
|
|
- Snapshot enthält nur whitelisted Profilfelder (keine Secrets/Tokens).
|
|
- Audit-Retention: 365 Tage (`POST /admin/user-lifecycle-audit/purge`).
|
|
|
|
## Wiederherstellung (ohne Assignments)
|
|
|
|
Restore ist nur für `action=delete` + `status=success` möglich und nur einmal pro Event.
|
|
|
|
Konfliktregeln (Hard fail):
|
|
|
|
- UUID existiert bereits
|
|
- E-Mail existiert bereits
|
|
|
|
Restore-Ergebnis:
|
|
|
|
- User wird neu angelegt mit Snapshot-Stammdaten
|
|
- `active=0`
|
|
- zufälliges Passwort
|
|
- keine Wiederherstellung von Tenant-/Role-/Department-Zuweisungen
|
|
|
|
## Rechte
|
|
|
|
- Ansicht Lifecycle-Protokolle: `user_lifecycle_audit.view`
|
|
- Wiederherstellen aus Lifecycle-Protokoll: `users.lifecycle_restore`
|
|
- Purge: `settings.update`
|