1
0
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

2.9 KiB

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

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.