## Summary - normalize provider-neutral target-scope and identity contracts across provider connection resolution, operation-start gating, verification reporting, and boundary configuration - align provider connection resource, onboarding, tenant summaries, and operation follow-up on the same shared scope contract while keeping Microsoft-specific profile details in provider-owned metadata - add Spec 281 artifacts and focused feature/browser coverage for the new provider-scope contract - move the tenant dashboard context-chip rail into Filament header widgets so the metadata row renders directly under the page subtitle ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php tests/Feature/Filament/ProviderConnectionResourceScopeSummaryTest.php tests/Feature/Onboarding/ManagedTenantOnboardingProviderConnectionScopeTest.php tests/Feature/Guards/ProviderConnectionMicrosoftScopeLeakGuardTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Dashboard/TenantDashboardProductizationSummaryTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - Filament remains on v5 with Livewire v4-compatible surfaces only. - Provider registration location is unchanged; Laravel 11+ providers stay in `apps/platform/bootstrap/providers.php`. - `ProviderConnectionResource` remains non-globally-searchable and still exposes View/Edit pages. - No new asset registration was added; deploy-time `filament:assets` expectations are unchanged. - No new destructive action path was introduced; existing server authorization and confirmation handling remain in place where applicable. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #339
13 KiB
Data Model: Provider Connection Scope & Microsoft Profile Extraction
Date: 2026-05-07
Branch: 281-provider-connection-scope
Overview
This slice introduces no new persistence. It keeps the existing provider-connection, credential, and run records intact and instead standardizes the derived runtime contracts that platform-core seams expose to UI, audit, and provider-operation flows.
Persisted Truth Unchanged
ProviderConnectionremains the workspace-owned, managed-environment-scoped binding record.ProviderCredentialremains the optional credential record attached to oneProviderConnection.OperationRunremains execution truth and keeps its current identity and lifecycle ownership.config/provider_boundaries.phpremains the single source for provider-owned versus platform-core seam classification.- No new table, registry, provider-profile entity, enum family, or taxonomy is introduced.
Derived Runtime Contracts
1. Provider Connection Record
Persistence: existing database row
Owner: ProviderConnection
| Field | Type | Required | Notes |
|---|---|---|---|
id |
int | yes | Existing record key |
workspace_id |
int | yes | Existing workspace boundary |
managed_environment_id |
int | yes | Existing managed-environment boundary; already the canonical scope anchor |
provider |
string | yes | Current provider key (microsoft today) |
display_name |
string | yes | Operator-visible connection label |
connection_type |
enum | yes | Existing platform or dedicated connection type |
is_default |
bool | yes | Existing default-binding flag |
is_enabled |
bool | yes | Existing enablement flag |
consent_status |
enum | yes | Existing consent state |
verification_status |
enum | yes | Existing verification state |
entra_tenant_id |
string | yes | Existing provider-owned persisted identifier; not the shared contract key after this slice |
metadata |
array | no | Existing legacy-identity and provider-owned metadata |
Rules:
managed_environment_idremains the persisted scope anchor; the stale candidate move is not reopened.entra_tenant_idmay remain a provider-owned stored value, but platform-core consumers must read the normalizedtarget_scopecontract instead of exposing this column name as shared truth.metadataremains derived/provider-owned detail and must not become a second canonical shared scope contract.
2. Shared Target Scope Descriptor
Persistence: derived
Owner: ProviderConnectionTargetScopeDescriptor
| Field | Type | Required | Notes |
|---|---|---|---|
provider |
string | yes | Shared provider key |
scope_kind |
string | yes | Current release supports tenant only |
scope_identifier |
string | yes | Neutral scope identifier used across platform-core seams |
scope_display_name |
string | yes | Operator-facing name for the scope |
shared_label |
string | yes | Current shared label, Target scope |
shared_help_text |
string | yes | Current shared help text |
Rules:
- This is the canonical shared
target_scopeobject for connection resolution, identity resolution, audit metadata, surface summaries, onboarding readiness, and provider-operation start context. - Shared
target_scopepayloads must not requireentra_tenant_idas a top-level key. scope_kindremains the currenttenantconstant; this slice does not add new scope-state machinery.
3. Provider Context
Persistence: derived
Owner: ProviderIdentityContextMetadata
| Field | Type | Required | Notes |
|---|---|---|---|
provider |
string | yes | Provider key for the disclosed context |
details |
list | yes | Ordered provider-owned detail items for profile, consent, audit, or troubleshooting disclosure |
Nested provider_context.details item
| Field | Type | Required | Notes |
|---|---|---|---|
detail_key |
string | yes | Stable provider-owned detail key such as microsoft_tenant_id, admin_consent_url, required_permissions_url, or portal_domain |
detail_label |
string | yes | Operator/support label |
detail_value |
string | yes | Current provider-owned value |
visibility |
string | yes | contextual_only, audit_only, or troubleshooting_only |
Rules:
provider_contextis the canonical nested provider-owned wrapper carried by shared identity, summary, onboarding, audit, and run-context contracts.- Current Microsoft details include
microsoft_tenant_id,authority_tenant,redirect_uri, consent links, required-permissions guidance, domains, and portal/profile links. - The detail set is intentionally provider-owned and extensible; this slice does not freeze provider context to a three-key catalog.
- These values may appear in nested provider profile/context blocks or audit metadata, but they do not replace the shared
target_scopedescriptor.
4. Provider Identity Resolution Contract
Persistence: derived
Owner: ProviderIdentityResolution
| Field | Type | Required | Notes |
|---|---|---|---|
resolved |
bool | yes | Shared resolved/blocked status |
connection_type |
string | yes | Existing connection-type truth |
target_scope |
object | no | Canonical shared target_scope descriptor |
effective_client_identity.client_id |
string | no | Neutral shared client identity when resolved |
effective_client_identity.credential_source |
string | yes | Shared credential source (platform_config, dedicated source, legacy source) |
blocked_reason.reason_code |
string | no | Existing provider reason code when blocked |
blocked_reason.message |
string | no | Operator-facing blocked reason message |
provider_context |
object | yes | Nested provider-owned context wrapper with provider and ordered details |
Rules:
- The shared contract center is
target_scope, effective client identity, credential source, and blocked reason. - Legacy
tenantContextis an implementation concern that should be absorbed into nested provider context or authority handling, not left as the primary shared contract field name. clientSecretremains runtime-only and is excluded from surface and audit contracts.- Blocked results still return
target_scopewhen it can be normalized, so surfaces keep one consistent summary even on failure.
5. Provider Connection Surface Summary
Persistence: derived
Owner: ProviderConnectionSurfaceSummary
| Field | Type | Required | Notes |
|---|---|---|---|
provider |
string | yes | Shared provider key |
target_scope |
object | yes | Canonical shared descriptor |
consent_state |
string | yes | Existing consent status value |
verification_state |
string | yes | Existing verification status value |
readiness_summary |
string | yes | Existing operator summary |
target_scope_summary |
string | yes | Shared rendered summary for UI surfaces |
provider_context |
object | yes | Nested provider-owned context wrapper with provider and ordered details |
contextual_identity_line |
string | no | Optional condensed display line derived from nested provider context |
is_enabled |
bool | yes | Existing enablement state for display logic |
Rules:
ProviderConnectionResource,ManagedTenantOnboardingWizard, and managed-environment related-context summaries must all reuse this contract.- Default-visible content remains summary-first: target scope, readiness, consent, and verification.
- Provider-specific detail is secondary and derived from nested provider context detail only.
- Invalid target scope falls back to an explicit review-needed summary instead of leaking raw provider fields back into shared UI.
6. Onboarding Provider-Connection Readiness View
Persistence: derived
Owner: ManagedTenantOnboardingWizard
| Field | Type | Required | Notes |
|---|---|---|---|
provider_connection_id |
int | yes | Selected or referenced connection |
provider_summary |
object | yes | Reused ProviderConnectionSurfaceSummary payload |
permission_overview |
object | yes | Existing required-permissions overview including nested provider-owned required_permissions_url guidance |
Rules:
- Onboarding must reuse the same
provider_summary.target_scopeandtarget_scope_summarycontract as the provider-connections resource. - Supporting verification and permission links remain secondary and stay nested under
permission_overview.required_permissions_urlor equivalent provider-owned guidance fields. - No onboarding-only target-scope wording or fallback structure is introduced.
7. Provider Operation Run Context
Persistence: derived run context in existing OperationRun rows
Owner: ProviderOperationStartGate
| Field | Type | Required | Notes |
|---|---|---|---|
execution_authority_mode |
string | yes | Existing execution-authority contract |
required_capability |
string | no | Existing capability contract |
provider |
string | yes | Shared provider key |
module |
string | yes | Existing provider-operation module |
provider_binding |
object | yes | Existing registry binding metadata |
provider_connection_id |
int | no | Existing binding identity when present |
target_scope |
object | yes | Canonical shared descriptor |
provider_context |
object | no | Nested provider-owned details when required for follow-up |
Rules:
- Started and blocked runs must use the same neutral shared
target_scopeschema. - Shared run context must stop writing
target_scope.entra_tenant_idas the primary contract. - Provider-specific fields needed for follow-up or troubleshooting move to nested
provider_contextor equivalent provider-owned metadata. - Current dedupe identity remains
provider_connection_idplus existing identity inputs; this slice does not redefine run identity semantics.
8. Credential Scope Validation Invariant
Persistence: derived runtime validation only
Owner: CredentialManager
| Field | Type | Required | Notes |
|---|---|---|---|
provider_connection_id |
int | yes | Existing credential owner |
payload.client_id |
string | yes | Existing credential field |
payload.client_secret |
string | yes | Existing credential field |
payload.scope_assertion |
mixed | no | Existing payload assertion if present today |
normalized_target_scope_identifier |
string | yes | Derived from canonical shared descriptor |
Rules:
- No provider-credential schema change is introduced.
- If a payload carries a scope assertion, validation should compare it to the normalized target-scope identifier rather than leaking raw provider-column names into the platform-core error contract.
- Neutral mismatch wording belongs in the shared seam; provider-specific values remain nested metadata only.
9. Provider Boundary Review Record
Persistence: config-driven
Owner: config/provider_boundaries.php
| Field | Type | Required | Notes |
|---|---|---|---|
seam_key |
string | yes | Boundary seam identifier |
owner |
string | yes | platform_core or provider_owned |
neutral_terms |
list | yes | Shared vocabulary allowed at the seam |
retained_provider_semantics |
list | yes | Documented provider-specific exceptions |
follow_up_action |
string | yes | Existing review follow-up rule |
Rules:
provider.connection_resolution,provider.identity_resolution, andprovider.operation_start_gateremain platform-core seams and must carry only the documented provider-specific exceptions.provider.gateway_runtimeremains provider-owned.config/provider_boundaries.phpstays the single review record for this classification; the slice does not create a new taxonomy.
Contract Flow
ProviderConnectionis loaded inside its current workspace plus managed-environment scope.ProviderConnectionTargetScopeNormalizerderives the canonical sharedtarget_scopedescriptor and the nestedprovider_contextwrapper.ProviderConnectionResolvervalidates enablement, consent, and supported binding using the normalizedtarget_scopecontract.ProviderIdentityResolveremits oneProviderIdentityResolutionresult centered on target scope, effective client identity, and nested provider context.ProviderConnectionSurfaceSummaryrenders the same summary contract for the provider-connections resource, onboarding, and related-context surfaces.ProviderOperationStartGaterecords the same neutraltarget_scopecontract intoOperationRuncontext while nesting any provider-only detail under provider context.- Provider-owned consumers such as admin-consent URL shaping and Graph runtime mapping read the nested provider context they need without re-promoting those values into shared platform-core vocabulary.
Deferred Boundaries
- No new provider implementation is introduced.
- No provider-profile table, registry, package engine, or artifact taxonomy is introduced.
- No routing work from Spec
280is absorbed. - No RBAC redesign, copy-neutralization, or cutover quality-gate work from Specs
282through287is introduced.