# RBAC Permission Playbook Letzte Aktualisierung: 2026-03-06 Ziel: Neue Rechte konsistent und ohne Legacy-Pfade ergänzen. ## Entscheidungshilfe 1. Nur UI an bestehende Ability hängen: 3 Schritte. 2. Neue Ability auf bestehende Permission: 4 Schritte. 3. Ganz neue Permission (inkl. DB): 7 Schritte. ## Fall A: Ganz neue Permission 1. Permission-Key in `PermissionService` ergänzen. Datei: `core/Service/Access/PermissionService.php` 2. DB-Update für Bestandsinstanzen anlegen (idempotent). Datei: `db/updates/YYYY-MM-DD-*.sql` 3. `db/init/init.sql` für Neuinstallationen synchron ergänzen. 4. Ability in passender Policy ergänzen: `ABILITY_*`, `supports()`, Mapping in `authorize()`. 5. Action/API auf Ability umstellen: Web: `Guard::requireAbility(...)` oder `AuthorizationService`. API: `ApiResponse::requireAbility(...)`. 6. Falls UI betroffen: `UiCapabilityMap` ergänzen und in Action nach `$viewAuth` auflösen. 7. Tests + Doku aktualisieren. Beispiel (Core): `system_audit.view` + `system_audit.purge` mit Abilities `ops.admin.system_audit.view` und `ops.admin.system_audit.purge`. ## Fall B: Neue Ability auf bestehende Permission 1. Ability in passender Policy ergänzen und auf vorhandenen Permission-Key mappen. 2. Action/API auf neue Ability ziehen. 3. Optional UI-Mapping in `UiCapabilityMap` + `$viewAuth`. 4. Tests/Doku nachziehen. ## Fall C: Nur UI-Freigabe erweitern (ohne neue Permission) 1. Capability-Key in `UiCapabilityMap` ergänzen. 2. In Action mit `UiAccessService::pageCapabilities(...)` oder `layoutCapabilities()` auflösen. 3. Template nur über `$viewAuth['page']` bzw. `$viewAuth['layout']` steuern. ## Fall D: API-only Endpoint 1. Ability festlegen (Policy/OperationsPolicy). 2. Endpoint mit `ApiResponse::requireAbility(...)` schützen. 3. OpenAPI aktualisieren. 4. API-Tests ergänzen. ## Fall E: Scope-sensitive Ability (Ressourcenbezug) 1. Immer Kontext übergeben, z. B.: `actor_user_id`, `target_user_id`, `target_tenant_id`, `input`. 2. Wenn Capabilities benötigt werden: `AuthorizationDecision::attribute('capabilities', [])` nutzen. 3. Für reine Bool-Checks `AuthorizationService::allow(...)` verwenden. ## Verbindliche Regeln 1. Keine Permission-Checks in Templates (`can(...)` verboten). 2. Keine alten Wrapper (`Guard::requirePermission*`, `ApiResponse::requirePermission`). 3. UI nur über `$viewAuth`. 4. Policy-/Ability-Namen sind der technische Vertrag, nicht der Permission-Key im Template. ## Minimal-Checkliste vor Merge ```bash rg -n "(?