TenantAtlas/specs/137-platform-provider-identity/contracts/provider-identity.openapi.yaml
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

286 lines
8.3 KiB
YAML

openapi: 3.1.0
info:
title: TenantPilot Provider Identity Standardization Contract
version: 0.1.0
summary: Internal contract for platform-default Microsoft provider connection flows.
description: Logical internal action contract for existing authorized provider-connection surfaces. Operations may be implemented by existing Filament or Livewire action handlers and controller endpoints without introducing new standalone public routes, provided the documented authorization, confirmation, audit, and payload semantics are preserved.
servers:
- url: /admin
paths:
/tenants/{tenant}/provider-connections:
post:
summary: Create a provider connection for a tenant
description: Creates a platform connection by default. Dedicated mode requires explicit opt-in and stronger authorization.
parameters:
- in: path
name: tenant
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProviderConnectionCreateRequest'
responses:
'201':
description: Provider connection created
content:
application/json:
schema:
$ref: '#/components/schemas/ProviderConnectionResponse'
'403':
description: Member lacks the required capability
'404':
description: Workspace or tenant scope not accessible
/provider-connections/{connection}/admin-consent-link:
post:
summary: Generate canonical admin consent link
parameters:
- in: path
name: connection
required: true
schema:
type: integer
responses:
'200':
description: Consent link generated
content:
application/json:
schema:
$ref: '#/components/schemas/AdminConsentLinkResponse'
'403':
description: Member lacks the required capability
'404':
description: Connection not accessible in tenant scope
/consent/callback:
get:
summary: Handle Microsoft admin consent callback
parameters:
- in: query
name: state
required: false
schema:
type: string
- in: query
name: tenant
required: false
schema:
type: string
- in: query
name: admin_consent
required: false
schema:
type: boolean
- in: query
name: error
required: false
schema:
type: string
responses:
'200':
description: Consent callback rendered and connection updated
'403':
description: Invalid callback state
'404':
description: Tenant or workspace context unavailable
/provider-connections/{connection}/verification:
post:
summary: Start provider connection verification
parameters:
- in: path
name: connection
required: true
schema:
type: integer
responses:
'202':
description: Verification run queued or deduped
content:
application/json:
schema:
$ref: '#/components/schemas/VerificationStartResponse'
'403':
description: Member lacks the provider run capability
'404':
description: Tenant scope not accessible
/provider-connections/{connection}/connection-type:
put:
summary: Change the connection type explicitly
description: Switching to or from dedicated requires stronger authorization and confirmation.
parameters:
- in: path
name: connection
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- connection_type
properties:
connection_type:
type: string
enum: [platform, dedicated]
responses:
'200':
description: Connection type changed
content:
application/json:
schema:
$ref: '#/components/schemas/ProviderConnectionResponse'
'403':
description: Member lacks dedicated-management capability
'404':
description: Connection not accessible in tenant scope
/provider-connections/{connection}/dedicated-credential:
put:
summary: Create or rotate dedicated credential
parameters:
- in: path
name: connection
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DedicatedCredentialRequest'
responses:
'200':
description: Dedicated credential stored or rotated
'403':
description: Member lacks dedicated-management capability
'404':
description: Connection not accessible in tenant scope
delete:
summary: Delete dedicated credential
description: Destructive operation that requires stronger authorization and confirmation.
parameters:
- in: path
name: connection
required: true
schema:
type: integer
responses:
'204':
description: Dedicated credential deleted
'403':
description: Member lacks dedicated-management capability
'404':
description: Connection not accessible in tenant scope
components:
schemas:
ProviderConnectionCreateRequest:
type: object
required:
- provider
- entra_tenant_id
- display_name
properties:
provider:
type: string
enum: [microsoft]
entra_tenant_id:
type: string
display_name:
type: string
is_default:
type: boolean
default: true
connection_type:
type: string
enum: [platform, dedicated]
default: platform
dedicated_credential:
$ref: '#/components/schemas/DedicatedCredentialRequest'
nullable: true
DedicatedCredentialRequest:
type: object
required:
- credential_kind
- client_id
- client_secret
properties:
credential_kind:
type: string
enum: [client_secret]
source:
type: string
enum: [dedicated_manual, dedicated_imported, legacy_migrated]
client_id:
type: string
client_secret:
type: string
writeOnly: true
ProviderConnectionResponse:
type: object
required:
- id
- provider
- entra_tenant_id
- display_name
- connection_type
- consent_status
- verification_status
- health_status
properties:
id:
type: integer
provider:
type: string
entra_tenant_id:
type: string
display_name:
type: string
connection_type:
type: string
enum: [platform, dedicated]
consent_status:
type: string
enum: [unknown, required, granted, failed, revoked]
verification_status:
type: string
enum: [unknown, pending, healthy, degraded, blocked, error]
health_status:
type: string
effective_app_id:
type: string
credential_source:
type: string
migration_review_required:
type: boolean
default: false
AdminConsentLinkResponse:
type: object
required:
- url
- client_id
- connection_type
properties:
url:
type: string
format: uri
client_id:
type: string
connection_type:
type: string
enum: [platform, dedicated]
VerificationStartResponse:
type: object
required:
- status
- operation_run_id
properties:
status:
type: string
enum: [started, deduped, scope_busy, blocked]
operation_run_id:
type: integer