TenantAtlas/specs/309-rbac-role-matrix-access-boundary-audit/spec.md
ahmido dd175c16a1 fix: tighten workspace RBAC access boundaries (#364)
## 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
2026-05-15 14:00:21 +00:00

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_memberships remains the workspace role source.
    • managed_environment_memberships remains 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 403 where 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.php
    • apps/platform/app/Services/Auth/WorkspaceRoleCapabilityMap.php
    • apps/platform/app/Services/Auth/RoleCapabilityMap.php
    • apps/platform/app/Providers/AuthServiceProvider.php
    • apps/platform/app/Models/User.php
    • apps/platform/app/Providers/Filament/AdminPanelProvider.php
    • apps/platform/app/Providers/Filament/SystemPanelProvider.php
    • apps/platform/app/Support/Workspaces/WorkspaceContext.php
    • apps/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, Filament canAccess() / 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.php and focused apps/platform/tests/Feature/Rbac/*BoundaryTest.php files 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.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/WorkspaceRoleCapabilityBoundaryTest.php tests/Feature/Rbac/AdminPanelAccessBoundaryTest.php tests/Feature/Rbac/SystemPanelAccessBoundaryTest.php
    • cd 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.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
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git 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:

  1. 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.
  2. 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:

  1. Given an ordinary workspace user, When they request /system, Then the system returns deny-as-not-found and no system content is visible.
  2. Given a user without valid workspace authority, When they request direct /admin workspace surfaces, Then access is denied by authentication/workspace middleware or policy, not only hidden navigation.
  3. 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.
  4. 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:

  1. Given a Manager/Operator/Readonly actor, When they attempt owner-only membership management, Then the server denies execution.
  2. 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.
  3. 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.
  4. 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 /admin surfaces MUST be tested. User::canAccessPanel() MUST NOT be the only boundary when it is permissive.
  • FR-005 System Panel Boundary Enforcement: Direct access to /system MUST 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: 404 for non-member/out-of-scope and 403 for 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:

  • WorkspaceRoleCapabilityMap grants Owner WORKSPACE_MEMBERSHIP_MANAGE and TENANT_MEMBERSHIP_MANAGE through merged tenant-role capabilities.
  • WorkspaceRoleCapabilityMap grants Manager WORKSPACE_MEMBERSHIP_MANAGE directly and appends TENANT_MEMBERSHIP_MANAGE in getCapabilities().
  • RoleCapabilityMap grants tenant Manager provider manage, review pack manage, environment review manage, evidence manage, and many governance mutation capabilities, while it does not grant TENANT_ROLE_MAPPING_MANAGE.
  • Operator has operational and read scopes but no TENANT_MEMBERSHIP_MANAGE, TENANT_MANAGE, PROVIDER_MANAGE, or TENANT_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 PlatformUser records using the platform guard and PlatformCapabilities.
  • Existing system-panel tests already prove several tenant-session-to-/system denials, 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.php and apps/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 /admin surfaces 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.md RBAC-UX rules for workspace/tenant isolation, owner-only tenant membership management, cross-plane denial, and server-side authorization
    • docs/product/roadmap.md enterprise access boundary/security hardening context
    • docs/product/spec-candidates.md enterprise 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/, and specs/304-tenant-panel-dead-code-retirement/ are completed/reviewed context for panel and route behavior.
  • specs/307-decision-register-evidence-operationrun-link-polish/ and specs/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.