docs: restructure docs to diataxis and finalize DOCS-RESTRUCTURE-001
This commit is contained in:
111
docs/reference-benutzer-lifecycle-policy.md
Normal file
111
docs/reference-benutzer-lifecycle-policy.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Benutzer-Lifecycle-Policy
|
||||
|
||||
Letzte Aktualisierung: 2026-03-06
|
||||
|
||||
## 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`
|
||||
Reference in New Issue
Block a user