## 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
6.9 KiB
6.9 KiB
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
- Lane assignment is explicit and narrowest sufficient (Feature).
- No new default-heavy helpers/factories/seeds are introduced.
- Scope/authority changes are guarded by deterministic tests before refactors.
- Any exception resolves as
document-in-feature,follow-up-spec, orreject-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.
- T001 Re-read
spec.md+plan.md+ thistasks.md. - T002 Confirm working tree intent and record baseline commit (
git status,git log -1). - T003 Inspect the confirmed authority seams:
apps/platform/app/Policies/ProviderConnectionPolicy.php:currentWorkspace()(forbidden fallback viaFilament::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()/WorkspaceHubEnvironmentFilteruse (explicitenvironment_idonly).
apps/platform/app/Support/Workspaces/WorkspaceContext.php:lastEnvironmentId()and remembered-environment helpers (navigation-only; must not grant create authority).
- T004 Inventory existing ProviderConnections tests and identify the best location for new regression tests:
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.phpapps/platform/tests/Feature/ProviderConnections/ProviderConnectionsWorkspaceHubContractTest.phpapps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.phpapps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php
Phase 2: Add failing contract tests first
Purpose: Make authority changes reviewable and regression-proof.
- T005 Add a new Spec 339 test proving create requires explicit
environment_id:- Create is denied when
/admin/provider-connections/createis requested withoutenvironment_id, - even if a remembered environment exists in session (
WorkspaceContext::lastEnvironmentId). - Implemented via:
apps/platform/tests/Feature/ProviderConnections/ScopeHardeningAuthoritySourcesTest.php
- Create is denied when
- 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.phpapps/platform/tests/Feature/ProviderConnections/ScopeHardeningResourceWorkspaceAuthorityTest.php
- 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
- T008 Add a test proving wrong-workspace environment IDs deny as 404:
environment_idfrom 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.
- 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.
- remove
- 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_iddenies as 404.
- require explicit
- 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.
- 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.
- T013 Confirm Provider Connections list filtering uses explicit
environment_idonly:- validate
environment_idagainst current workspace and access scope, - ignore legacy query aliases as authority.
- validate
- 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.
- 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.
- 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)
- 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
- T018 Run narrow tests first:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening
- T019 Run formatting and patch checks:
cd apps/platform && ./vendor/bin/sail pint --dirty --format agentgit diff --check
Explicit Non-Goals
- NT001 Do not add migrations, new tables, or new persisted truth.
- NT002 Do not redesign Provider Connections UX or navigation placement.
- NT003 Do not introduce a new scope/authority abstraction framework.
- NT004 Do not reopen provider-neutral target-scope/identity refactors (Spec 281 family).