## Summary - harden Provider Connection authority so workspace scope comes only from explicit workspace context and record ownership - require explicit `environment_id` for Provider Connection create flows and remove remembered-environment or Filament-tenant fallback authority - keep legacy query aliases such as `tenant`, `tenant_id`, and `managed_environment_id` inert for Provider Connection access - add targeted Spec 339 feature coverage for create authority, workspace authority, and wrong-workspace / legacy-query denial behavior - include Spec 339 artifacts (`spec.md`, `plan.md`, `tasks.md`) for the hardening slice ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening` ## Notes - no new uncommitted workspace changes were present to commit in this turn; the branch already contained the feature commits - Livewire v4 compliance unchanged - Filament provider registration remains in `bootstrap/providers.php` - no migrations, new assets, or route-family restructures Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #410
115 lines
6.9 KiB
Markdown
115 lines
6.9 KiB
Markdown
# Tasks: Spec 339 - Provider Connection Scope Hardening
|
|
|
|
- Input: `specs/339-provider-connection-scope-hardening/spec.md`, `specs/339-provider-connection-scope-hardening/plan.md`
|
|
- Preparation status: implementation-ready.
|
|
|
|
**Tests**: Required. This spec hardens credential-adjacent scope/authorization semantics.
|
|
|
|
## Test Governance Checklist
|
|
|
|
- [x] Lane assignment is explicit and narrowest sufficient (Feature).
|
|
- [x] No new default-heavy helpers/factories/seeds are introduced.
|
|
- [x] Scope/authority changes are guarded by deterministic tests before refactors.
|
|
- [x] Any exception resolves as `document-in-feature`, `follow-up-spec`, or `reject-or-split`.
|
|
|
|
## Phase 1: Preparation And Repo Truth (blocks runtime changes)
|
|
|
|
**Purpose**: Confirm repo truth and identify the exact forbidden fallback seams before changing behavior.
|
|
|
|
- [x] T001 Re-read `spec.md` + `plan.md` + this `tasks.md`.
|
|
- [x] T002 Confirm working tree intent and record baseline commit (`git status`, `git log -1`).
|
|
- [x] T003 Inspect the confirmed authority seams:
|
|
- `apps/platform/app/Policies/ProviderConnectionPolicy.php`:
|
|
- `currentWorkspace()` (forbidden fallback via `Filament::getTenant()`).
|
|
- `resolveCreateTenant()` (forbidden fallbacks via remembered environment + Filament tenant).
|
|
- record-derived checks for workspace/environment ownership (ensure these remain the canonical authority for view/edit/actions).
|
|
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`:
|
|
- `applyMembershipScope()` (must not infer workspace via tenant context).
|
|
- `resolveRequestedEnvironment()` / `WorkspaceHubEnvironmentFilter` use (explicit `environment_id` only).
|
|
- `apps/platform/app/Support/Workspaces/WorkspaceContext.php`:
|
|
- `lastEnvironmentId()` and remembered-environment helpers (navigation-only; must not grant create authority).
|
|
- [x] T004 Inventory existing ProviderConnections tests and identify the best location for new regression tests:
|
|
- `apps/platform/tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.php`
|
|
- `apps/platform/tests/Feature/ProviderConnections/ProviderConnectionsWorkspaceHubContractTest.php`
|
|
- `apps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php`
|
|
- `apps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php`
|
|
|
|
## Phase 2: Add failing contract tests first
|
|
|
|
**Purpose**: Make authority changes reviewable and regression-proof.
|
|
|
|
- [x] T005 Add a new Spec 339 test proving create requires explicit `environment_id`:
|
|
- Create is denied when `/admin/provider-connections/create` is requested without `environment_id`,
|
|
- even if a remembered environment exists in session (`WorkspaceContext::lastEnvironmentId`).
|
|
- Implemented via: `apps/platform/tests/Feature/ProviderConnections/ScopeHardeningAuthoritySourcesTest.php`
|
|
- [x] T006 Add a test proving workspace authority does not fall back to Filament tenant:
|
|
- When workspace context is missing, Provider Connection access is deny-as-not-found (404),
|
|
- even if `Filament::getTenant()` is set.
|
|
- Implemented via:
|
|
- `apps/platform/tests/Feature/ProviderConnections/ScopeHardeningPolicyWorkspaceAuthorityTest.php`
|
|
- `apps/platform/tests/Feature/ProviderConnections/ScopeHardeningResourceWorkspaceAuthorityTest.php`
|
|
- [x] T007 Add a test proving legacy query aliases do not grant authority:
|
|
- `?managed_environment_id=...`, `?tenant=...`, `?tenant_id=...` must not widen list scope or unlock create.
|
|
- Implemented via: `apps/platform/tests/Feature/ProviderConnections/ScopeHardeningAuthoritySourcesTest.php`
|
|
- [x] T008 Add a test proving wrong-workspace environment IDs deny as 404:
|
|
- `environment_id` from another workspace must not authorize create or list filtering.
|
|
|
|
## Phase 3: Policy authority hardening (Spec 339 contract)
|
|
|
|
**Purpose**: Remove forbidden authority fallbacks and enforce the 404/403 semantics contract.
|
|
|
|
- [x] T009 Update `apps/platform/app/Policies/ProviderConnectionPolicy.php::currentWorkspace()`:
|
|
- remove `Filament::getTenant()` as an authority source for workspace selection,
|
|
- keep workspace membership validation,
|
|
- keep deny-as-not-found (404) behavior when workspace context is missing.
|
|
- [x] T010 Update `apps/platform/app/Policies/ProviderConnectionPolicy.php::resolveCreateTenant()`:
|
|
- require explicit `environment_id`,
|
|
- remove remembered-environment fallback and Filament-tenant fallback,
|
|
- ensure wrong-workspace `environment_id` denies as 404.
|
|
- [x] T011 Confirm 404 vs 403 semantics for all policy methods:
|
|
- non-member / out-of-scope record → 404,
|
|
- member missing capability → 403.
|
|
|
|
## Phase 4: Resource scoping hardening (no hidden context authority)
|
|
|
|
**Purpose**: Ensure list/query and record surfaces do not infer authority from hidden context.
|
|
|
|
- [x] T012 Update `apps/platform/app/Filament/Resources/ProviderConnectionResource.php::applyMembershipScope()`:
|
|
- remove fallback that infers workspace ID from tenant context when session workspace is missing,
|
|
- keep query empty (no results) when workspace context is missing.
|
|
- [x] T013 Confirm Provider Connections list filtering uses explicit `environment_id` only:
|
|
- validate `environment_id` against current workspace and access scope,
|
|
- ignore legacy query aliases as authority.
|
|
- [x] T014 Confirm record pages and action dispatchers use record-derived tenant/workspace authority, not remembered environment or Filament tenant.
|
|
|
|
## Phase 5: Credential-adjacent actions audit
|
|
|
|
**Purpose**: Ensure high-risk actions remain safe and record-scoped.
|
|
|
|
- [x] T015 Audit all actions on `ProviderConnectionResource` (edit + dedicated credential actions + provider operations):
|
|
- confirm policy methods are used consistently,
|
|
- confirm destructive-like actions retain `->requiresConfirmation()`,
|
|
- confirm record ownership controls scope for all actions.
|
|
- [x] T016 Confirm audit posture remains intact for credential-adjacent mutations:
|
|
- no new audit event families are introduced in this slice,
|
|
- existing audit logging remains correct and record-scoped.
|
|
|
|
## Phase 6: Optional UX clarification (only if needed)
|
|
|
|
- [x] T017 If create is denied without `environment_id`, ensure the list empty state or guidance makes the required next step obvious (filter/select an environment first) without introducing a new picker or redesign. (No changes needed.)
|
|
|
|
## Phase 7: Validation
|
|
|
|
- [x] T018 Run narrow tests first:
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening`
|
|
- [x] T019 Run formatting and patch checks:
|
|
- `cd apps/platform && ./vendor/bin/sail pint --dirty --format agent`
|
|
- `git diff --check`
|
|
|
|
## Explicit Non-Goals
|
|
|
|
- [x] NT001 Do not add migrations, new tables, or new persisted truth.
|
|
- [x] NT002 Do not redesign Provider Connections UX or navigation placement.
|
|
- [x] NT003 Do not introduce a new scope/authority abstraction framework.
|
|
- [x] NT004 Do not reopen provider-neutral target-scope/identity refactors (Spec 281 family).
|