## Summary - tighten workspace RBAC and panel access boundaries - remove non-owner workspace membership management capability from workspace role mapping - add focused boundary coverage for admin panel, managed environments, providers, review packs, operation runs, finding exceptions, and workspace role capabilities - include spec artifacts for feature 309 ## Testing - cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/RoleMatrix/ManagerAccessTest.php tests/Feature/Rbac/WorkspaceMembershipsRelationManagerUiEnforcementTest.php tests/Feature/Rbac/AdminPanelAccessBoundaryTest.php tests/Feature/Rbac/FindingExceptionLifecycleAccessBoundaryTest.php tests/Feature/Rbac/ManagedEnvironmentAccessBoundaryTest.php tests/Feature/Rbac/OperationRunAccessBoundaryTest.php tests/Feature/Rbac/ProviderConnectionAccessBoundaryTest.php tests/Feature/Rbac/ReviewPackAccessBoundaryTest.php tests/Feature/Rbac/SystemPanelAccessBoundaryTest.php tests/Feature/Rbac/WorkspaceRoleCapabilityBoundaryTest.php tests/Unit/Auth/CapabilityResolverTest.php tests/Unit/Auth/WorkspaceRoleCapabilityMapTest.php - cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #364
20 KiB
Implementation Plan: RBAC Role Matrix & Access Boundary Audit
Branch: 309-rbac-role-matrix-access-boundary-audit | Date: 2026-05-15 | Spec: spec.md
Input: Feature specification from /specs/309-rbac-role-matrix-access-boundary-audit/spec.md
Summary
Audit and harden TenantPilot's RBAC and panel-access boundaries across workspace, managed-environment, provider connection, review, review pack, evidence, finding exception, OperationRun, Admin panel, and System panel surfaces.
The implementation is audit-first:
- Inventory repo-real role/capability grants and direct access boundaries.
- Classify Constitution/runtime contradictions.
- Write focused tests for confirmed contradictions and boundary bugs.
- Apply only minimal runtime fixes.
- Re-run focused regression lanes and document remaining product decisions.
Technical Context
Language/Version: PHP 8.4.15, Laravel 12.52.0
Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Laravel Sail
Storage: PostgreSQL; no schema change expected
Testing: Pest 4 Unit and Feature tests; Browser only if Feature/Filament tests cannot prove a panel/action boundary
Validation Lanes: confidence; optional browser; formatting/diff-check
Target Platform: Laravel Sail locally; Dokploy container deployment for staging/production
Project Type: Laravel/Filament app under apps/platform
Performance Goals: No broad query redesign; authorization checks should reuse existing resolvers and avoid new global scans
Constraints: no new RBAC architecture, no migrations by default, no new roles, no new assets, no UI redesign, no broad route cleanup
Scale/Scope: focused security-boundary audit and minimal fixes over existing role maps/policies/panels/tests
UI / Surface Guardrail Plan
- Guardrail scope: no new operator-facing surface; direct access/action authorization and possible minor visibility alignment only.
- Native vs custom classification summary: existing Filament v5 panels/resources/pages/actions.
- Shared-family relevance: panel access, workspace/environment context, resource authorization, direct action execution, global search safety.
- State layers in scope: panel guard, middleware, route model binding, policies, Filament page/action access, Livewire action execution.
- Audience modes in scope: workspace users, customer-safe readers, platform/system users.
- Decision/diagnostic/raw hierarchy plan: no presentation hierarchy change.
- Raw/support gating plan: verify raw/provider/support details remain gated by existing policies.
- One-primary-action / duplicate-truth control: no new actions.
- Handling modes by drift class or surface: security blocker and high-risk contradiction fix in 309; product-decision-needed stays deferred.
- Repository-signal treatment: review-mandatory for role-map, panel, policy, and sensitive action changes.
- Special surface test profiles: standard-native-filament plus direct Feature/Livewire action tests.
- Required tests or manual smoke: focused Unit/Feature tests; browser not required unless direct behavior cannot be proven otherwise.
- Exception path and spread control: no exceptions planned.
- Active feature PR close-out entry: RBAC Inventory / Boundary Proof / Remaining Decisions.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched: role maps, capability resolvers, policies, gates, panels, workspace context, Filament resources/pages/actions, existing RBAC tests.
- Shared abstractions reused:
Capabilities,PlatformCapabilities,WorkspaceRoleCapabilityMap,RoleCapabilityMap,WorkspaceCapabilityResolver,CapabilityResolver,ManagedEnvironmentAccessScopeResolver, model policies, Gate definitions, Filament access methods. - New abstraction introduced? why?: none planned.
- Why the existing abstraction was sufficient or insufficient: the repo already has canonical maps and resolvers; the issue is suspected incorrect grants or missing enforcement, not absent infrastructure.
- Bounded deviation / spread control: any fix must remain local to existing maps/policies/panel checks and must not add a public permission framework.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: authorization only.
- Central contract reused:
OperationRunPolicy,OperationRunCapabilityResolver,OperationRunLinks. - Delegated UX behaviors: all existing start/completion/link feedback remains unchanged.
- Surface-owned behavior kept local: no new operation UI or notifications.
- Queued DB-notification policy: N/A.
- Terminal notification path: existing central lifecycle.
- Exception path: none.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: provider credential authorization is audited.
- Provider-owned seams: credential rotation/delete/dedicated credential management.
- Platform-core seams: ProviderConnection resource/policy and workspace/environment access boundaries.
- Neutral platform terms / contracts preserved: provider connection, provider credential, workspace, managed environment, operation.
- Retained provider-specific semantics and why: existing Microsoft/Intune details stay in provider-owned logic.
- Bounded extraction or follow-up path: no provider registry redesign; provider-specific follow-up only if audit finds structural drift.
Constitution Check
- Inventory-first: PASS. No inventory or Graph sync behavior changes are planned.
- Read/write separation: PASS. Mutations remain behind existing action flows; this spec audits and fixes authorization.
- Graph contract path: PASS. No Graph endpoint or contract change.
- Deterministic capabilities: NEEDS IMPLEMENTATION PROOF. Role/capability grants must become deterministic and tested.
- RBAC-UX: NEEDS IMPLEMENTATION PROOF. Constitution says Manager must not manage tenant memberships; current maps appear to grant Manager membership-management authority.
- Workspace isolation: NEEDS IMPLEMENTATION PROOF. Cross-workspace direct URLs must be tested for representative sensitive resources.
- Tenant/managed-environment isolation: NEEDS IMPLEMENTATION PROOF. Same-workspace wrong-environment direct URLs must be tested.
- Cross-plane access: PARTIAL PASS. Existing
/systemtests prove several tenant-session denials; Spec 309 should keep/extend focused proof. - Run observability: PASS. No new run behavior; OperationRun access must remain policy-gated.
- TEST-GOV-001: PASS if tests stay focused and no broad helper defaults are introduced.
- PROP-001 / BLOAT-001: PASS. No new tables, roles, capability framework, enum, or UI taxonomy planned.
- PERSIST-001: PASS. No new persisted truth.
- STATE-001: PASS. No new lifecycle/status family.
- UI-SEM-001: PASS. No presentation framework.
- XCUT-001: PASS if implementation reuses existing auth/policy/gate paths.
- PROV-001: PASS. Provider credential authorization is audited without expanding provider semantics.
- UI-FIL-001: PASS if any visibility alignment stays Filament-native and avoids assets/ad-hoc styling.
Initial Read-Only Repo Findings
RBAC Inventory
| Role | Current inspected sensitive capabilities | Initial match assessment | Action |
|---|---|---|---|
| Workspace Owner | workspace_membership.manage, tenant_membership.manage, provider manage/dedicated, review/evidence manage, finding exception approve |
Mostly expected | Keep unless tests reveal bypass |
| Workspace Manager | workspace_membership.manage, appended tenant_membership.manage, provider manage, review/evidence manage, finding exception approve |
High-risk contradiction for membership; other manage grants need classification | Add tests, fix membership if Owner-only confirmed |
| Workspace Operator | membership view, provider view/run, review/evidence view, findings triage, audit view | Mostly expected | Prove no owner-only mutation |
| Workspace Readonly | workspace/settings/alerts/baselines/audit view plus tenant/review/evidence/provider view via merged tenant role | Mostly expected but verify customer-safe download/mutation boundaries | Prove read-only cannot mutate |
| Platform/System | PlatformUser + PlatformCapabilities, separate platform guard |
Expected separate plane | Prove no ordinary workspace access to /system and no implicit customer data access |
Constitution vs Runtime
apps/platform/app/Services/Auth/WorkspaceRoleCapabilityMap.phpcurrently grants ManagerCapabilities::WORKSPACE_MEMBERSHIP_MANAGE.WorkspaceRoleCapabilityMap::getCapabilities()appendsCapabilities::TENANT_MEMBERSHIP_MANAGEfor Manager.apps/platform/app/Services/Auth/RoleCapabilityMap.phpdoes not grant tenant ManagerTENANT_MEMBERSHIP_MANAGE, which makes the WorkspaceRoleCapabilityMap append the direct source of the tenant-membership Manager grant..specify/memory/constitution.mdstates: "Manager ... MUST NOT manage tenant memberships (Owner-only)."- Existing tests currently assert Manager can manage tenant membership:
apps/platform/tests/Unit/Auth/CapabilityResolverTest.phpapps/platform/tests/Feature/Rbac/RoleMatrix/ManagerAccessTest.php
Panel Boundary Findings
apps/platform/app/Models/User.php::canAccessPanel()currently returnstrue.- Admin panel uses
webguard plusensure-correct-guard:web,ensure-workspace-selected, andensure-filament-tenant-selected. - System panel uses
authGuard('platform'),ensure-correct-guard:platform, andensure-platform-capability:platform.access_system_panel. - Existing tests already cover several system-panel cross-plane denials:
apps/platform/tests/Feature/Auth/CrossScopeAccessTest.phpapps/platform/tests/Feature/System/Spec113/AuthorizationSemanticsTest.phpapps/platform/tests/Feature/System/Spec114/SystemConsoleAccessSemanticsTest.php
- Spec 309 still needs a dedicated boundary test family tying those semantics to the RBAC matrix and current
canAccessPanel()posture.
Proposed Minimal Fix Strategy
- Start with static tests for
WorkspaceRoleCapabilityMapandRoleCapabilityMap. - If Constitution Owner-only semantics are confirmed, remove Manager's
WORKSPACE_MEMBERSHIP_MANAGEgrant and the Manager-specific appendedTENANT_MEMBERSHIP_MANAGE. - Update existing tests that assert Manager membership management so they become denial tests.
- Verify whether
User::canAccessPanel()can be tightened without breaking admin login/workspace chooser flow. If not, document the middleware/policy proof and add direct route tests. - Add or adjust policy/action tests for confirmed direct-access bypasses only.
- Align Filament visibility only after server-side policy behavior is correct.
- Do not change provider/review/evidence/finding-operation grants unless the audit classifies them as confirmed security bugs rather than product decisions.
Project Structure
Documentation (this feature)
specs/309-rbac-role-matrix-access-boundary-audit/
|-- spec.md
|-- plan.md
|-- tasks.md
`-- checklists/
`-- requirements.md
Likely Source Code Surfaces For Later Implementation
apps/platform/app/Support/Auth/
|-- Capabilities.php
|-- PlatformCapabilities.php
`-- WorkspaceRole.php
apps/platform/app/Support/
`-- TenantRole.php
apps/platform/app/Services/Auth/
|-- WorkspaceRoleCapabilityMap.php
`-- RoleCapabilityMap.php
apps/platform/app/Models/
|-- User.php
`-- PlatformUser.php
apps/platform/app/Providers/
|-- AuthServiceProvider.php
`-- Filament/
|-- AdminPanelProvider.php
`-- SystemPanelProvider.php
apps/platform/app/Policies/
|-- OperationRunPolicy.php
|-- ProviderConnectionPolicy.php
|-- EnvironmentReviewPolicy.php
|-- ReviewPackPolicy.php
|-- EvidenceSnapshotPolicy.php
`-- FindingExceptionPolicy.php
apps/platform/tests/Unit/Auth/
apps/platform/tests/Feature/Rbac/
apps/platform/tests/Feature/Auth/
apps/platform/tests/Feature/System/
apps/platform/tests/Feature/ProviderConnections/
apps/platform/tests/Feature/ReviewPack/
apps/platform/tests/Feature/Reviews/
apps/platform/tests/Feature/Findings/
apps/platform/tests/Feature/Operations/
Structure Decision: Use existing Laravel/Filament/Pest test families where equivalent coverage exists. Create new tests/Feature/Rbac/*BoundaryTest.php files only when no repo-real focused equivalent exists.
Technical Approach
- Inventory capabilities from
Capabilities::all()andPlatformCapabilities::all(). - Inventory role grants from
WorkspaceRoleCapabilityMap::getCapabilities()andRoleCapabilityMap::getCapabilities(). - Categorize capabilities into workspace administration, managed-environment administration, provider connections, findings/exceptions, reviews, review packs, evidence, OperationRuns, reports, support requests, and system panel.
- Compare membership, credential, lifecycle, review/export, and operation actions against Constitution RBAC-UX statements.
- Add focused tests for confirmed mismatches and direct route/action boundaries.
- Apply only the smallest map/policy/panel/resource changes needed for confirmed bugs.
- Run focused regressions for affected review, review-pack, provider, finding, and operation lanes.
- Close out with role inventory, fixed contradictions, deferred product decisions, and validation results.
Data / Model Implications
- No migration expected.
- No new model expected.
- No new capability persistence expected.
- Static role-to-capability maps may change.
- Existing
workspace_membershipsandmanaged_environment_membershipsdata is not migrated by default.
Policy / Authorization Implications
WorkspaceMembershipPolicyandWorkspaceRoleCapabilityMapare the primary owner-only membership-management proof targets.- Provider credential actions should continue to rely on
ProviderConnectionPolicy. - Review and Review Pack actions should continue to rely on
EnvironmentReviewPolicyandReviewPackPolicy. - FindingException lifecycle actions should continue to rely on
FindingExceptionPolicy. - OperationRun visibility/action access should continue to rely on
OperationRunPolicyandOperationRunCapabilityResolver. - Service-level mutations must call Gate/Policy where UI actions execute state changes.
Filament v5 / Livewire v4 Compliance Notes
- Filament is v5.2.1 and Livewire is v4.1.4.
- Panel providers are registered in
apps/platform/bootstrap/providers.php, notbootstrap/app.php. - This spec does not add a new panel provider.
- Any changed globally searchable resource must either keep an Edit/View page or disable global search.
- Destructive actions must execute via
Action::make(...)->action(...), include->requiresConfirmation(), and still authorize server-side. - No new assets are planned. Existing panel theme assets remain resolved through
PanelThemeAsset; deployment should keep the existingcd apps/platform && php artisan filament:assetsstep where registered Filament assets are published.
Test Strategy
New Or Updated Focused Tests
apps/platform/tests/Unit/Auth/WorkspaceRoleCapabilityMapTest.phpapps/platform/tests/Feature/Rbac/WorkspaceRoleCapabilityBoundaryTest.phpapps/platform/tests/Feature/Rbac/AdminPanelAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/SystemPanelAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/ManagedEnvironmentAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/ProviderConnectionAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/ReviewPackAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/OperationRunAccessBoundaryTest.phpapps/platform/tests/Feature/Rbac/FindingExceptionLifecycleAccessBoundaryTest.php
Use existing tests instead when they already provide the exact proof and update names only if a new focused file improves reviewability.
Regression Lanes
- Review/customer workspace:
apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.phpapps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php
- ReviewPack:
apps/platform/tests/Feature/ReviewPack/ReviewPackRbacTest.phpapps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php
- ProviderConnection:
- existing
apps/platform/tests/Feature/ProviderConnections/*Authorization*and credential security tests if provider boundaries change.
- existing
- OperationRun:
apps/platform/tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.phpapps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php- existing operation link/legacy route guard tests if policy or links change.
Validation Commands
cd apps/platform && ./vendor/bin/sail artisan test --compact \
tests/Unit/Auth/WorkspaceRoleCapabilityMapTest.php \
tests/Feature/Rbac/WorkspaceRoleCapabilityBoundaryTest.php \
tests/Feature/Rbac/AdminPanelAccessBoundaryTest.php \
tests/Feature/Rbac/SystemPanelAccessBoundaryTest.php \
tests/Feature/Rbac/ManagedEnvironmentAccessBoundaryTest.php \
tests/Feature/Rbac/ProviderConnectionAccessBoundaryTest.php \
tests/Feature/Rbac/ReviewPackAccessBoundaryTest.php \
tests/Feature/Rbac/OperationRunAccessBoundaryTest.php \
tests/Feature/Rbac/FindingExceptionLifecycleAccessBoundaryTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact \
tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php \
tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php \
tests/Feature/ReviewPack/ReviewPackRbacTest.php \
tests/Feature/ReviewPack/ReviewPackDownloadTest.php
If OperationRun policy or links are touched:
cd apps/platform && ./vendor/bin/sail artisan test --compact \
tests/Feature/Rbac/OperationRunWorkspaceFirstAuthorizationTest.php \
tests/Feature/Operations/TenantlessOperationRunViewerTest.php \
tests/Feature/Guards/OperationRunLinkContractGuardTest.php
Final:
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
git diff --check
Implementation Phases
- Read-only inventory: confirm role maps, panel guards, policies, routes, resources, and existing tests.
- Classification: distinguish confirmed security bugs, product decisions, docs drift, UI-only mismatches, and out-of-scope findings.
- Tests first: add failing tests for confirmed contradictions.
- Minimal fixes: adjust maps/policies/panel/resource access only where confirmed.
- Regression validation: run focused affected lanes.
- Close-out: record inventory, fixed contradictions, deferred decisions, tests, and remaining risks.
Risk Controls
- Do not remove Manager capabilities unrelated to membership unless classified as confirmed bugs.
- Do not tighten
canAccessPanel()until direct route/middleware behavior and workspace chooser flow are understood. - Do not implement support impersonation, break-glass redesign, or system-to-workspace implicit access.
- Do not add new capability aliases.
- Do not create migrations unless the existing model cannot represent the confirmed fix.
- Do not broaden test helpers or factories globally.
Rollout / Deployment Considerations
- No migration expected.
- No env vars expected.
- No queue/cron changes expected.
- No storage volume changes expected.
- No frontend build expected.
- Any changed authorization behavior must be validated in Staging before Production promotion.
- Existing Dokploy deployment should keep current asset publication and cache-clearing steps; no new asset step is introduced by this spec.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| None planned | N/A | N/A |
Open Product Decisions To Preserve If Unclear
- Manager membership-management authority.
- Manager managed-environment access-scope authority.
- Manager provider credential rotation/delete authority.
- Manager accepted-risk approval authority.
- Readonly Review Pack download authority.
- System/platform support access to customer workspaces.
Unclear items must be recorded as product-decision-needed rather than fixed blindly.