TenantAtlas/specs/137-platform-provider-identity/tasks.md
ahmido bab01f07a9 feat: standardize platform provider identity (#166)
## Summary
- standardize Microsoft provider connections around explicit platform vs dedicated identity modes
- centralize admin-consent URL and runtime identity resolution so platform flows no longer fall back to tenant-local credentials
- add migration classification, richer consent and verification state handling, dedicated override management, and focused regression coverage

## Validation
- focused repo test coverage was added across provider identity, onboarding, audit, policy, guard, and migration flows
- latest explicit passing run in the workspace: `vendor/bin/sail artisan test --compact tests/Feature/AdminConsentCallbackTest.php tests/Feature/Audit/ProviderConnectionConsentAuditTest.php`

## Notes
- branch includes the full Spec 137 artifact set under `specs/137-platform-provider-identity/`
- target base branch: `dev`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #166
2026-03-13 16:29:08 +00:00

256 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 2s 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.