Added `ProviderResourceBinding` model, migrations, policies, and supporting framework for canonical resource identity mapping as defined in Spec 381. This provides the structural capability to resolve baseline and posture discrepancies by binding logical entities across source providers to canonical identities. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #452
14 KiB
Tasks: Spec 381 - Provider Resource Identity and Binding Foundation v1
Input: specs/381-provider-resource-identity-binding/spec.md, specs/381-provider-resource-identity-binding/plan.md
Prerequisites: Spec and plan are complete. Spec 163 and Spec 380 are historical/context only and must not be rewritten. This task list is for a later implementation loop, not for this preparation step.
Tests: Unit, Feature, PostgreSQL, and targeted no-op baseline/evidence/review regression tests are required. Browser tests are not required because no UI surface changes.
Test Governance Checklist
- Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- New tests stay in the smallest honest family; no heavy-governance or browser family is introduced.
- Shared helpers, factories, seeds, fixtures, provider setup, workspace membership context, and fake-provider defaults stay cheap by default.
- PostgreSQL validation is used only for migration/partial unique/composite foreign key/index behavior that SQLite cannot prove.
- Planned validation commands cover identity, binding service behavior, authorization, audit, PostgreSQL uniqueness, workspace/environment integrity, source-reference scoping, and current-runtime no-op behavior.
- Any material budget, baseline, trend, or escalation note is recorded in the implementation close-out.
Phase 1: Baseline And Guardrail Reconfirmation
Purpose: Confirm repo truth and protect completed-spec history before implementation.
- T001 Record current branch, HEAD, dirty state, and intended touched-file set in the implementation close-out notes for
specs/381-provider-resource-identity-binding/. - T002 Re-read
specs/381-provider-resource-identity-binding/spec.md,specs/381-provider-resource-identity-binding/plan.md, andspecs/381-provider-resource-identity-binding/tasks.md. - T003 Re-read
specs/163-baseline-subject-resolution/spec.md,specs/163-baseline-subject-resolution/plan.md, andspecs/163-baseline-subject-resolution/tasks.mdas completed/historical context without editing Spec 163. - T004 Re-read
apps/platform/app/Support/Baselines/BaselineSubjectKey.php,apps/platform/app/Support/Baselines/SubjectClass.php,apps/platform/app/Support/Baselines/ResolutionOutcome.php, andapps/platform/app/Support/Baselines/Compare/CompareSubjectIdentity.php. - T005 Re-read
apps/platform/app/Models/ProviderConnection.php,apps/platform/app/Models/ManagedEnvironment.php,apps/platform/app/Models/AuditLog.php,apps/platform/app/Support/Auth/Capabilities.php, and existing provider/baseline policy tests. - T006 Confirm no Filament resource/page/action, route, Livewire component, Blade view, Graph client, provider adapter, OperationRun type, or evidence/review behavior change is planned; if one appears necessary, stop and update spec/plan before continuing.
Phase 2: Identity And Canonical Key Foundation
Purpose: Represent provider identity and canonical subject keys without display names as primary identity.
- T007 [P] [US1] Add unit coverage in
apps/platform/tests/Unit/Support/Resources/ResourceIdentityTest.phpfor tenant-owned, built-in, default, virtual, unsupported, and unknown identities. - T008 [P] [US1] Add unit coverage in
apps/platform/tests/Unit/Support/Baselines/BaselineSubjectKeyCanonicalIdentityTest.phpproving canonical keys use provider/resource identity or canonical discriminator and do not collapse same-label distinct resources. - T009 [P] [US1] Add unit coverage in
apps/platform/tests/Unit/Support/Resources/ProviderResourceDescriptorTest.phpfor descriptor serialization, source references, last-seen metadata, fingerprints, and fake-provider data. - T010 [US1] Implement
apps/platform/app/Support/Resources/ResourceIdentity.phpwith named constructors for provider resource, canonical built-in/default, virtual target, unsupported, and unknown identities. - T011 [US1] Extend
apps/platform/app/Support/Baselines/BaselineSubjectKey.phpwith canonical provider-resource key helpers rather than creating a parallelCanonicalSubjectKeyclass. - T012 [US1] Implement
apps/platform/app/Support/Resources/ProviderResourceDescriptor.phpas a small serializable descriptor overResourceIdentity. - T013 [US1] Run the focused identity unit tests for
ResourceIdentity,BaselineSubjectKeyCanonicalIdentity, andProviderResourceDescriptor.
Phase 3: Binding Persistence And Integrity
Purpose: Persist managed-environment-scoped binding decisions with active uniqueness and no duplicate active truth.
- T014 [P] [US2] Add PostgreSQL migration/index coverage in
apps/platform/tests/Feature/ProviderResources/ProviderResourceBindingPostgresTest.phpfor active partial unique index, composite(managed_environment_id, workspace_id)foreign key integrity, managed-environment non-null scope, enum/check-constraint validity where practical, and index-backed lookup assumptions. - T015 [P] [US2] Add feature coverage in
apps/platform/tests/Feature/ProviderResources/ProviderResourceBindingServiceTest.phpfor create, supersede, revoke, required note, single-active binding behavior, provider-default-as-canonical-built-in behavior, fake-provider service persistence, and every resolution mode listed inspec.md. - T016 [US2] Create
apps/platform/database/migrations/<timestamp>_create_provider_resource_bindings_table.phpwith non-nullworkspace_id, non-nullmanaged_environment_id, composite(managed_environment_id, workspace_id)foreign key tomanaged_environments(id, workspace_id), provider/subject/resource descriptor fields, binding status, resolution mode, source references, actor fields, timestamps, indexes, and a PostgreSQL partial unique index on active bindings. - T017 [US2] Implement
apps/platform/app/Support/Resources/ProviderResourceBindingStatus.phpwithactive,superseded, andrevoked. - T018 [US2] Implement
apps/platform/app/Support/Resources/ProviderResourceResolutionMode.phpwith the modes listed inspec.md. - T019 [US2] Implement
apps/platform/app/Models/ProviderResourceBinding.phpwith casts, relationships, active lookup scope,DerivesWorkspaceIdFromTenantor equivalent workspace-derivation invariant, and managed-environment/workspace helpers. - T020 [US2] Implement
apps/platform/database/factories/ProviderResourceBindingFactory.phpwith cheap defaults and explicit fake-provider/provider-resource states. - T021 [US2] Run the PostgreSQL binding migration/index test through
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/ProviderResources/ProviderResourceBindingPostgresTest.php.
Phase 4: Binding Service, RBAC, And Audit
Purpose: Make binding decisions safe, authorized, note-backed, and auditable.
- T022 [P] [US2] Add authorization coverage in
apps/platform/tests/Feature/ProviderResources/ProviderResourceBindingAuthorizationTest.phpfor allowed manager, read-only denial, missing capability 403, cross-workspace deny-as-not-found, and cross-managed-environment deny-as-not-found for records and source references. - T023 [P] [US2] Add audit assertions to
apps/platform/tests/Feature/ProviderResources/ProviderResourceBindingServiceTest.phpfor create, supersede, exclusion, accepted limitation, unsupported coverage, missing expected, revocation, old binding ID where applicable, new binding ID where applicable, resolution mode, safe source references, and redacted/safe operator note metadata. - T024 [US2] Implement
apps/platform/app/Policies/ProviderResourceBindingPolicy.phpusing existingworkspace_baselines.viewandworkspace_baselines.managecapability semantics unless the spec is updated first. - T025 [US2] Register the
ProviderResourceBindingPolicyinapps/platform/app/Providers/AuthServiceProvider.phpunless implementation updatesplan.mdwith a stronger adjacent provider-registration precedent first. - T026 [US2] Implement
apps/platform/app/Services/Resources/ProviderResourceBindingService.phpwith transactional methods for manual binding, exclusion, accepted limitation, unsupported coverage, missing expected, supersession, and revocation, including provider-connection/provider-key validation and scoped source-reference validation before persistence. - T027 [US2] Add stable audit action IDs for provider resource binding decisions in
apps/platform/app/Support/Audit/AuditActionId.php. - T028 [US2] Ensure service audit metadata excludes secrets, tokens, raw credentials, raw provider payloads, raw Graph response bodies, signed URLs, stack traces, raw sensitive JSON, and unchecked raw operator note text.
- T029 [US2] Run the binding service and authorization feature tests.
Phase 5: No-Op Runtime Regression
Purpose: Prove Spec 381 does not silently change current compare, evidence, review, or report behavior.
- T030 [P] [US3] Add no-op regression coverage in
apps/platform/tests/Feature/Baselines/BaselineCompareProviderResourceBindingNoOpTest.phpproving existing compare behavior does not automatically consume bindings in v1. - T031 [P] [US3] Add no-op regression coverage in
apps/platform/tests/Feature/Evidence/BaselineDriftPostureSourceTest.phpor a focused adjacent test proving existing evidence posture output is unchanged when bindings exist. - T032 [P] [US3] Add no-op regression coverage in
apps/platform/tests/Feature/ReviewPack/Spec349ReviewPackResolutionGuidanceTest.phpor a focused adjacent test proving review guidance/readiness does not treat accepted limitation as no-drift in v1. - T033 [US3] Run targeted existing baseline/evidence/review tests listed in
plan.md. - T034 [US3] Confirm the migration does not alter or backfill existing baseline snapshots, baseline snapshot items, inventory items, policy versions, operation runs, evidence snapshots, stored reports, or review packs.
- T035 [US3] Confirm no code path in current baseline compare, evidence readiness, review readiness, or review-pack publication automatically resolves subjects through
ProviderResourceBindingService; if implementation needs that, stop and prepare Spec 382/385 instead.
Phase 6: Final Validation And Artifact Hygiene
Purpose: Close implementation with bounded proof and no hidden scope.
- T036 Run
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Resources/ResourceIdentityTest.php tests/Unit/Support/Resources/ProviderResourceDescriptorTest.php tests/Unit/Support/Baselines/BaselineSubjectKeyCanonicalIdentityTest.php. - T037 Run
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderResources/ProviderResourceBindingServiceTest.php tests/Feature/ProviderResources/ProviderResourceBindingAuthorizationTest.php. - T038 Run
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/ProviderResources/ProviderResourceBindingPostgresTest.php. - T039 Run
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineCompareGapClassificationTest.php tests/Feature/Evidence/BaselineDriftPostureSourceTest.php tests/Feature/ReviewPack/Spec349ReviewPackResolutionGuidanceTest.php. - T040 Run
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent. - T041 Run
git diff --check. - T042 Scan changed files for secrets, tokens, raw credentials, raw provider payloads, raw Graph payloads, signed URLs, stack traces, SQL errors, and unnecessary customer-sensitive data.
- T043 Complete implementation close-out with Livewire v4 compliance, provider registration location, global-search status, high-impact action handling, asset strategy, validation commands, and deployment impact.
Non-Goals
- NT001 Do not add a Baseline Subject Resolution UI, Filament resource, route, navigation item, Livewire component, or Blade view.
- NT002 Do not implement baseline matching pipeline consumption, automatic Microsoft built-in mapping, or provider adapter canonicalization.
- NT003 Do not change evidence snapshot readiness, environment review readiness, review-pack publication, or customer-facing output.
- NT004 Do not add Graph calls, provider runtime calls, queued jobs, OperationRun types, terminal notifications, or scheduler behavior.
- NT005 Do not add workspace-level, baseline-profile-specific, or subject-only binding scopes in v1.
- NT006 Do not add an
is_activecolumn or other duplicate active-binding truth. - NT007 Do not rewrite completed Spec 163 or Spec 380 artifacts or remove their close-out/completed-task history.
Dependencies And Ordering
- Phase 1 must complete before code changes.
- Phase 2 identity primitives must exist before descriptors and binding service payloads depend on them.
- Phase 3 migration/model/enums must complete before the service persists decisions.
- Phase 4 policy/service/audit depends on Phase 3 persistence.
- Phase 5 no-op regression runs after bindings can exist.
- Phase 6 runs last.
Parallel Opportunities
- T007, T008, and T009 can run in parallel.
- T014 and T015 can run in parallel.
- T022 and T023 can run in parallel.
- T030, T031, and T032 can run in parallel.
- Final validation commands T036 through T039 may run in parallel if Sail resources allow.
Implementation Strategy
- Prove identity primitives first.
- Add persistence and PostgreSQL uniqueness.
- Add authorized/audited service mutations.
- Prove current compare/evidence/review behavior is unchanged.
- Run focused validation and stop before follow-up matching/UI/evidence scopes.