Files
breadcrumb-the-shire/docs/howto-rbac-permissions-playbook.md
fs 0e86925464 refactor: rename lib/ to core/ for clearer core-module separation
Rename the top-level lib/ directory to core/ so the project root
immediately communicates which code is core platform and which lives
in modules/. PHP namespaces (MintyPHP\*) are unchanged — only the
Composer PSR-4 path mapping moves from lib/ to core/.

Module-internal lib/ directories (modules/*/lib/) are untouched.

Updated across the full stack:
- composer.json PSR-4 mapping
- bootstrap entry points (web/index.php, bin/*, tests/bootstrap.php)
- tooling configs (phpstan.neon, phpunit.xml, php-cs-fixer)
- 26 architecture contract tests
- enforcement-policy, guard-catalog, quality-gates
- all documentation (CLAUDE.md, README, 25 docs/, .agents/skills/)
- bin/qa-extended.sh search paths
- .claude/settings.local.json permission paths

Workflow: .agents/runs/CORE-LIB-RENAME-001/ (Analyst → Planner →
Executor → Code Review (4 findings fixed) → Security Review →
Acceptance Test → Finalizer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 23:20:42 +02:00

79 lines
2.9 KiB
Markdown

# 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 "(?<!::)\\bcan\\(" templates pages -g '*.phtml' -P
rg -n "Guard::requirePermission\\(|Guard::requirePermissionOrForbidden\\(|ApiResponse::requirePermission\\(" pages lib tests web templates -g '*.php'
docker compose exec php vendor/bin/phpunit
docker compose exec php vendor/bin/phpstan analyse -c phpstan.neon --no-progress
```
Erwartung:
1. Die beiden `rg`-Checks liefern `0` Treffer.
2. `phpunit` und `phpstan` sind grün.