201 lines
17 KiB
Markdown
201 lines
17 KiB
Markdown
# Spec 402 Implementation Report - Resource Policy & Authorization Proof Matrix
|
|
|
|
## A. Candidate Gate Result
|
|
|
|
**Result: PASS.**
|
|
|
|
No P0 or P1 authorization blocker remains in the inspected high-risk proof set. The confirmed Spec 401 residual around provider action visibility was fixed and covered by focused Livewire/Filament UI and direct execution tests plus browser smoke proof for representative rendered authorization behavior.
|
|
|
|
## B. Scope
|
|
|
|
Included:
|
|
|
|
- Repository-truth authorization inventory across admin resources, system surfaces, controller-backed exports/downloads, relation managers, global search posture, and representative custom pages.
|
|
- Minimal hardening in `ProviderConnectionResource` to separate business visibility from capability authorization for provider high-impact actions.
|
|
- Focused test and browser proof for provider action UI enforcement, provider disabled-action UX, provider direct execution blocking, backup hidden mutation behavior, admin global-search safety, and system/admin separation.
|
|
|
|
Not included:
|
|
|
|
- New roles, capabilities, permission model, migrations, persisted entities, JSONB work, product taxonomy/status families, new pages, navigation changes, or broad RBAC redesign.
|
|
- Completed historical spec rewrites.
|
|
- Full browser audit of every page.
|
|
|
|
## C. Dirty State
|
|
|
|
- Starting branch: `402-resource-policy-authorization-proof-matrix`
|
|
- Starting HEAD: `e1a7752f chore: finalize high risk admin action proof pack (#472)`
|
|
- Starting dirty state: active untracked `specs/402-resource-policy-authorization-proof-matrix/`; no tracked runtime changes.
|
|
- Starting `git diff --check`: passed.
|
|
- Ending changed files:
|
|
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`
|
|
- `apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php`
|
|
- `apps/platform/tests/Browser/Spec402ResourcePolicyAuthorizationSmokeTest.php`
|
|
- `specs/402-resource-policy-authorization-proof-matrix/spec.md`
|
|
- `specs/402-resource-policy-authorization-proof-matrix/plan.md`
|
|
- `specs/402-resource-policy-authorization-proof-matrix/implementation-report.md`
|
|
- `specs/402-resource-policy-authorization-proof-matrix/tasks.md`
|
|
- No unrelated dirty files were reset, deleted, or cleaned.
|
|
|
|
## D. Resource Policy & Authorization Matrix
|
|
|
|
| Resource / Surface | Panel | Model | Category | Scope | Policy | Gate / Capability | CRUD | Custom Actions | Bulk | Relations | Global Search | Query Scope Proof | Direct Access Proof | Tests | Decision |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
| Provider connections | Admin | `ProviderConnection` | B | Workspace + environment | `ProviderConnectionPolicy` | `provider.view`, `provider.manage`, `provider.manage_dedicated`, `provider.run` | View/create/edit gated | Check, sync, snapshot, default, lifecycle, dedicated credential actions | None | N/A | Disabled | `applyMembershipScope()` | Non-member 404 route tests | Provider UI enforcement + direct execution denial + Spec 402 browser | PASS |
|
|
| Backup schedules | Admin | `BackupSchedule` | B | Environment | `BackupSchedulePolicy` | tenant view/manage/run/delete | View allowed; mutations gated | Run, retry, archive, restore, force delete | Run/retry | Operation runs | Disabled | tenant-owned query trait | Non-member 404 + forged-key tests | Backup lifecycle/run tests + browser | PASS |
|
|
| Backup sets | Admin | `BackupSet` | B | Environment | Query/gate path | tenant view/restore capabilities | Read/detail scoped | Add policies via relation | None | Backup items | Disabled | tenant-owned query | Existing parity tests | Backup set/RBAC tests | PASS |
|
|
| Restore runs | Admin | `RestoreRun` | B | Environment | Query/gate path | restore/tenant capabilities | Read/create gated | Execute/confirm safety flow | None | N/A | Disabled | tenant-owned query | Restore UI tests | Restore run enforcement | PASS |
|
|
| Policies | Admin | `Policy` | B | Environment | Query/gate path | tenant view/sync/restore | Read scoped | Sync/restore actions gated | None | Versions | Disabled | tenant-owned query | Existing route/search tests | Policy resource/search tests | PASS |
|
|
| Policy versions | Admin | `PolicyVersion` | B | Environment | Query/gate path | tenant view/restore | Read scoped | Restore gated | None | N/A | Disabled | tenant-owned query | Existing tests | Policy version RBAC/search | PASS |
|
|
| Inventory items | Admin | `InventoryItem` | A | Environment | Query/gate path | tenant view | Read scoped | None | None | N/A | Existing scoped posture | scoped query | Existing tests | Inventory item tests | PASS |
|
|
| Entra groups | Admin | `EntraGroup` | A/B | Environment | `EntraGroupPolicy` | Entra roles view/manage | Read/mutate gated | Sync/manage actions gated | None | N/A | Existing scoped URL | scoped query | Existing tests | Directory group tests | PASS |
|
|
| Findings | Admin | `Finding` | B | Environment/workspace | `FindingPolicy` | finding view/triage/assign/resolve | Read/mutate gated | Workflow actions gated | Bulk triage | Exceptions | Existing scoped posture | scoped query | Existing workflow tests | Findings tests | PASS |
|
|
| Finding exceptions | Admin | `FindingException` | B | Environment/workspace | `FindingExceptionPolicy` | exception view/manage/approve | Read/mutate gated | Approval/renewal/decision actions | None | Decisions | Disabled | scoped query | Existing lifecycle tests | Exception RBAC tests | PASS |
|
|
| Environment reviews | Admin | `EnvironmentReview` | B/C | Environment/customer-safe output | `EnvironmentReviewPolicy` | review view/manage/acknowledge | Read/mutate gated | Export/acknowledge gated | None | Sections | Disabled | scoped query | Existing tests | Review UI/export tests | PASS |
|
|
| Review packs | Admin | `ReviewPack` | C | Environment/customer output | `ReviewPackPolicy` + `CustomerOutputGate` | review pack view/manage | Read/mutate gated | Download/publish/resolve gated | None | Reports | Disabled | scoped query | Controller tests | Review pack/customer output tests | PASS |
|
|
| Stored reports | Admin | `StoredReport` | C | Environment/customer output | Query/gate path | review/report capabilities | Read/create/edit/delete gated | Download gated | None | Review pack | Disabled | scoped query | Existing tests | Stored report tests | PASS |
|
|
| Evidence snapshots | Admin | `EvidenceSnapshot` | C | Environment/evidence | `EvidenceSnapshotPolicy` | evidence view/manage | Read/mutate gated | Capture/publish gated | None | N/A | Disabled | scoped query | Existing tests | Evidence tests | PASS |
|
|
| Baseline profiles | Admin | `BaselineProfile` | B | Workspace/environment assignment | Query/gate path | baseline/manage capabilities | Read/mutate gated | Compare/capture gated | None | Assignments | Disabled | scoped query | Existing tests | Baseline action tests | PASS |
|
|
| Baseline snapshots | Admin | `BaselineSnapshot` | B | Environment | Query/gate path | tenant view/baseline | Read scoped | Compare/details | None | N/A | Disabled | scoped query | Existing tests | Snapshot auth tests | PASS |
|
|
| Alerts | Admin | `AlertRule`, `AlertDestination`, `AlertDelivery` | B | Workspace/environment | Alert policies | alert view/manage | Read/mutate gated | Test/send/ack gated | None | Deliveries | Disabled | scoped queries | Existing access tests | Alert access/viewer tests | PASS |
|
|
| Operation runs | Admin | `OperationRun` | A/C | Environment/workspace | `OperationRunPolicy` | ops/tenant view | Read scoped | Retry/view links gated by source | None | N/A | Disabled | scoped query | Existing tests | Ops/run tests | PASS |
|
|
| Managed environments | Admin | `ManagedEnvironment` | D | Workspace | Query/gate path | tenant/workspace capabilities | Read/manage gated | Onboarding/verify/setup gated | None | Memberships | Disabled by query | workspace scope | Existing tests | Tenant action tests | PASS |
|
|
| Workspaces | Admin | `Workspace` | D | Workspace | `WorkspacePolicy` | workspace view/manage | Read/manage gated | Membership/settings | None | Memberships | Existing scoped posture | workspace query | Existing tests | Workspace RBAC tests | PASS |
|
|
| Custom admin pages | Admin | Multiple/read models | A-D | Workspace/environment | Page-level gates/resolvers | Existing tenant/workspace capabilities | Page access scoped | Page actions gated | N/A | N/A | N/A | context middleware + page queries | Existing page tests | Surface guard tests | PASS |
|
|
| System panel pages | System | `PlatformUser`, ops/directory models | D/E | System only | Platform guard + page capabilities | `PlatformCapabilities::*` | Page access gated | Repair/ops controls gated | N/A | N/A | System-only | `platform` guard + middleware | Tenant session 404; missing capability 403 | System boundary tests + browser | PASS |
|
|
| Review/download controllers | HTTP | Review/report models | C | Environment/customer output | Controller authorization + output gates | review pack view/customer output gate | Download only | Stream/export | N/A | N/A | N/A | tenant/workspace checks | Controller tests | Review/report tests | PASS |
|
|
| Provider callbacks/context routes | HTTP | Provider/workspace context | D | Workspace/environment | Middleware + controller checks | provider/manage/context | Callback/context only | Consent/RBAC callbacks | N/A | N/A | N/A | guarded routes | Existing route tests | Provider/onboarding tests | PASS |
|
|
| Relation managers | Admin | Related models | B/C/D | Owner record scope | Owner resource + relation checks | owner capabilities | Related CRUD/attach gated | Add/remove/update gated | N/A | Owner scoped | N/A | relation owner scoping | Existing relation tests | Relation-manager RBAC tests | PASS |
|
|
|
|
## E. Runtime Changes
|
|
|
|
- `ProviderConnectionResource` now uses `recordAllowsProviderMemberVisibility()` for action visibility and leaves capability decisions to `UiEnforcement::requireCapability()`.
|
|
- The change covers provider edit, run/check/sync/snapshot, default, lifecycle, and dedicated credential actions.
|
|
- Result: non-members remain hidden/404, members missing capability get visible-disabled or non-exposed rendered behavior depending on Filament action-group rendering, and server-side guards remain capability-backed.
|
|
|
|
## F. Policies / Gates / Capabilities
|
|
|
|
- Added policies: none.
|
|
- Added capabilities: none.
|
|
- Updated gates: none.
|
|
- Existing provider capabilities remain authoritative: `provider.manage`, `provider.manage_dedicated`, `provider.run`.
|
|
- Documented exception: models with sufficient existing scoped query + capability paths were not given cosmetic policies.
|
|
|
|
## G. Tests Added / Updated
|
|
|
|
- Updated `ProviderConnectionsUiEnforcementTest` with manager-without-dedicated-capability proof and direct Livewire execution denial for disabled provider operations.
|
|
- Added `Spec402ResourcePolicyAuthorizationSmokeTest` browser smoke.
|
|
- Reused existing focused tests for global search, system/admin separation, backup hidden/disabled mutation behavior, and direct resource denial.
|
|
|
|
## H. Proof Summary
|
|
|
|
- Direct access: provider non-member route tests and backup schedule non-member tests prove deny-as-not-found behavior.
|
|
- UI visibility/action execution: provider actions are disabled for members missing capabilities; direct Livewire calls to disabled provider check/sync/snapshot actions do not queue jobs or create OperationRuns; backup readonly cannot dispatch run/retry.
|
|
- Workspace/environment isolation: backup browser smoke proves cross-workspace denied path; feature tests cover provider guessed URLs.
|
|
- System/admin separation: feature tests prove tenant users get 404 on `/system`; browser smoke covers rendered denial.
|
|
- Customer/internal boundary: review/report controllers retain existing authorization and customer output gates; no runtime changes.
|
|
- Global search: representative high-risk admin resources remain disabled; global-search safety tests passed.
|
|
- Relation managers and bulk actions: existing relation/bulk tests remain the proof source; no relation or bulk runtime changes.
|
|
|
|
## I. Focused Browser Proof
|
|
|
|
Command:
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test tests/Browser/Spec402ResourcePolicyAuthorizationSmokeTest.php --compact
|
|
```
|
|
|
|
Result: passed, 1 test / 22 assertions.
|
|
|
|
Covered:
|
|
|
|
- Authorized admin provider detail for owner.
|
|
- Readonly provider detail renders provider verification/edit/sync/snapshot actions as visible but disabled, with no JavaScript or console errors.
|
|
- Readonly backup schedule list renders without exposing `Run now` and creates no operation run; this is the browser high-impact hidden-action proof.
|
|
- Cross-workspace backup schedule path denied.
|
|
- Workspace web session denied on `/system`.
|
|
- No JavaScript or console errors on checked pages.
|
|
|
|
Not covered by the focused browser smoke:
|
|
|
|
- Provider direct disabled-action execution is covered by `ProviderConnectionsUiEnforcementTest`.
|
|
- Global-search disabled/scoped posture is covered by `AdminGlobalSearchContextSafetyTest`; the browser smoke intentionally does not claim global-search UI coverage.
|
|
|
|
Note: stale Playwright run-server processes from previous browser work initially caused `SIGKILL`; those orphaned runner processes were stopped, and the final browser proof passed. No runner processes remained after cleanup.
|
|
|
|
## J. Remaining Findings
|
|
|
|
- P0: none.
|
|
- P1: none.
|
|
- P2: full browser audit across every matrix row and global-search browser UI proof remain intentionally out of scope.
|
|
- P3: some low-risk/read-only resources rely on scoped query + capability paths rather than dedicated policy classes; documented as sufficient existing architecture.
|
|
|
|
## K. Deferred Items
|
|
|
|
- Evidence currentness closure: deferred to the evidence/review feature stream.
|
|
- Management PDF staging validation: deferred; no PDF behavior changed.
|
|
- Governance lifecycle expansion: deferred.
|
|
- JSONB migration/index work: deferred.
|
|
- Full browser audit: deferred.
|
|
- Product decision changes for roles/capabilities: none requested and none added.
|
|
|
|
## L. Validation Commands
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail pint app/Filament/Resources/ProviderConnectionResource.php tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php tests/Browser/Spec402ResourcePolicyAuthorizationSmokeTest.php
|
|
```
|
|
|
|
Result: passed.
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php --compact
|
|
```
|
|
|
|
Result: passed, 7 tests / 97 assertions.
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php tests/Feature/Rbac/SystemPanelAccessBoundaryTest.php --compact
|
|
```
|
|
|
|
Result: passed, 13 tests / 112 assertions.
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php tests/Feature/Rbac/SystemPanelAccessBoundaryTest.php tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php tests/Feature/BackupScheduling/RunNowRetryActionsTest.php --filter='provider|global search|system panel|readonly|members without manage capability|dedicated' --compact
|
|
```
|
|
|
|
Result: passed, 14 tests / 134 assertions.
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test tests/Browser/Spec402ResourcePolicyAuthorizationSmokeTest.php --compact
|
|
```
|
|
|
|
Result: passed, 1 test / 22 assertions.
|
|
|
|
```bash
|
|
git diff --check
|
|
```
|
|
|
|
Result: passed.
|
|
|
|
## M. Recommended Next Action
|
|
|
|
Proceed to Spec 403 only after review of this proof matrix and runtime hardening. The next spec should not introduce new roles/capabilities unless a product decision explicitly requires it.
|
|
|
|
Product Surface Contract close-out:
|
|
|
|
- No-legacy posture: no legacy surface introduced.
|
|
- Product Surface Impact: existing authorization hardening only.
|
|
- UI Surface Impact: existing Filament action visibility/disabled posture only; no new page, navigation, widget, or copy-heavy surface.
|
|
- Page archetype: standard native Filament resources.
|
|
- Surface budgets: unchanged.
|
|
- Technical Annex / deep-link demotion: N/A.
|
|
- Canonical status vocabulary: unchanged.
|
|
- Product Surface exceptions: none.
|
|
- Focused browser proof: completed via `Spec402ResourcePolicyAuthorizationSmokeTest`.
|
|
- Human Product Sanity: visible disabled affordances increased intentionally inside existing provider More/action surfaces to satisfy RBAC-UX; the focused browser smoke verified the readonly provider actions are rendered disabled. No new page, navigation, widget, or copy-heavy surface was added, and readonly users are not offered executable high-impact controls.
|
|
- Livewire v4: compliant with installed Livewire 4.1.4.
|
|
- Provider registration: panels remain registered in `apps/platform/bootstrap/providers.php`.
|
|
- Global search: no globally searchable resource was enabled; high-risk resources remain disabled or existing scoped.
|
|
- Destructive/high-impact actions: existing `->requiresConfirmation()` retained; authorization remains enforced by `UiEnforcement` and policies/gates.
|
|
- Asset strategy: no assets added; `filament:assets` deployment step unchanged and not newly required by this spec.
|
|
- Deployment impact: no migrations, env vars, queues, storage, or asset build changes.
|