# Tasks: Platform Provider Identity Standardization **Input**: Design documents from `/specs/137-platform-provider-identity/` **Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `quickstart.md`, `contracts/provider-identity.openapi.yaml` **Tests**: Tests are REQUIRED for this feature because it changes runtime provider resolution, onboarding behavior, consent handling, authorization, and migration safeguards. **Operations**: Existing verification and provider-operation flows already create `OperationRun` records. Tasks below preserve that model and extend blocker handling and reporting without introducing a new operations surface. **RBAC**: This feature changes authorization around dedicated override and credential lifecycle management, so tasks include capability-registry changes, policy enforcement, confirmation requirements, and positive and negative authorization tests. **UI Naming**: Tasks include alignment for operator-facing labels such as `Platform connection`, `Dedicated connection`, `Grant admin consent`, and `Run verification again`. **Filament UI Action Surfaces**: This feature modifies Filament resources and onboarding pages, so tasks include action-surface updates, confirmation requirements, audit logging, and layout consistency work. **Badges**: Tasks include centralized badge updates for new consent and verification semantics. **Organization**: Tasks are grouped by user story so each story can be implemented and validated independently once foundational work is complete. ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Establish shared constants, capabilities, and test fixtures that the rest of the feature depends on. - [X] T001 [P] Add provider identity state constants and value objects in `app/Support/Providers/ProviderConnectionType.php`, `app/Support/Providers/ProviderConsentStatus.php`, `app/Support/Providers/ProviderVerificationStatus.php`, `app/Support/Providers/ProviderCredentialSource.php`, and `app/Support/Providers/ProviderCredentialKind.php` - [X] T002 [P] Add dedicated-management capability registry entries in `app/Support/Auth/Capabilities.php`, `app/Services/Auth/RoleCapabilityMap.php`, and `app/Services/Auth/WorkspaceRoleCapabilityMap.php` - [X] T003 [P] Update provider factories and shared test helpers for platform and dedicated defaults in `database/factories/ProviderConnectionFactory.php`, `database/factories/ProviderCredentialFactory.php`, and `tests/Pest.php` --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Build the schema and core resolver infrastructure required before any user story work can start. **⚠️ CRITICAL**: No user story work can begin until this phase is complete. - [X] T004 Add provider identity state and migration-review fields to `provider_connections` in `database/migrations/2026_03_13_000001_add_provider_identity_fields_to_provider_connections.php` and dedicated credential lifecycle metadata to `provider_credentials` in `database/migrations/2026_03_13_000002_add_dedicated_metadata_to_provider_credentials.php` - [X] T005 [P] Update provider connection and credential model casts for new identity fields in `app/Models/ProviderConnection.php` and `app/Models/ProviderCredential.php` - [X] T006 [P] Create the central platform identity resolver in `app/Services/Providers/PlatformProviderIdentityResolver.php` - [X] T007 [P] Create the connection-type-aware identity resolver in `app/Services/Providers/ProviderIdentityResolver.php` - [X] T008 [P] Create the canonical consent URL factory and state projector in `app/Services/Providers/AdminConsentUrlFactory.php` and `app/Services/Providers/ProviderConnectionStateProjector.php` - [X] T009 [P] Create the migration classifier for legacy provider connections in `app/Services/Providers/ProviderConnectionClassifier.php` - [X] T010 [P] Extend shared provider reason codes and connection status semantics in `app/Support/Providers/ProviderReasonCodes.php` and `app/Support/Badges/BadgeCatalog.php` **Checkpoint**: Foundation ready. User stories can now proceed. --- ## Phase 3: User Story 1 - Self-service platform onboarding (Priority: P1) 🎯 MVP **Goal**: Deliver a standard Microsoft onboarding flow that creates a platform connection by default, does not collect app credentials, and sends consent through the canonical platform app identity. **Independent Test**: Start a new Microsoft connection from the onboarding wizard, confirm the UI shows the platform app ID read-only with no client credential inputs, complete the consent callback, and verify that the created connection is `platform` without a `provider_credentials` row. ### Tests for User Story 1 - [X] T011 [P] [US1] Add platform-default onboarding feature coverage in `tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php` - [X] T012 [P] [US1] Add admin consent callback platform-state coverage in `tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php` ### Implementation for User Story 1 - [X] T013 [US1] Default new provider connections to platform mode in `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` and `app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php` - [X] T014 [US1] Remove standard client credential entry and show platform app metadata in `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` - [X] T015 [US1] Update provider connection create and detail schemas for platform-default UX in `app/Filament/Resources/ProviderConnectionResource.php` and `app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` - [X] T016 [US1] Route onboarding consent start through the canonical factory in `app/Http/Controllers/TenantOnboardingController.php` and `app/Support/Links/RequiredPermissionsLinks.php` - [X] T017 [US1] Persist explicit platform consent defaults and callback state transitions in `app/Http/Controllers/AdminConsentCallbackController.php` and `resources/views/admin-consent-callback.blade.php` - [X] T018 [US1] Update tenant-side consent entry points and next-step links to use platform terminology in `app/Filament/Resources/TenantResource.php` and `app/Support/Providers/ProviderNextStepsRegistry.php` - [X] T019 [US1] Add audited consent start and consent result events with required payload fields in `app/Http/Controllers/TenantOnboardingController.php`, `app/Http/Controllers/AdminConsentCallbackController.php`, and `tests/Feature/Audit/ProviderConnectionConsentAuditTest.php` **Checkpoint**: User Story 1 is complete when standard onboarding creates a `platform` connection, shows no manual credential inputs, and drives consent through the canonical platform identity. --- ## Phase 4: User Story 2 - Runtime and consent stay on one identity (Priority: P1) **Goal**: Ensure platform consent generation and runtime Graph resolution use the same central identity and never fall back silently to tenant-local or dedicated credentials. **Independent Test**: Generate a consent URL for a platform connection, complete the callback, run verification, and assert that all runtime graph options resolve from the platform identity while tenant-local and dedicated credential fallbacks are blocked. ### Tests for User Story 2 - [X] T020 [P] [US2] Add canonical consent URL unit coverage in `tests/Unit/Providers/AdminConsentUrlFactoryTest.php` and update `tests/Unit/TenantResourceConsentUrlTest.php` - [X] T021 [P] [US2] Add platform-versus-dedicated runtime resolver coverage in `tests/Unit/Providers/PlatformProviderIdentityResolverTest.php`, `tests/Unit/Providers/ProviderIdentityResolverTest.php`, `tests/Unit/Providers/CredentialManagerTest.php`, and `tests/Unit/Providers/ProviderGatewayTest.php` - [X] T022 [P] [US2] Add no-fallback architectural guard coverage in `tests/Feature/Guards/NoPlatformCredentialFallbackTest.php` - [X] T023 [P] [US2] Add verification-result and consent-revocation audit coverage with payload assertions in `tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php` and `tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php` ### Implementation for User Story 2 - [X] T024 [US2] Refactor credential selection to branch strictly on `connection_type` in `app/Services/Providers/CredentialManager.php` and `app/Services/Providers/ProviderIdentityResolver.php` - [X] T025 [US2] Refactor Graph option construction to use resolved platform identity in `app/Services/Providers/ProviderGateway.php` and `app/Services/Providers/MicrosoftGraphOptionsResolver.php` - [X] T026 [US2] Separate consent blockers from credential blockers in `app/Services/Providers/ProviderConnectionResolver.php` and `app/Support/Providers/ProviderReasonCodes.php` - [X] T027 [US2] Replace legacy consent URL builders with `AdminConsentUrlFactory` in `app/Filament/Resources/TenantResource.php` and `app/Support/Links/RequiredPermissionsLinks.php` - [X] T028 [US2] Update verification and provider-operation start flows to consume resolved identity state and emit auditable verification-result and consent-revocation outcomes in `app/Jobs/ProviderConnectionHealthCheckJob.php`, `app/Services/Verification/StartVerification.php`, and `app/Services/Providers/ProviderConnectionStateProjector.php` - [X] T029 [US2] Cut over downstream Microsoft consumers to provider identity resolution in `app/Services/Intune/RbacOnboardingService.php`, `app/Services/Intune/RbacHealthService.php`, `app/Services/Intune/TenantConfigService.php`, `app/Services/Intune/PolicySyncService.php`, `app/Services/Intune/PolicySnapshotService.php`, `app/Services/Intune/RestoreService.php`, `app/Services/Inventory/InventorySyncService.php`, and `app/Services/Graph/ScopeTagResolver.php` - [X] T030 [US2] Update verification reports and remediation messaging for platform and dedicated reason codes in `app/Support/Verification/BlockedVerificationReportFactory.php`, `app/Support/Verification/TenantPermissionCheckClusters.php`, and `app/Support/Verification/VerificationReportSanitizer.php` **Checkpoint**: User Story 2 is complete when platform consent and runtime use the same effective app identity and no silent fallback path remains. --- ## Phase 5: User Story 3 - Dedicated stays explicit and protected (Priority: P2) **Goal**: Keep dedicated connections available only through an explicit, strongly authorized override path with audited and confirmed credential lifecycle actions. **Independent Test**: Verify that unauthorized users cannot access dedicated override or credential management, while authorized users can explicitly enable dedicated mode, manage dedicated credentials, and run verification against that dedicated identity only. ### Tests for User Story 3 - [X] T031 [P] [US3] Add dedicated override authorization coverage in `tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php` and `tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php` - [X] T032 [P] [US3] Add dedicated onboarding and inline-edit Livewire coverage in `tests/Feature/ManagedTenantOnboardingWizardTest.php` and `tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php` ### Implementation for User Story 3 - [X] T033 [US3] Enforce a distinct dedicated-management capability boundary in `app/Support/Auth/Capabilities.php`, `app/Services/Auth/RoleCapabilityMap.php`, `app/Services/Auth/WorkspaceRoleCapabilityMap.php`, and `app/Policies/ProviderConnectionPolicy.php` - [X] T034 [US3] Add connection-type and dedicated credential actions that satisfy the internal action contract through existing authorized Filament or Livewire surfaces, with confirmation and grouped actions, in `app/Filament/Resources/ProviderConnectionResource.php` - [X] T035 [US3] Update provider connection edit and view pages for dedicated-only credential management, including delete support, in `app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` and `app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` - [X] T036 [US3] Gate dedicated override UI and inline-edit paths in `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` - [X] T037 [US3] Add audited connection-type and dedicated credential lifecycle logging in `app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php`, `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, and `app/Observers/ProviderCredentialObserver.php` - [X] T038 [US3] Align provider connection empty states, labels, and helper copy to platform-versus-dedicated vocabulary in `app/Filament/Resources/ProviderConnectionResource.php` and `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` **Checkpoint**: User Story 3 is complete when dedicated mode is explicit, audited, confirmed for destructive actions, and unavailable without the stronger capability. --- ## Phase 6: User Story 4 - Existing hybrid tenants are migrated safely (Priority: P2) **Goal**: Classify existing provider connections into platform, dedicated, or review-required outcomes without silent hybrid conversion. **Independent Test**: Run the classifier against representative platform-like, dedicated, and contradictory legacy records and confirm each record receives the expected classification, audit trail, and review-required handling. **Execution Rule**: T042 and T043 are post-deploy operational tasks. They must not be embedded in schema migrations or hidden inside deploy-time migration side effects. ### Tests for User Story 4 - [X] T039 [P] [US4] Add migration classifier unit coverage in `tests/Unit/Providers/ProviderConnectionClassifierTest.php` - [X] T040 [P] [US4] Add migration and legacy-source regression coverage in `tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php` and `tests/Feature/Guards/NoLegacyTenantProviderFallbackTest.php` ### Implementation for User Story 4 - [X] T041 [US4] Implement review-required classification metadata and result projection in `app/Services/Providers/ProviderConnectionClassifier.php` and `app/Models/ProviderConnection.php` - [X] T042 [US4] Add an explicit provider connection classification command for post-deploy execution in `app/Console/Commands/ClassifyProviderConnections.php` - [X] T043 [US4] Add audited post-migration classification backfill orchestration in `app/Console/Commands/ClassifyProviderConnections.php` and `tests/Feature/Audit/ProviderConnectionMigrationAuditTest.php` - [X] T044 [US4] Block new standard reads and writes to legacy tenant app credential fields in `app/Models/Tenant.php`, `app/Filament/Resources/TenantResource.php`, and `app/Http/Controllers/TenantOnboardingController.php` - [X] T045 [US4] Surface migration review state and effective app metadata in `app/Filament/Resources/ProviderConnectionResource.php` and `app/Support/Providers/ProviderNextStepsRegistry.php` **Checkpoint**: User Story 4 is complete when existing records can be classified safely and contradictory legacy configurations are visible instead of silently normalized. --- ## Phase 7: Polish & Cross-Cutting Concerns **Purpose**: Finish centralized status rendering, audit regression coverage, and final validation across the completed stories. - [X] T046 [P] Update centralized provider badge mappings for new consent and verification semantics in `app/Support/Badges/BadgeCatalog.php`, `app/Support/Badges/Domains/ProviderConnectionStatusBadge.php`, `app/Support/Badges/Domains/ProviderConnectionHealthBadge.php`, and `app/Support/Badges/Domains/ManagedTenantOnboardingVerificationStatusBadge.php` - [X] T047 [P] Add consolidated audit payload and badge regression coverage in `tests/Feature/Audit/ProviderConnectionIdentityAuditTest.php` and `tests/Unit/Providers/ProviderConnectionBadgeMappingTest.php` - [X] T048 Validate the focused quickstart scenarios and targeted suites from `specs/137-platform-provider-identity/quickstart.md` using `tests/Unit/Providers`, `tests/Feature/Onboarding`, `tests/Feature/ProviderConnections`, and `tests/Feature/Guards` as a validation-only quality gate - [X] T049 Run formatting and final cleanup with `vendor/bin/sail bin pint --dirty --format agent` and verify `specs/137-platform-provider-identity/quickstart.md` --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: No dependencies; can start immediately. - **Foundational (Phase 2)**: Depends on Setup completion and blocks all user stories. - **User Story 1 (Phase 3)**: Depends on Foundational completion. - **User Story 2 (Phase 4)**: Depends on Foundational completion; can run in parallel with User Story 1 if staffed, but is recommended immediately after or alongside US1 because verification uses the shared identity resolver. - **User Story 3 (Phase 5)**: Depends on Foundational completion and benefits from User Story 2’s resolver cutover. - **User Story 4 (Phase 6)**: Depends on Foundational completion and should land after the new runtime rules are defined so classification matches the final model. - **Polish (Phase 7)**: Depends on the desired user stories being complete. ### User Story Dependencies - **US1**: Independent after Foundational; delivers the platform-default onboarding path. - **US2**: Independent after Foundational; delivers central identity parity and fallback removal. - **US3**: Independent after Foundational but assumes the new `connection_type` model and resolver behavior exist. - **US4**: Independent after Foundational but should be applied after the target model is stable. ### Within Each User Story - Write tests first and confirm they fail before implementation. - Land state or contract updates before UI and downstream integrations. - Complete the story-specific authorization and audit work before marking the story done. - Preserve the internal action-contract interpretation during implementation: prefer existing authorized surfaces over adding new standalone routes unless a documented gap requires one. ### Parallel Opportunities - T001-T003 can run in parallel. - T005-T010 can run in parallel once T004 is defined. - Within each user story, test tasks marked `[P]` can run in parallel. - US1 and US2 can be developed in parallel after Phase 2 if different engineers own onboarding versus runtime cutover. - US3 and US4 can also proceed in parallel once the core identity model is stable, but T042-T043 must remain post-deploy operational work rather than schema-migration work. --- ## Parallel Example: User Story 1 ```bash # Write the two US1 tests together: T011 Add platform-default onboarding feature coverage in tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php T012 Add admin consent callback platform-state coverage in tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php # Then split the UX and callback implementation work: T014 Remove standard client credential entry and show platform app metadata in app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php T017 Persist explicit platform consent defaults and callback state transitions in app/Http/Controllers/AdminConsentCallbackController.php and resources/views/admin-consent-callback.blade.php ``` ## Parallel Example: User Story 2 ```bash # Resolver and guard tests can be written in parallel: T020 Add canonical consent URL unit coverage in tests/Unit/Providers/AdminConsentUrlFactoryTest.php and tests/Unit/TenantResourceConsentUrlTest.php T021 Add platform-versus-dedicated runtime resolver coverage in tests/Unit/Providers/PlatformProviderIdentityResolverTest.php and related unit files T022 Add no-fallback architectural guard coverage in tests/Feature/Guards/NoPlatformCredentialFallbackTest.php T023 Add verification-result and consent-revocation audit coverage in tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php and tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php # Runtime refactors can then be split by layer: T024 Refactor credential selection in app/Services/Providers/CredentialManager.php and app/Services/Providers/ProviderIdentityResolver.php T029 Cut over downstream Microsoft consumers in app/Services/Intune/*, app/Services/Inventory/InventorySyncService.php, and app/Services/Graph/ScopeTagResolver.php ``` ## Parallel Example: User Story 3 ```bash # Authorization and Livewire tests can be built together: T031 Add dedicated override authorization coverage in tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php and tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php T032 Add dedicated onboarding and inline-edit Livewire coverage in tests/Feature/ManagedTenantOnboardingWizardTest.php and tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php # UI and policy work can then proceed in parallel: T033 Enforce a distinct dedicated-management capability boundary in app/Support/Auth/Capabilities.php and related capability maps T035 Update provider connection edit and view pages for dedicated-only credential management in app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php and app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php ``` ## Parallel Example: User Story 4 ```bash # Classification tests can be written in parallel: T039 Add migration classifier unit coverage in tests/Unit/Providers/ProviderConnectionClassifierTest.php T040 Add migration and legacy-source regression coverage in tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php and tests/Feature/Guards/NoLegacyTenantProviderFallbackTest.php # Then split classifier and UI follow-up work: T041 Implement review-required classification metadata in app/Services/Providers/ProviderConnectionClassifier.php and app/Models/ProviderConnection.php T045 Surface migration review state and effective app metadata in app/Filament/Resources/ProviderConnectionResource.php and app/Support/Providers/ProviderNextStepsRegistry.php ``` --- ## Implementation Strategy ### MVP First Deliver **Setup + Foundational + User Story 1** first to expose a platform-default onboarding flow that no longer asks for credentials. ### Identity Integrity Second Land **User Story 2** immediately after or in parallel so the new onboarding flow and runtime provider operations share the same identity rules before broad rollout. ### Enterprise Override and Migration Last Finish with **User Story 3** and **User Story 4** to preserve the dedicated exception path and classify legacy tenants safely without weakening the new default model.