openapi: 3.0.3 info: title: TenantPilot Admin - Provider Connection Scope & Profile Contract (Conceptual) version: 0.1.0 description: | Conceptual shared-contract artifact for Spec 281. This package keeps the existing provider-connection persistence model and operator surfaces, but makes the shared provider-connection target-scope, identity-resolution, onboarding-summary, and operation-start context shape implementable without guessing at field ownership. These paths model logical surfaces and shared contracts, not a promise of new public route families. Public route ownership remains on the existing Filament resource and pages, with adjacent routing work deferred to Spec 280. servers: - url: /logical/provider-connections paths: /connections/{connection}/surface-summary: get: summary: Resolve the shared provider-connection summary contract parameters: - $ref: '#/components/parameters/ConnectionIdentifier' responses: '200': description: Shared provider-connection summary resolved content: application/json: schema: $ref: '#/components/schemas/ProviderConnectionSurfaceSummaryView' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' x-contract-rules: - Shared `target_scope` must use `ProviderTargetScope`. - Provider-specific Microsoft detail remains nested under provider context or profile metadata. /connections/{connection}/identity-resolution: get: summary: Resolve the shared provider identity-result contract parameters: - $ref: '#/components/parameters/ConnectionIdentifier' responses: '200': description: Provider identity resolved or blocked with a neutral shared contract content: application/json: schema: $ref: '#/components/schemas/ProviderIdentityResolutionView' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' x-contract-rules: - The shared contract centers on `target_scope`, effective client identity, credential source, and blocked reason. - Provider-specific authority or redirect detail stays nested in `provider_context`. /connections/{connection}/provider-profile: get: summary: Resolve provider-owned profile and contextual disclosure parameters: - $ref: '#/components/parameters/ConnectionIdentifier' responses: '200': description: Provider-owned profile disclosure resolved content: application/json: schema: $ref: '#/components/schemas/ProviderProfileDisclosureView' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' x-provider-owned: true /onboarding/provider-connections/{connection}/readiness: get: summary: Resolve the onboarding readiness summary for an existing provider connection parameters: - $ref: '#/components/parameters/ConnectionIdentifier' responses: '200': description: Onboarding readiness payload resolved content: application/json: schema: $ref: '#/components/schemas/OnboardingProviderConnectionReadinessView' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' x-contract-rules: - Onboarding must reuse the same `ProviderConnectionSurfaceSummaryView` contract as the provider-connections resource. /provider-operations/{operationType}/start: post: summary: Start or block a provider operation using neutral shared target-scope context parameters: - $ref: '#/components/parameters/OperationType' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ProviderOperationStartRequest' responses: '200': description: Existing active run reused or scope marked busy content: application/json: schema: $ref: '#/components/schemas/ProviderOperationStartResult' '202': description: New operation run queued content: application/json: schema: $ref: '#/components/schemas/ProviderOperationStartResult' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '422': description: Operation start blocked with a recorded run and neutral shared target-scope context content: application/json: schema: $ref: '#/components/schemas/ProviderOperationStartResult' x-contract-rules: - Shared run context must use `ProviderOperationRunContext.target_scope` instead of `target_scope.entra_tenant_id`. - Provider-specific detail needed for follow-up belongs in `provider_context.details`. components: parameters: ConnectionIdentifier: name: connection in: path required: true schema: type: integer OperationType: name: operationType in: path required: true schema: type: string responses: Forbidden: description: Actor is in scope but lacks the required provider capability. NotFound: description: Provider connection or managed-environment scope is not visible to the actor. schemas: ProviderTargetScope: type: object required: - provider - scope_kind - scope_identifier - scope_display_name - shared_label - shared_help_text properties: provider: type: string scope_kind: type: string enum: [tenant] scope_identifier: type: string scope_display_name: type: string shared_label: type: string shared_help_text: type: string ProviderContextDetail: type: object description: Extensible provider-owned detail item used for profile, consent, required-permissions, domain, portal, audit, or troubleshooting disclosure. required: - detail_key - detail_label - detail_value - visibility properties: detail_key: type: string description: Stable provider-owned detail key such as microsoft_tenant_id, authority_tenant, redirect_uri, admin_consent_url, required_permissions_url, portal_domain, or portal_link. detail_label: type: string detail_value: type: string visibility: type: string enum: [contextual_only, audit_only, troubleshooting_only] ProviderContext: type: object description: Provider-owned nested context wrapper reused by UI summaries, audit metadata, and provider-operation follow-up surfaces. required: - provider - details properties: provider: type: string details: type: array items: $ref: '#/components/schemas/ProviderContextDetail' EffectiveClientIdentity: type: object required: - credential_source properties: client_id: type: string nullable: true credential_source: type: string BlockedReason: type: object required: - reason_code properties: reason_code: type: string message: type: string nullable: true ProviderConnectionSurfaceSummaryView: type: object required: - provider - target_scope - consent_state - verification_state - readiness_summary - target_scope_summary - provider_context - is_enabled properties: provider: type: string target_scope: $ref: '#/components/schemas/ProviderTargetScope' consent_state: type: string verification_state: type: string readiness_summary: type: string target_scope_summary: type: string provider_context: $ref: '#/components/schemas/ProviderContext' contextual_identity_line: type: string nullable: true is_enabled: type: boolean ProviderIdentityResolutionView: type: object required: - resolved - connection_type - effective_client_identity - provider_context properties: resolved: type: boolean connection_type: type: string target_scope: allOf: - $ref: '#/components/schemas/ProviderTargetScope' nullable: true effective_client_identity: $ref: '#/components/schemas/EffectiveClientIdentity' blocked_reason: allOf: - $ref: '#/components/schemas/BlockedReason' nullable: true provider_context: $ref: '#/components/schemas/ProviderContext' ProviderProfileDisclosureView: type: object required: - provider - target_scope - provider_context properties: provider: type: string target_scope: $ref: '#/components/schemas/ProviderTargetScope' provider_context: $ref: '#/components/schemas/ProviderContext' PermissionOverview: type: object required: - overall - counts - freshness - missing_permissions properties: overall: type: string nullable: true counts: type: object additionalProperties: type: integer freshness: type: object required: [last_refreshed_at, is_stale] properties: last_refreshed_at: type: string nullable: true is_stale: type: boolean missing_permissions: type: object required: [application, delegated] properties: application: type: array items: type: string delegated: type: array items: type: string required_permissions_url: type: string nullable: true OnboardingProviderConnectionReadinessView: type: object required: - provider_connection_id - provider_summary - permission_overview properties: provider_connection_id: type: integer provider_summary: $ref: '#/components/schemas/ProviderConnectionSurfaceSummaryView' permission_overview: $ref: '#/components/schemas/PermissionOverview' ProviderBindingContext: type: object required: - provider - binding_status - handler_notes - exception_notes properties: provider: type: string binding_status: type: string handler_notes: type: string exception_notes: type: string ProviderOperationRunContext: type: object required: - provider - module - provider_binding - target_scope properties: execution_authority_mode: type: string nullable: true required_capability: type: string nullable: true provider: type: string module: type: string provider_binding: $ref: '#/components/schemas/ProviderBindingContext' provider_connection_id: type: integer nullable: true target_scope: $ref: '#/components/schemas/ProviderTargetScope' provider_context: allOf: - $ref: '#/components/schemas/ProviderContext' nullable: true OperationRunReference: type: object required: - id - type - status - context properties: id: type: integer type: type: string status: type: string outcome: type: string nullable: true context: $ref: '#/components/schemas/ProviderOperationRunContext' ProviderOperationStartRequest: type: object required: - managed_environment_id properties: managed_environment_id: type: integer provider_connection_id: type: integer nullable: true execution_authority_mode: type: string nullable: true extra_context: type: object additionalProperties: true ProviderOperationStartResult: type: object required: - result - run properties: result: type: string enum: [started, deduped, scope_busy, blocked] run: $ref: '#/components/schemas/OperationRunReference' blocked_reason: allOf: - $ref: '#/components/schemas/BlockedReason' nullable: true