## 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
36 KiB
Feature Specification: RBAC Role Matrix & Access Boundary Audit
Feature Branch: 309-rbac-role-matrix-access-boundary-audit
Created: 2026-05-15
Status: Ready for implementation
Input: User-provided Spec 309 draft: "RBAC Role Matrix & Access Boundary Audit"
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: TenantPilot is becoming a governance-of-record platform, but repo analysis shows a possible security-boundary contradiction: the Constitution says Manager must not manage tenant memberships, while the current role capability map appears to grant Manager-level membership-management authority.
- Today's failure: The product may present deterministic workspace and managed-environment isolation while runtime capability maps, panel access, policies, and direct routes disagree. That can create privilege escalation, workspace/environment leakage, provider credential exposure, or customer-visible review artifact access outside intended scope.
- User-visible improvement: Operators and reviewers can trust that workspace isolation, managed-environment isolation, capability checks, and panel boundaries agree server-side. Sensitive membership, provider, review, review-pack, accepted-risk, and operation surfaces are proven by direct tests rather than navigation visibility.
- Smallest enterprise-capable version: Run an audit-first repo verification over the existing capability registry, role maps, panel providers, workspace context, policies, resources, and tests; add focused failing tests for confirmed contradictions; apply only minimal corrections to existing role maps, policies, panel access, or Filament visibility after server-side proof.
- Explicit non-goals: No new RBAC model, no new role family, no permission UI, no identity federation, no SCIM, no support impersonation redesign, no billing lifecycle work, no navigation cleanup, no route-family redesign, no migrations by default, no customer portal work, and no broad policy framework.
- Permanent complexity imported: Focused Unit/Feature tests and possibly small edits to existing capability maps, policies, panel access, or visibility helpers. No new table, persisted entity, enum/status family, capability registry architecture, frontend asset, or public abstraction.
- Why now: The roadmap prioritizes customer-safe review/productization, but RBAC ambiguity is a foundation risk. Spec 309 reduces security and trust risk before additional customer-facing governance surfaces are built on top.
- Why not local: The suspected contradiction spans
WorkspaceRoleCapabilityMap, Constitution role semantics,User::canAccessPanel(), panel middleware, policies, and existing tests. A local patch to one resource would not prove the boundary. - Approval class: Core Enterprise
- Red flags triggered: Cross-surface authorization audit and broad test matrix. Defense: this is a security-boundary verification pass, not a new framework; all work reuses existing capability/policy/gate infrastructure and fixes only confirmed contradictions.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve
Spec Scope Fields (mandatory)
- Scope: workspace
- Primary Routes:
/admin/admin/login- workspace and managed-environment admin surfaces under the existing Admin panel
- existing environment-scoped resource routes for Provider Connections, Environment Reviews, Review Packs, Evidence, Finding Exceptions, and Operation Runs
/system- representative
/system/*pages and operation-detail routes
- Data Ownership:
- No new persisted data.
workspace_membershipsremains the workspace role source.managed_environment_membershipsremains an access-scope/membership surface as currently implemented; this spec audits whether any remaining role-bearing or owner-only authority contradicts the Constitution.- Provider Connections, Environment Reviews, Review Packs, Evidence, Finding Exceptions, Stored Reports, and tenant-bound OperationRuns must remain workspace + managed-environment scoped.
- Workspace-bound OperationRuns may remain workspace-only, but tenant-bound runs must still enforce environment entitlement before capability checks.
- RBAC:
- Workspace membership is the first isolation boundary.
- Managed-environment entitlement is the second isolation boundary.
- Capability/policy authorization is third.
- UI visibility is last and never the security boundary.
- Non-member or out-of-scope access must deny as not found (
404) where repo policy semantics already use boundary hiding. - In-scope members missing a capability must receive
403where policies define capability denial.
This is not a canonical-view spec. No new default filter behavior is introduced.
Cross-Cutting / Shared Pattern Reuse (mandatory)
- Cross-cutting feature?: yes.
- Interaction class(es): RBAC capability resolution, panel access, route authorization, Filament resource/page access, action authorization, global search safety, operation drilldown links, provider credential actions, review/export/download access, and accepted-risk lifecycle actions.
- Systems touched:
apps/platform/app/Support/Auth/Capabilities.phpapps/platform/app/Services/Auth/WorkspaceRoleCapabilityMap.phpapps/platform/app/Services/Auth/RoleCapabilityMap.phpapps/platform/app/Providers/AuthServiceProvider.phpapps/platform/app/Models/User.phpapps/platform/app/Providers/Filament/AdminPanelProvider.phpapps/platform/app/Providers/Filament/SystemPanelProvider.phpapps/platform/app/Support/Workspaces/WorkspaceContext.phpapps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php- relevant policies/resources/pages for ProviderConnection, EnvironmentReview, ReviewPack, EvidenceSnapshot, StoredReport, FindingException, and OperationRun.
- Existing pattern(s) to extend: capability registry constants,
WorkspaceCapabilityResolver,CapabilityResolver,ManagedEnvironmentAccessScopeResolver, model policies, Gate definitions, FilamentcanAccess()/canViewAny()/ policy checks, existing cross-plane middleware, and existing 404/403 semantics. - Shared contract / presenter / builder / renderer to reuse: Existing capability/policy/gate infrastructure only. Do not introduce a new RBAC abstraction.
- Why the existing shared path is sufficient or insufficient: The repo already has a central capability registry and role maps. The issue is whether current mappings, panels, policies, and tests agree with the Constitution, not absence of infrastructure.
- Allowed deviation and why: None planned. If implementation discovers that a minimal helper is required to remove duplicated direct checks, it must be private, narrow, and justified in close-out.
- Consistency impact: Role maps, policies, direct URLs, Filament action execution, global search, operation links, and panel guards must all derive the same outcome for the same actor/workspace/environment/capability tuple.
- Review focus: Block UI-only security, raw role-string checks, direct route bypasses, cross-plane access, Manager/Operator/Readonly owner-only grants, and speculative RBAC redesign.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: yes, authorization only.
- Shared OperationRun UX contract/layer reused:
OperationRunPolicy,OperationRunCapabilityResolver,OperationRunLinks, and existing Monitoring/Operations route helpers. - Delegated start/completion UX behaviors: Existing operation start/link/display UX remains unchanged; this spec verifies that run visibility and action capability checks remain scope-safe.
- Local surface-owned behavior that remains: No new operation UI. Any touched action keeps its existing initiation input and feedback path.
- Queued DB-notification policy: N/A.
- Terminal notification path: Existing central lifecycle mechanism.
- Exception required?: none.
Provider Boundary / Platform Core Check (mandatory)
- Shared provider/platform boundary touched?: yes, provider credential access is audited.
- Boundary classification: mixed. ProviderConnection records are platform-core integration records bound to a workspace and managed environment; provider credential operations remain high-privilege provider-owned behavior.
- Seams affected: ProviderConnection policies/resources/actions, provider management capabilities, dedicated credential actions, verification/start surfaces.
- Neutral platform terms preserved or introduced: provider connection, provider credential, managed environment, workspace, operation.
- Provider-specific semantics retained and why: Existing Microsoft/Intune specifics remain inside provider connection and Graph-facing code; this spec does not introduce provider-specific platform terminology.
- Why this does not deepen provider coupling accidentally: The audit checks access boundaries only and does not add provider contracts, endpoints, or provider taxonomy.
- Follow-up path: Support Access Governance remains separate; provider capability registry redesign is out of scope.
UI / Surface Guardrail Impact (mandatory)
No new operator-facing surface is introduced. UI changes are allowed only after server-side authorization is correct and only to align visibility/disabled state with existing policy outcomes.
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Admin panel access boundary | no new surface | Existing Filament panel | panel access, workspace context | middleware, panel gate, route | no | direct URL behavior must be tested |
| System panel access boundary | no new surface | Existing Filament system panel | cross-plane access | guard, middleware, panel auth | no | ordinary workspace users must not access /system |
| Existing resource/actions visibility | possible minor alignment only | Native Filament resources/actions | action execution and visibility | action policy, page access | no | visibility follows server-side policy |
Decision-First Surface Role (mandatory when operator-facing surfaces are changed)
N/A - this spec does not create or materially redesign an operator-facing surface. Existing surfaces remain decision-owned by their current resources/pages.
Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)
N/A - no customer-facing content or disclosure hierarchy changes. Existing raw/support diagnostics must remain capability-gated or hidden according to current policies.
UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)
N/A - no new or redesigned list/detail/workbench surface. Existing Filament v5 action rules still apply to any touched resource/action: destructive actions require ->requiresConfirmation() and server-side authorization.
Operator Surface Contract (mandatory when operator-facing surfaces are changed)
N/A - no new operator surface contract. Direct access/action tests are the proof mechanism for this spec.
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no.
- New persisted entity/table/artifact?: no.
- New abstraction?: no planned abstraction.
- New enum/state/reason family?: no.
- New cross-domain UI framework/taxonomy?: no.
- Current operator problem: possible mismatch between role/capability truth, Constitution semantics, panel access, and direct route/action authorization.
- Existing structure is insufficient because: it may contain incorrect grants or missing policy checks; the structure itself is sufficient if corrected and tested.
- Narrowest correct implementation: inventory, classify, write focused tests, and adjust only existing maps/policies/panel checks where repo truth confirms a bug.
- Ownership cost: focused RBAC boundary tests and close-out inventory.
- Alternative intentionally rejected: new permission framework or role model. That would import complexity without being required for this security audit.
- Release truth: current-release trust and security boundary hardening.
Compatibility posture
The product is pre-production. Compatibility shims, legacy capability aliases, dual-read logic, and data migrations are out of scope unless a repo-verified security blocker cannot be represented by the current role/capability model.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Unit and Feature. Browser is not required unless direct panel/action behavior cannot be proven by Feature/Filament tests.
- Validation lane(s): confidence for RBAC/panel/policy tests; optional browser only for unprovable rendered panel interaction.
- Why this classification and these lanes are sufficient: Static role-map tests prove deterministic grants. Feature tests prove direct URLs, policies, action execution, and cross-scope denial. Browser smoke is unnecessary when Feature/Livewire tests prove direct route/action boundaries.
- New or expanded test families:
apps/platform/tests/Unit/Auth/WorkspaceRoleCapabilityMapTest.phpand focusedapps/platform/tests/Feature/Rbac/*BoundaryTest.phpfiles or repo-real equivalents. - Fixture / helper cost impact: moderate and feature-local. Tests need users, workspace memberships, managed environments, environment-scope rows, ProviderConnections, ReviewPacks, EnvironmentReviews, FindingExceptions, OperationRuns, and platform users. Shared helper defaults must stay cheap.
- Heavy-family visibility / justification: none expected.
- Special surface test profile: standard-native-filament and access-boundary feature tests.
- Standard-native relief or required special coverage: feature tests are preferred over browser smoke for panel boundaries and policies.
- Reviewer handoff: Confirm 404 vs 403 semantics, direct route/action proof, no UI-only security, no new RBAC model, no assets, no migrations, and no broadened test defaults.
- Budget / baseline / trend impact: low to moderate focused confidence-lane growth; no heavy-governance family.
- Escalation needed: none unless implementation discovers a structural RBAC model gap.
- Active feature PR close-out entry: RBAC Inventory / Boundary Proof / Remaining Decisions.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Auth/WorkspaceRoleCapabilityMapTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/WorkspaceRoleCapabilityBoundaryTest.php tests/Feature/Rbac/AdminPanelAccessBoundaryTest.php tests/Feature/Rbac/SystemPanelAccessBoundaryTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/ManagedEnvironmentAccessBoundaryTest.php tests/Feature/Rbac/ProviderConnectionAccessBoundaryTest.php tests/Feature/Rbac/ReviewPackAccessBoundaryTest.php tests/Feature/Rbac/OperationRunAccessBoundaryTest.php tests/Feature/Rbac/FindingExceptionLifecycleAccessBoundaryTest.phpcd 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.phpcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentgit diff --check
User Scenarios & Testing (mandatory)
User Story 1 - Role Matrix Truth Is Audited (Priority: P1)
As a platform maintainer, I need a repo-derived inventory of roles and capabilities so owner-only contradictions can be identified before new customer-facing governance surfaces are built.
Why this priority: This is the trigger for the spec and the prerequisite for deciding whether runtime behavior should change.
Independent Test: A focused role-map test can prove whether Owner, Manager, Operator, Readonly, and Platform/System grants match the intended sensitive-boundary matrix.
Acceptance Scenarios:
- Given the current capability registry and role maps, When the implementation inventories all role grants, Then the close-out lists each sensitive grant, match/mismatch classification, and action.
- Given the Constitution says Manager must not manage tenant memberships, When the role map grants Manager membership-management capability, Then the mismatch is either fixed as a confirmed bug or explicitly recorded as product-decision-needed.
User Story 2 - Panel And Scope Boundaries Are Proven Directly (Priority: P1)
As a security reviewer, I need direct URL proof for /admin, /system, workspace isolation, and managed-environment isolation so hidden navigation cannot be mistaken for security.
Why this priority: Panel and scope bypasses would be security blockers.
Independent Test: Feature tests can authenticate ordinary workspace users, platform users, non-members, wrong-workspace members, and wrong-environment members, then assert direct URLs/actions return the repo-standard denial.
Acceptance Scenarios:
- Given an ordinary workspace user, When they request
/system, Then the system returns deny-as-not-found and no system content is visible. - Given a user without valid workspace authority, When they request direct
/adminworkspace surfaces, Then access is denied by authentication/workspace middleware or policy, not only hidden navigation. - Given a member of workspace A, When they request workspace B review packs, findings, provider connections, or operation runs, Then the response denies as not found.
- Given a member scoped to environment A, When they request environment B records in the same workspace, Then the response denies as not found before capability checks.
User Story 3 - Sensitive Actions Are Server-Side Gated (Priority: P2)
As an enterprise operator, I need sensitive membership, provider credential, review/review-pack, accepted-risk, and operation actions to be impossible for unauthorized roles even through direct action execution.
Why this priority: Mutation boundaries are higher risk than read-only view boundaries, and UI visibility is explicitly not a security boundary.
Independent Test: Filament/Livewire Feature tests and policy tests can call representative actions directly and assert non-owner or missing-capability actors are denied.
Acceptance Scenarios:
- Given a Manager/Operator/Readonly actor, When they attempt owner-only membership management, Then the server denies execution.
- Given a Manager/Operator actor without high-privilege provider authority, When they attempt provider credential rotation/delete/dedicated credential management, Then the server denies execution.
- Given a Readonly actor, When they attempt finding exception approval/rejection, review publication/archive/export mutation, review-pack mutation, or operation action, Then the server denies execution.
- Given an Owner or allowed role, When they perform existing allowed flows covered by regression tests, Then the flow still works.
Edge Cases
- A user has workspace membership but no current workspace context.
- A user has workspace membership but a stale remembered managed-environment context.
- A user has platform/system authority but no workspace membership.
- A user has both web and platform sessions; cross-plane session separation must still hide the other plane.
- A record has a workspace_id / managed_environment_id mismatch.
- An OperationRun is workspace-bound with no managed_environment_id.
- An OperationRun is tenant-bound but its environment is deleted or outside the current workspace.
- A Filament URL-only action is navigation-only; confirmation behavior must not be assumed unless the action executes via
->action(...). - A resource is globally searchable but lacks an Edit/View page; global search must be disabled or the page must exist.
Functional Requirements (mandatory)
- FR-001 Role Map Inventory: Implementation MUST produce a repo-derived inventory of all roles and assigned capabilities, including Owner, Manager, Operator, Readonly, Platform/System, and any repo-real special roles.
- FR-002 Constitution Alignment: Implementation MUST compare Constitution RBAC statements against runtime mappings and classify mismatches as confirmed bug, intentional product decision, docs/constitution drift, unclear/product-decision-needed, or out of scope.
- FR-003 Owner-only Enforcement: Confirmed owner-only capabilities MUST NOT be granted to Manager, Operator, Readonly, or customer-safe actors.
- FR-004 Admin Panel Boundary Enforcement: Direct access to
/adminsurfaces MUST be tested.User::canAccessPanel()MUST NOT be the only boundary when it is permissive. - FR-005 System Panel Boundary Enforcement: Direct access to
/systemMUST be tested. Ordinary workspace users MUST NOT access the System panel through workspace roles. - FR-006 Workspace Isolation: Cross-workspace direct access MUST be denied for at least Environment Review, Review Pack, FindingException or decision surface, OperationRun, and ProviderConnection or equivalent sensitive resource.
- FR-007 Managed Environment Isolation: Same-workspace wrong-environment direct access MUST be denied for at least Review/ReviewPack, Evidence or StoredReport, FindingException, and OperationRun.
- FR-008 Provider Connection Boundary: ProviderConnection view/manage/verify/update/delete/dedicated-credential capabilities MUST match the target role model and be proven server-side.
- FR-009 Review / Review Pack Boundary: Customer-safe review and review-pack surfaces MUST preserve existing access rules, redaction, and no hidden environment leakage in summaries, counts, exports, or download URLs.
- FR-010 FindingException / Decision Boundary: Approval, rejection, renewal, revocation, closure, and accepted-risk lifecycle actions MUST be capability-gated server-side.
- FR-011 OperationRun Boundary: OperationRun visibility and action permissions MUST be workspace/environment scope-safe; run links MUST NOT grant access to users who cannot view the underlying run.
- FR-012 Service-level Authorization: Critical mutation paths MUST be checked for policy/gate enforcement beyond hidden UI actions.
- FR-013 No New RBAC System: Implementation MUST reuse existing capabilities, policies, gates, middleware, and resource checks.
- FR-014 Close-out Inventory Format: Close-out MUST include
Role -> Capabilities -> Sensitive? -> Matches target? -> Action.
Non-Functional Requirements
- NFR-001 Minimality: Fix only confirmed contradictions and direct boundary bugs.
- NFR-002 Auditability: Sensitive access decisions must be explainable by role, capability, workspace, environment, and policy.
- NFR-003 Determinism: Same user, workspace, environment, and capability set must always produce the same authorization outcome.
- NFR-004 Testability: Each corrected boundary must have focused Unit or Feature coverage.
- NFR-005 No UI-only Security: Navigation visibility, hidden actions, and disabled actions are insufficient proof.
- NFR-006 No New Assets: No CSS, JS, Vite, or design-system changes.
- NFR-007 No Migration By Default: Stop and document if a migration appears necessary.
Security Requirements
- SEC-001: Workspace isolation is mandatory for all workspace-owned records.
- SEC-002: Managed-environment isolation is mandatory for all environment-owned records.
- SEC-003: Panel access must be enforced server-side.
- SEC-004: Membership management must be Owner-only unless a repo/product decision explicitly says otherwise.
- SEC-005: Provider credential-level operations must be high privilege only.
- SEC-006: Readonly/customer-safe users must not mutate anything.
- SEC-007: Platform/system users must not implicitly access customer workspace data through system authority.
- SEC-008: Direct URLs to denied objects must follow repo-standard denial semantics:
404for non-member/out-of-scope and403for in-scope missing capability where existing policies define it. - SEC-009: No test may rely only on navigation invisibility.
Repo Evidence Anchors
Initial preparation found these repo-real paths:
| Area | Repo-real path | Preparation note |
|---|---|---|
| Capability registry | apps/platform/app/Support/Auth/Capabilities.php |
Canonical tenant/workspace capability names |
| Workspace role map | apps/platform/app/Services/Auth/WorkspaceRoleCapabilityMap.php |
User draft said Support/Auth; repo path is Services/Auth |
| Managed-environment role map | apps/platform/app/Services/Auth/RoleCapabilityMap.php |
Current tenant-role capabilities |
| Workspace roles | apps/platform/app/Support/Auth/WorkspaceRole.php |
Owner, Manager, Operator, Readonly |
| Tenant roles | apps/platform/app/Support/TenantRole.php |
Owner, Manager, Operator, Readonly |
| Platform capabilities | apps/platform/app/Support/Auth/PlatformCapabilities.php |
System panel capabilities |
| Auth/provider wiring | apps/platform/app/Providers/AuthServiceProvider.php |
Gate and policy registration |
| User panel access | apps/platform/app/Models/User.php |
canAccessPanel() currently returns true |
| Admin panel | apps/platform/app/Providers/Filament/AdminPanelProvider.php |
/admin, web guard, workspace/environment middleware |
| System panel | apps/platform/app/Providers/Filament/SystemPanelProvider.php |
/system, platform guard, platform capability middleware |
| Provider registration | apps/platform/bootstrap/providers.php |
Laravel 12 provider registration location |
| Workspace context | apps/platform/app/Support/Workspaces/WorkspaceContext.php |
Workspace session/context enforcement |
| Environment routes | apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php |
Managed-environment scoped URL model |
| OperationRun policy | apps/platform/app/Policies/OperationRunPolicy.php |
Workspace/environment/run access |
| ProviderConnection policy | apps/platform/app/Policies/ProviderConnectionPolicy.php |
Provider credential/scope boundary |
| Review policy | apps/platform/app/Policies/EnvironmentReviewPolicy.php |
Review access/mutation |
| ReviewPack policy | apps/platform/app/Policies/ReviewPackPolicy.php |
Review pack access/mutation |
| Evidence policy | apps/platform/app/Policies/EvidenceSnapshotPolicy.php |
Evidence access/mutation |
| FindingException policy | apps/platform/app/Policies/FindingExceptionPolicy.php |
Accepted-risk/decision lifecycle |
| Constitution | .specify/memory/constitution.md |
RBAC-UX owner-only and cross-plane rules |
Initial Repo-Derived Inventory Snapshot
This preparation did not implement changes, but read-only inspection found:
WorkspaceRoleCapabilityMapgrants OwnerWORKSPACE_MEMBERSHIP_MANAGEandTENANT_MEMBERSHIP_MANAGEthrough merged tenant-role capabilities.WorkspaceRoleCapabilityMapgrants ManagerWORKSPACE_MEMBERSHIP_MANAGEdirectly and appendsTENANT_MEMBERSHIP_MANAGEingetCapabilities().RoleCapabilityMapgrants tenant Manager provider manage, review pack manage, environment review manage, evidence manage, and many governance mutation capabilities, while it does not grantTENANT_ROLE_MAPPING_MANAGE.- Operator has operational and read scopes but no
TENANT_MEMBERSHIP_MANAGE,TENANT_MANAGE,PROVIDER_MANAGE, orTENANT_BACKUP_SCHEDULES_MANAGE. - Readonly has view-only provider/review/evidence/audit-style capabilities and no mutation capabilities from the inspected map.
- Platform users are separate
PlatformUserrecords using theplatformguard andPlatformCapabilities. - Existing system-panel tests already prove several tenant-session-to-
/systemdenials, but Spec 309 should add/extend focused boundary tests for the current risk matrix.
Suspected Contradictions To Verify
- Manager membership-management grant appears to contradict the Constitution line: "Manager ... MUST NOT manage tenant memberships (Owner-only)."
User::canAccessPanel()returning true may be acceptable only if admin/system middleware, guards, workspace context, and policies definitively enforce access. Implementation must prove this before changing it.- Existing tests currently assert Manager can manage tenant membership in
apps/platform/tests/Unit/Auth/CapabilityResolverTest.phpandapps/platform/tests/Feature/Rbac/RoleMatrix/ManagerAccessTest.php; if Owner-only is confirmed, those tests must be updated as failing proof before runtime fix. - Provider manage and credential-level capabilities for Manager may be intentional or too broad; classify before changing.
- Review/ReviewPack/Evidence manage capabilities for Manager may be intentional governance workflow authority; classify before changing.
- FindingException approval via workspace capability currently grants Owner and Manager from the inspected map; classify whether Manager approval is intended.
Acceptance Criteria
- AC-001 Role Inventory Produced: Close-out includes a role/capability inventory for Owner, Manager, Operator, Readonly, Platform/System, and repo-real special roles.
- AC-002 Owner-only Contradictions Resolved Or Classified: Manager/Operator grants of owner-only membership-management capability are fixed or explicitly classified.
- AC-003 Admin Panel Boundary Tested: Tests prove users without valid admin/workspace authority cannot access
/adminsurfaces through direct URLs. - AC-004 System Panel Boundary Tested: Tests prove ordinary workspace users cannot access
/system. - AC-005 Workspace Isolation Tested: Cross-workspace direct access is denied for EnvironmentReview, ReviewPack, FindingException or decision surface, OperationRun, and ProviderConnection/equivalent.
- AC-006 Managed Environment Isolation Tested: Same-workspace wrong-environment direct access is denied for Review/ReviewPack, Evidence or StoredReport, FindingException, and OperationRun.
- AC-007 Sensitive Actions Tested: At least one sensitive action from each group is tested against unauthorized roles: membership management, provider credential management, review/review-pack mutation, accepted-risk lifecycle mutation, and operation action/view.
- AC-008 UI Visibility Is Not The Only Guard: Every fixed sensitive action has a direct server-side access/action test.
- AC-009 No Broad RBAC Redesign: No new role model, table, public permission framework, or capability registry redesign is introduced.
- AC-010 Focused Tests Pass: Focused RBAC/panel/access-boundary tests pass.
- AC-011 Existing Product Flows Still Work: Existing Review, Review Pack, Findings, and OperationRun scenarios covered by regression tests still pass for Owner and allowed Manager/Operator roles.
- AC-012 Filament v5 Contract Preserved: Filament remains v5 with Livewire v4; provider registration remains in
apps/platform/bootstrap/providers.php; no new assets are introduced; deploy continues to include the existing Filament asset publication step where registered assets are used.
Assumptions
- Spec 308 is merged or cleanly separated before implementation.
- The product remains pre-production, so removing incorrect capability grants does not require data migration shims.
- Existing capability names remain canonical; no new capability strings are introduced unless implementation proves an existing owner-only capability cannot express the boundary.
- Browser tests are optional and only needed if Feature/Filament tests cannot prove a panel or action boundary.
Risks
- Removing Manager membership authority may break existing tests and workflows that assumed Manager could manage memberships.
- Constitution may be newer than current product intent; unclear cases must be product-decision-needed instead of silently fixed.
- Tightening
canAccessPanel()without understanding workspace-selection flow could block legitimate login/chooser flows. - Provider/manage and review/manage authority may be too broad for this spec if the repo treats them as product decisions.
- Adding broad fixtures could worsen test-suite cost; keep RBAC tests focused and helper setup opt-in.
Open Questions
- Can Manager manage workspace membership? Recommended default: no.
- Can Manager manage managed-environment membership/access scope? Recommended default: no unless product explicitly approves partial scope management.
- Can Manager rotate or delete provider credentials? Recommended default: no.
- Can Manager approve accepted risks? Recommended default: existing policy unless unsafe, but classify.
- Can Readonly download Review Packs? Recommended default: capability-gated according to existing review-pack policy.
- Should
User::canAccessPanel()be restrictive? Recommended default: restrictive where it does not break workspace selection, with middleware/policies still enforcing fine-grained boundaries. - Can platform/system users access workspace data? Recommended default: no implicit access; support access governance stays separate.
Candidate Selection Rationale
- Selected candidate:
309 - RBAC Role Matrix & Access Boundary Audit. - Source locations:
- explicit user-provided Spec 309 draft on 2026-05-15
.specify/memory/constitution.mdRBAC-UX rules for workspace/tenant isolation, owner-only tenant membership management, cross-plane denial, and server-side authorizationdocs/product/roadmap.mdenterprise access boundary/security hardening contextdocs/product/spec-candidates.mdenterprise access boundary/support access governance context, with support-access implementation kept out of scope
- Why selected: The repo-read found a high-risk static mismatch between Constitution owner-only membership semantics and the current Manager grants in
WorkspaceRoleCapabilityMap. This security-boundary warning should be verified before further customer-facing productization. - Why close alternatives were deferred:
- Customer Review Workspace v1 Completion is deferred until RBAC/access boundaries are verified.
- Product Truth / Docs Drift Reconciliation is deferred until Spec 309 distinguishes runtime truth from docs drift.
- Support Access Governance v1 is deferred because it is a new support/impersonation product slice, not the minimal role-matrix audit.
- Roadmap relationship: Foundation hardening before customer-safe governance productization.
- Smallest viable implementation slice: inventory, classify, focused tests, minimal fixes for confirmed contradictions, and close-out decisions.
Completed-Spec Guardrail Result
Related existing specs are context only and must not be rewritten:
specs/285-workspace-rbac-environment-access/has implementation-completed/validated task markers and browser-smoke proof; use only as workspace-first RBAC context.specs/276-support-access-governance/has completed task markers and review outcome; support access remains a follow-up, not part of 309.specs/301-admin-inventory-navigation-cutover/,specs/302-tenant-owned-surface-route-audit/,specs/303-admin-directory-groups-cutover/, andspecs/304-tenant-panel-dead-code-retirement/are completed/reviewed context for panel and route behavior.specs/307-decision-register-evidence-operationrun-link-polish/andspecs/308-decision-register-summary-review-pack/are Decision Register / Review Pack context only.- No existing
specs/309-*package existed before this preparation.
Follow-up Candidates
- Support Access Governance v1: audited support/impersonation, TTL, reason, approval, banner, and exportable access logs.
- Product Truth / Docs Drift Reconciliation: update roadmap/ledger/candidates after repo truth is confirmed.
- Commercial Entitlements / Billing-State Enforcement: plan lifecycle and workspace entitlement gates.
- Customer Review Workspace v1 Completion: continue customer-facing productization after security boundary verification.
- Route / Panel Access Contract Audit: broader route duplication and canonical-route cleanup if 309 uncovers structural route drift.
Implementation Done Definition
Spec 309 is done when the role/capability inventory is documented, owner-only contradictions are fixed or classified, /admin and /system boundaries are tested, cross-workspace and cross-environment boundaries are tested, sensitive actions are server-side denied for unauthorized roles, no new RBAC architecture is introduced, focused tests pass, Pint dirty passes, git diff --check passes, and remaining product decisions are listed as follow-ups.