22 KiB
Implementation Plan: Spec 402 - Resource Policy & Authorization Proof Matrix
Branch: 402-resource-policy-authorization-proof-matrix | Date: 2026-06-23 | Spec: specs/402-resource-policy-authorization-proof-matrix/spec.md
Input: Feature specification from specs/402-resource-policy-authorization-proof-matrix/spec.md
Summary
Spec 402 converts TenantPilot resource authorization from implicit/scattered proof into an auditable matrix and targeted hardening package. The implementation must inventory existing admin and system resource-backed surfaces, classify each policy/gate/capability/scoped-query decision, add focused negative tests for high-risk authorization paths, and apply only minimal hardening for confirmed gaps.
Do not start by adding policies. Build the matrix first, classify gaps, then fix only the smallest confirmed in-scope authorization defects.
Technical Context
Language/Version: PHP 8.4.15, Laravel 12.52.0
Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Laravel Sail, Pest 4.3.1, PHPUnit 12.5.4
Storage: PostgreSQL; no schema changes allowed
Testing: Pest Feature/Filament/Policy tests, focused Pest Browser smoke where available
Validation Lanes: confidence for Feature/Filament authorization tests; browser for representative UI proof; heavy-governance only if a matrix/discovery guard is implemented
Target Platform: TenantPilot Laravel monolith under apps/platform
Project Type: Laravel + Filament application
Performance Goals: No material runtime or suite-cost increase; avoid broad browser/full-suite expansion
Constraints: No new roles, permission product model, persisted truth, migrations, product surfaces, navigation, or broad refactor
Scale/Scope: Existing /admin resources/pages/actions and /system pages/actions with resource-backed authorization impact
Preparation Context
- Dirty state before preparation: clean on
platform-devate1a7752f chore: finalize high risk admin action proof pack (#472). - Spec Kit script used:
.specify/scripts/bash/create-new-feature.sh --json --number 402 --short-name resource-policy-authorization-proof-matrix "Resource Policy & Authorization Proof Matrix". - Generated branch/path:
402-resource-policy-authorization-proof-matrix,specs/402-resource-policy-authorization-proof-matrix/. - Existing conflict note: local and remote branch
402-screwfast-website-rebuildexisted before preparation, but nospecs/402-*package existed. - Candidate source: direct user-provided Spec 402 draft, promoted from Spec 400 P1 resource-policy matrix condition.
- Completed-spec guardrail: Specs 400 and 401 are read-only context. Do not rewrite their close-out, validation, completed tasks, implementation reports, or browser evidence.
Existing Repository Surfaces
Panels and routes
- Admin panel provider:
apps/platform/app/Providers/Filament/AdminPanelProvider.php, registered inapps/platform/bootstrap/providers.php, path/admin, discoversApp\Filament\Resources. - System panel provider:
apps/platform/app/Providers/Filament/SystemPanelProvider.php, registered inapps/platform/bootstrap/providers.php, path/system, discoversApp\Filament\System\Pages. - Admin route families include workspace/environment resource routes under
/admin/workspaces/{workspace}/environments/{environment}/.... - System route families include
/system/directory/...,/system/ops/...,/system/security/access-logs, and/system/repair-workspace-owners.
Authorization foundations
- Tenant/admin capabilities are registered in
apps/platform/app/Providers/AuthServiceProvider.phpfromApp\Support\Auth\Capabilities. - Platform/system capabilities are registered in
AuthServiceProviderfromApp\Support\Auth\PlatformCapabilities. - Some policies are registered via
$policiesinAuthServiceProvider. - Additional policies are manually bound in
apps/platform/app/Providers/AppServiceProvider.phpforBackupSchedule,Finding,EntraGroup, andOperationRun. - Existing central paths include
App\Services\Auth\CapabilityResolver,App\Services\Auth\WorkspaceCapabilityResolver,App\Support\Rbac\UiEnforcement, andApp\Support\Rbac\WorkspaceUiEnforcement.
Resource inventory seed
The implementation must verify this list rather than treating it as complete:
- Admin resources:
AlertDeliveryResource,AlertDestinationResource,AlertRuleResource,BackupScheduleResource,BackupSetResource,BaselineProfileResource,BaselineSnapshotResource,EntraGroupResource,EnvironmentReviewResource,EvidenceSnapshotResource,FindingExceptionResource,FindingResource,InventoryItemResource,ManagedEnvironmentResource,OperationRunResource,PolicyResource,PolicyVersionResource,ProviderConnectionResource,RestoreRunResource,ReviewPackResource,StoredReportResource,Workspaces\WorkspaceResource. - Admin model-backed pages/custom flows:
BaselineSubjectResolution,EnvironmentDashboard,EnvironmentDiagnostics,EnvironmentRequiredPermissions,FindingsIntakeQueue,MyFindingsInbox,DecisionRegister,GovernanceInbox,AuditLog,EvidenceOverview,Operations,TenantlessOperationRunViewer,CustomerReviewWorkspace,ReviewRegister,WorkspaceSettings,ManagedEnvironmentOnboardingWizard. - Relation managers: backup schedule operation runs, backup items, baseline tenant assignments, managed environment memberships, policy versions, workspace memberships, and any relation managers discovered during implementation.
- System pages: dashboard, directory tenants/workspaces/detail pages, ops controls/failures/runbooks/runs/stuck/view run, repair workspace owners, security access logs.
- Controller-backed routes: review-pack downloads/rendered reports, management-report PDF downloads, provider consent/RBAC callbacks, finding exception queue deep links, workspace/environment context switching.
UI / Surface Guardrail Plan
- Guardrail scope: existing operator/admin/system surfaces may be authorization-hardened; no new surfaces.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces: exact touched surfaces named in implementation report after matrix inventory.
- No-impact class, if applicable: N/A because rendered authorization behavior may change.
- Native vs custom classification summary: native Filament resources/pages plus existing Laravel controllers and shared authorization helpers.
- Shared-family relevance: authorization, global search, high-impact actions, relation managers, downloads/exports, system panel access.
- State layers in scope: page, table/action, relation manager, route/query, global search, controller route.
- Audience modes in scope: operator-MSP, readonly/customer where existing tests/surfaces represent it, support-platform/system.
- Decision/diagnostic/raw hierarchy plan: unchanged; do not expose new raw technical evidence.
- Raw/support gating plan: preserve or tighten existing capability gating.
- One-primary-action / duplicate-truth control: unchanged; do not add UI layers.
- Handling modes by drift class or surface: review-mandatory for high-risk authorization paths; exception-required for any policy/gate exception; hard-stop for P0 unsafe access.
- Repository-signal treatment: review-mandatory for missing policy proof, direct invocation gaps, relation/bulk/search uncertainty, and system/admin boundary gaps.
- Special surface test profiles: standard-native-filament, global-context-shell, system-admin, browser representative proof.
- Required tests or manual smoke: Feature/Filament/policy tests plus focused browser smoke.
- Exception path and spread control: documented exception in matrix and implementation report only; no runtime exception framework.
- Active feature PR close-out entry:
Guardrail / Exception / Smoke Coverage. - UI/Productization coverage decision: existing-surface authorization hardening only; no route-inventory/design matrix update unless implementation materially changes a reachable surface beyond authorization.
- Coverage artifacts to update: none planned.
- No-impact rationale: N/A.
- Navigation / Filament provider-panel handling: no provider registration changes; system/admin provider locations must be stated in close-out.
- Screenshot or page-report need: no page-report set; focused browser proof is sufficient.
Product Surface Contract Plan
- Product Surface Contract reference:
docs/product/standards/product-surface-contract.md - No-legacy posture: canonical current authorization, no compatibility exception.
- Page archetype and surface budget plan: existing archetypes only; neutral budget impact expected.
- Technical Annex and deep-link demotion plan: unchanged; do not promote OperationRun/evidence/raw IDs/source keys/payloads.
- Canonical status vocabulary plan: unchanged.
- Product Surface exceptions: none planned.
- Browser verification plan: focused representative authorization paths.
- Human Product Sanity plan: focused authorization sanity over changed rendered behavior.
- Visible complexity outcome target: neutral or decreased.
- Implementation report target:
specs/402-resource-policy-authorization-proof-matrix/implementation-report.md.
Filament / Livewire / Deployment Posture
- Livewire v4 compliance: Livewire 4.1.4 confirmed by Laravel Boost; no Livewire v3 APIs allowed.
- Panel provider registration location: unchanged; Laravel 12 providers are registered in
apps/platform/bootstrap/providers.php. - Global search posture: every resource must be classified; do not enable global search merely for completeness. Globally searchable resources need View/Edit pages,
$recordTitleAttribute, scoped queries, and tests. - Destructive/high-impact action posture: all touched destructive/high-impact actions must be action-backed,
->requiresConfirmation()where destructive/high-impact, server-authorized, audited when mutating, and tested. - Asset strategy: no new assets.
filament:assetsis not newly required unless implementation unexpectedly registers assets, which is out of scope by default. - Testing plan: policy/gate tests, Filament page/action tests, relation manager tests, direct route access tests, global search posture tests, system/admin separation tests, focused browser smoke.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, routes, panels, or navigation changes expected. If authorization hardening changes runtime behavior, deployment notes must call out safer access enforcement only.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched: policies, gates, capability resolvers, UI enforcement helpers, scoped Filament resource queries, relation managers, system capability middleware, controller authorization.
- Shared abstractions reused:
CapabilityResolver,WorkspaceCapabilityResolver, policy classes,UiEnforcement,WorkspaceUiEnforcement, platform capability middleware, existing scoped query helpers. - New abstraction introduced? why?: none planned.
- Why the existing abstraction was sufficient or insufficient: existing abstractions are the correct sources of product authorization semantics; the gap is proof consistency and any missing direct/access tests.
- Bounded deviation / spread control: gate/capability exception acceptable only when matrix documents why adding a policy would duplicate existing tested contract without increasing safety.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: proof only, possible if OperationRun-linked actions/resources are hardened.
- Central contract reused: existing OperationRun policies and links.
- Delegated UX behaviors: unchanged.
- Surface-owned behavior kept local: existing initiation inputs only.
- Queued DB-notification policy: unchanged.
- Terminal notification path: unchanged.
- Exception path: none planned.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes, for provider connection/resource/readiness authorization proof.
- Provider-owned seams: provider connection credentials/readiness/permissions details.
- Platform-core seams: workspace/environment authorization, operations, evidence, audit, capabilities, system/admin planes.
- Neutral platform terms / contracts preserved: workspace, managed environment, provider connection, operation, evidence, audit, capability.
- Retained provider-specific semantics and why: Microsoft/Graph/Entra terms remain only where existing provider-owned implementation uses them.
- Bounded extraction or follow-up path: none; provider productization is a later candidate if proof reveals UX friction rather than auth defect.
Constitution Check
- Inventory-first: PASS planned. Authorization proof inspects existing inventory/resource truth and does not alter external truth.
- Read/write separation: PASS planned. Any touched mutating action keeps server authorization, confirmation where high-impact/destructive, audit, and tests.
- Graph contract path: PASS planned. No new Graph calls.
- Deterministic capabilities: PASS planned. Use existing capability resolvers and registries.
- RBAC-UX: PASS planned. Admin
/adminand system/systemplanes remain separate; non-member/wrong-scope access deny-as-not-found; missing capability forbidden at execution level. - Workspace isolation: PASS planned. Cross-workspace direct access tests are required.
- Tenant isolation: PASS planned. ManagedEnvironment-scoped resources must remain workspace/environment safe.
- Run observability: PASS planned. Existing OperationRun behavior only.
- OperationRun start UX: PASS planned. No new local start UX.
- Data minimization: PASS planned. No secrets/raw provider payloads in reports/tests.
- Test governance: PASS planned. Confidence/browser lanes are explicit; heavy-governance cost remains visible if used.
- Proportionality: PASS planned. Matrix/report is review evidence, not runtime framework.
- No premature abstraction: PASS planned. No new helper unless spec/plan is updated.
- Persisted truth: PASS. No new persistence.
- Behavioral state: PASS. No new states.
- UI semantics: PASS. No new presentation taxonomy.
- Shared pattern first: PASS. Existing authorization helpers preferred.
- Provider boundary: PASS. Provider-specific semantics stay bounded.
- V1 explicitness / few layers: PASS. Direct tests and targeted hardening only.
- Spec discipline / bloat check: PASS. One coherent authorization proof spec rather than many micro-specs.
- Filament-native UI: PASS planned. Existing Filament authorization/action patterns preserved.
- UI/Productization coverage: PASS planned. Existing-surface authorization hardening only.
- Product Surface Contract Gate: PASS planned. Spec/plan/tasks name no-legacy, UI impact, browser proof, human sanity, global search, destructive/high-impact actions, and close-out fields.
Test Governance Check
- Test purpose / classification by changed surface: Policy/Gate for authorization decisions; Feature/Filament for resources/actions/relation managers; Browser for representative rendered proof; Heavy-Governance only for broad matrix/discovery guard.
- Affected validation lanes: confidence, browser, optional heavy-governance.
- Why this lane mix is the narrowest sufficient proof: resource authorization cannot be proven by unit tests only; browser proof is limited to representative high-risk paths.
- Narrowest proving command(s):
cd apps/platform && ./vendor/bin/sail artisan test --filter=Policycd apps/platform && ./vendor/bin/sail artisan test --filter=Authorizationcd apps/platform && ./vendor/bin/sail artisan test --filter=Capabilitycd apps/platform && ./vendor/bin/sail artisan test --filter=Filamentcd apps/platform && ./vendor/bin/sail artisan test --filter=Resourcecd apps/platform && ./vendor/bin/sail artisan test --filter=System- targeted Spec 402 test files
- focused Spec 402 browser smoke if browser test support is available
git diff --check- conditional project formatter check for changed PHP runtime/test files
- report/test/log redaction check for secrets, tokens, raw credential payloads, and sensitive raw provider payloads
- Fixture / helper / factory / seed / context cost risks: workspace/environment/user/platform-user setup; keep helpers existing or opt-in.
- Expensive defaults or shared helper growth introduced?: no by default.
- Heavy-family additions, promotions, or visibility changes: none planned except explicit matrix/discovery guard if implementation chooses it.
- Surface-class relief / special coverage rule: standard-native-filament for ordinary resource pages; special coverage for global-context-shell and system-admin boundary.
- Closing validation and reviewer handoff: implementation report records command results, lane fit, browser proof, and residual findings.
- Budget / baseline / trend follow-up: none expected; document any material test runtime growth.
- Review-stop questions: Does every fixed gap have a negative test? Did any policy duplicate capability logic? Did relation/search/bulk proof cover direct access? Did
/systemremain platform-only? - Escalation path: document-in-feature by default; follow-up-spec for structural unresolved authorization decisions; reject-or-split for scope creep.
- Active feature PR close-out entry:
Guardrail / Exception / Smoke Coverage. - Why no dedicated follow-up spec is needed: this spec itself is the bounded authorization proof package; only remaining P0/P1 blockers require a remediation spec.
Project Structure
Documentation (this feature)
specs/402-resource-policy-authorization-proof-matrix/
├── spec.md
├── plan.md
├── tasks.md
├── checklists/
│ └── requirements.md
└── implementation-report.md # created during implementation
Source Code (repository root)
Implementation may inspect and, if required by confirmed gaps, minimally edit:
apps/platform/app/Filament/Resources/
apps/platform/app/Filament/Pages/
apps/platform/app/Filament/System/Pages/
apps/platform/app/Http/Controllers/
apps/platform/app/Http/Middleware/
apps/platform/app/Policies/
apps/platform/app/Providers/AuthServiceProvider.php
apps/platform/app/Providers/AppServiceProvider.php
apps/platform/app/Services/Auth/
apps/platform/app/Support/Auth/
apps/platform/app/Support/Rbac/
apps/platform/routes/web.php
apps/platform/tests/
Structure Decision: Use the existing Laravel monolith structure. Do not create new base folders or new runtime packages. Add tests under existing domain folders or focused Spec402... files.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| Spec-local authorization matrix/report | Required to prove fragmented resource authorization across admin/system panels | Blind policy generation or local fixes would not prove relation/search/bulk/direct/system boundaries |
| Focused browser proof | Required because UI-hidden/disabled state and panel separation are rendered behavior | Feature tests alone cannot prove representative browser/Filament runtime behavior |
No runtime abstraction, persisted truth, enum/status family, or UI framework is planned.
Implementation Phases
Phase 1 - Baseline and inventory
Run required dirty-state commands, inspect panels/resources/routes/policies/gates/tests, and build the internal inventory. No edits before this phase is complete.
Phase 2 - Resource authorization matrix
Create the implementation-report matrix before adding policies or hardening code. Include all columns required by the spec.
Phase 3 - Gap classification
Classify each gap as missing proof only, sufficient gate/capability without policy, missing policy and insufficient path, UI/execution inconsistency, scope risk, system/admin boundary risk, global-search risk, relation/bulk risk, or product-decision required.
Phase 4 - Tests first for high-risk gaps
Add or update negative tests for direct access, action execution, cross-workspace denial, system/admin separation, global search, relation managers, and bulk actions before runtime hardening when feasible.
Phase 5 - Minimal hardening
Only after matrix and tests, apply the smallest safe fix: policy class, policy registration, action-level authorization, search disable/restrict, bulk/relation scoping, controller authorization, or documented exception.
Phase 6 - Focused browser proof
Run a representative browser smoke for allowed admin access, cross-workspace denial, system-only denial to workspace admin, and unauthorized high-impact action visibility/execution. Global-search posture may remain feature-level proof when exercising the search UI would turn the focused smoke into a broader browser audit.
Phase 7 - Implementation report and validation
Complete implementation-report.md, classify remaining findings, run targeted validation, record dirty state, and recommend PASS/PASS WITH CONDITIONS/FAIL.
Risk Controls
- Stop and update spec/plan before introducing new roles, capabilities, product surfaces, database changes, or a shared authorization framework.
- Treat missing product semantics as
DEFERRED: product decision required. - Preserve completed specs and historical close-out evidence.
- Do not conflate UI visibility with execution authorization.
- Do not treat global search as safe unless scoped and tested.
- Do not count route middleware alone as record-level authorization proof.
Rollout Considerations
- Staging: run targeted authorization tests and browser proof before merge.
- Production: no migrations or env changes expected. If authorization hardening changes access outcomes, release notes should mention stricter authorization enforcement.
- Queues/scheduler/storage/assets: no expected impact.
filament:assets: no new requirement unless unexpected asset registration occurs, which is out of scope.
Candidate Readiness
- Candidate Selection Gate: planned PASS because the operator explicitly promoted Spec 402, no existing spec package existed, and the scope is bounded to authorization proof/hardening.
- Spec Readiness Gate: should pass when
spec.md,plan.md,tasks.md, andchecklists/requirements.mdare complete, placeholders are removed, and preparation analysis finds no blocking artifact drift.