TenantAtlas/specs/202-governance-subject-taxonomy/contracts/governance-subject-taxonomy.logical.openapi.yaml

618 lines
19 KiB
YAML

openapi: 3.1.0
info:
title: Governance Subject Taxonomy and Baseline Scope V2 Internal Contract
version: 0.1.0
summary: Internal logical contract for canonical baseline scope, taxonomy listing, save-forward writes, and normalized baseline operation starts
description: |
This contract is an internal planning artifact for Spec 202. The affected
surfaces still render through Filament and Livewire, and baseline capture or
compare continues to run through the existing Laravel services and jobs. The
schemas below define the canonical baseline scope document, the governance
subject taxonomy registry, legacy normalization behavior, and the effective
scope that capture and compare must consume. The path entries below are
logical boundary identifiers for existing Filament, Livewire, and service
entry points only; they do not imply new HTTP controllers or routes.
x-logical-artifact: true
x-governance-subject-taxonomy-consumers:
- surface: baseline.profile.form
sourceFiles:
- apps/platform/app/Filament/Resources/BaselineProfileResource.php
- apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/CreateBaselineProfile.php
- apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/EditBaselineProfile.php
mustRender:
- normalized_scope_summary
- active_subject_groups
- support_readiness
- invalid_scope_feedback
mustAccept:
- legacy_scope_input
- canonical_scope_v2
- surface: baseline.profile.detail
sourceFiles:
- apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
mustRender:
- canonical_scope_summary
- support_readiness
- normalization_lineage_on_demand
- surface: baseline.scope.backfill.command
sourceFiles:
- apps/platform/app/Console/Commands/BackfillBaselineScopeV2.php
mustAccept:
- preview_mode_by_default
- explicit_write_confirmation
mustProduce:
- candidate_rewrite_summary
- committed_rewrite_summary
- committed_write_audit_logging
- surface: baseline.capture.start
sourceFiles:
- apps/platform/app/Services/Baselines/BaselineCaptureService.php
mustConsume:
- effective_scope_v2
- capture_eligible_subject_types
- compatibility_projection_if_needed
- surface: baseline.compare.start
sourceFiles:
- apps/platform/app/Services/Baselines/BaselineCompareService.php
mustConsume:
- effective_scope_v2
- compare_eligible_subject_types
- compatibility_projection_if_needed
paths:
/internal/workspaces/{workspace}/governance-subject-taxonomy/baseline-subject-types:
get:
summary: List active baseline-selectable governance subject types for the current workspace context
operationId: listBaselineSubjectTypes
parameters:
- name: workspace
in: path
required: true
schema:
type: integer
responses:
'200':
description: Grouped taxonomy metadata for baseline scope selection and validation
content:
application/vnd.tenantpilot.governance-taxonomy+json:
schema:
$ref: '#/components/schemas/GovernanceSubjectTaxonomyRegistry'
'403':
description: Actor is in scope but lacks workspace baseline view capability
'404':
description: Workspace is outside actor scope
/internal/workspaces/{workspace}/baseline-scope/normalize:
post:
summary: Normalize legacy or canonical scope input into Baseline Scope V2
operationId: normalizeBaselineScope
parameters:
- name: workspace
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LegacyOrV2ScopeInput'
responses:
'200':
description: Canonical V2 scope plus summary and validation detail
content:
application/vnd.tenantpilot.baseline-scope-normalized+json:
schema:
$ref: '#/components/schemas/BaselineScopeNormalizationResult'
'422':
description: Scope input is invalid or ambiguous after normalization
content:
application/vnd.tenantpilot.baseline-scope-errors+json:
schema:
$ref: '#/components/schemas/BaselineScopeValidationErrors'
'403':
description: Actor is in scope but lacks workspace baseline manage capability
'404':
description: Workspace is outside actor scope
/internal/workspaces/{workspace}/baseline-scope/backfill:
post:
summary: Logical maintenance boundary for previewing or committing baseline profile scope backfill
operationId: backfillBaselineProfileScopeV2
description: Logical-only maintenance contract for `baseline_profiles.scope_jsonb`; compare assignment overrides remain tolerant-read only in this release.
parameters:
- name: workspace
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BaselineScopeBackfillRequest'
responses:
'200':
description: Preview or commit summary for the baseline profile scope backfill command
content:
application/vnd.tenantpilot.baseline-scope-backfill+json:
schema:
$ref: '#/components/schemas/BaselineScopeBackfillResult'
'403':
description: Actor is in scope but lacks workspace baseline manage capability
'404':
description: Workspace is outside actor scope
/admin/baseline-profiles:
post:
summary: Create a baseline profile using a scope request that is canonicalized to V2 before persistence
operationId: createBaselineProfileWithCanonicalScope
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BaselineProfileWriteRequest'
responses:
'201':
description: Baseline profile created with canonical V2 scope persisted
content:
application/vnd.tenantpilot.baseline-profile+json:
schema:
$ref: '#/components/schemas/BaselineProfileScopeEnvelope'
'422':
description: Scope validation failed
'403':
description: Actor is in scope but lacks workspace baseline manage capability
'404':
description: Workspace is outside actor scope
/admin/baseline-profiles/{profile}:
patch:
summary: Update a baseline profile and save scope forward as canonical V2
operationId: updateBaselineProfileWithCanonicalScope
parameters:
- name: profile
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BaselineProfileWriteRequest'
responses:
'200':
description: Baseline profile updated with canonical V2 scope persisted
content:
application/vnd.tenantpilot.baseline-profile+json:
schema:
$ref: '#/components/schemas/BaselineProfileScopeEnvelope'
'422':
description: Scope validation failed
'403':
description: Actor is in scope but lacks workspace baseline manage capability
'404':
description: Workspace or baseline profile is outside actor scope
/internal/tenants/{tenant}/baseline-profiles/{profile}/capture:
post:
summary: Start baseline capture using normalized effective scope
operationId: startBaselineCaptureWithNormalizedScope
parameters:
- name: tenant
in: path
required: true
schema:
type: integer
- name: profile
in: path
required: true
schema:
type: integer
responses:
'202':
description: Baseline capture accepted with canonical effective scope recorded in operation context
content:
application/vnd.tenantpilot.baseline-operation+json:
schema:
$ref: '#/components/schemas/BaselineOperationEnvelope'
'422':
description: Requested scope is invalid or includes unsupported capture subject types
'403':
description: Actor is in scope but lacks capability to start capture
'404':
description: Tenant or profile is outside actor scope
/internal/tenants/{tenant}/baseline-profiles/{profile}/compare:
post:
summary: Start baseline compare using normalized effective scope
operationId: startBaselineCompareWithNormalizedScope
parameters:
- name: tenant
in: path
required: true
schema:
type: integer
- name: profile
in: path
required: true
schema:
type: integer
responses:
'202':
description: Baseline compare accepted with canonical effective scope recorded in operation context
content:
application/vnd.tenantpilot.baseline-operation+json:
schema:
$ref: '#/components/schemas/BaselineOperationEnvelope'
'422':
description: Requested scope is invalid or includes unsupported compare subject types
'403':
description: Actor is in scope but lacks capability to start compare
'404':
description: Tenant or profile is outside actor scope
components:
schemas:
GovernanceDomainKey:
type: string
description: Current active values are `intune` and `platform_foundation`; additional domain keys may be introduced later without changing the V2 contract shape.
examples:
- intune
- platform_foundation
- entra
GovernanceSubjectClass:
type: string
enum:
- policy
- configuration_resource
- posture_dimension
- control
GovernanceSubjectType:
type: object
additionalProperties: false
required:
- domain_key
- subject_class
- subject_type_key
- label
- description
- capture_supported
- compare_supported
- inventory_supported
- active
properties:
domain_key:
$ref: '#/components/schemas/GovernanceDomainKey'
subject_class:
$ref: '#/components/schemas/GovernanceSubjectClass'
subject_type_key:
type: string
label:
type: string
description:
type:
- string
- 'null'
capture_supported:
type: boolean
compare_supported:
type: boolean
inventory_supported:
type: boolean
active:
type: boolean
support_mode:
type:
- string
- 'null'
legacy_bucket:
type:
- string
- 'null'
GovernanceSubjectTaxonomyRegistry:
type: object
additionalProperties: false
required:
- subject_types
properties:
subject_types:
type: array
items:
$ref: '#/components/schemas/GovernanceSubjectType'
LegacyBaselineScopePayload:
type: object
additionalProperties: false
minProperties: 1
properties:
policy_types:
type: array
description: Empty or omitted means all supported Intune policy subject types when the other legacy bucket is present.
items:
type: string
foundation_types:
type: array
description: Empty or omitted means no foundation subject types when the other legacy bucket is present.
items:
type: string
BaselineScopeEntryV2:
type: object
additionalProperties: false
required:
- domain_key
- subject_class
- subject_type_keys
properties:
domain_key:
$ref: '#/components/schemas/GovernanceDomainKey'
subject_class:
$ref: '#/components/schemas/GovernanceSubjectClass'
subject_type_keys:
type: array
minItems: 1
items:
type: string
filters:
type: object
additionalProperties: true
default: {}
BaselineScopeDocumentV2:
type: object
additionalProperties: false
required:
- version
- entries
properties:
version:
type: integer
enum:
- 2
entries:
type: array
minItems: 1
items:
$ref: '#/components/schemas/BaselineScopeEntryV2'
LegacyOrV2ScopeInput:
oneOf:
- $ref: '#/components/schemas/LegacyBaselineScopePayload'
- $ref: '#/components/schemas/BaselineScopeDocumentV2'
BaselineScopeSummaryGroup:
type: object
additionalProperties: false
required:
- domain_key
- subject_class
- group_label
- selected_subject_types
- capture_supported_count
- compare_supported_count
properties:
domain_key:
$ref: '#/components/schemas/GovernanceDomainKey'
subject_class:
$ref: '#/components/schemas/GovernanceSubjectClass'
group_label:
type: string
selected_subject_types:
description: Operator-facing selected subject labels for the group, not raw subject type keys.
type: array
items:
type: string
capture_supported_count:
type: integer
compare_supported_count:
type: integer
inactive_count:
type: integer
BaselineScopeNormalizationResult:
type: object
additionalProperties: false
required:
- canonical_scope
- normalization_lineage
- summary
properties:
canonical_scope:
$ref: '#/components/schemas/BaselineScopeDocumentV2'
normalization_lineage:
$ref: '#/components/schemas/BaselineScopeNormalizationLineage'
summary:
type: array
items:
$ref: '#/components/schemas/BaselineScopeSummaryGroup'
legacy_projection:
type:
- object
- 'null'
additionalProperties:
type: array
items:
type: string
BaselineScopeValidationError:
type: object
additionalProperties: false
required:
- code
- message
properties:
code:
type: string
message:
type: string
path:
type:
- string
- 'null'
BaselineScopeValidationErrors:
type: object
additionalProperties: false
required:
- errors
properties:
errors:
type: array
items:
$ref: '#/components/schemas/BaselineScopeValidationError'
BaselineProfileWriteRequest:
type: object
additionalProperties: false
required:
- name
- status
- capture_mode
- requested_scope
properties:
name:
type: string
description:
type:
- string
- 'null'
status:
type: string
capture_mode:
type: string
version_label:
type:
- string
- 'null'
requested_scope:
$ref: '#/components/schemas/LegacyOrV2ScopeInput'
BaselineProfileScopeEnvelope:
type: object
additionalProperties: false
required:
- profile_id
- persisted_scope
- normalization_lineage
- summary
properties:
profile_id:
type: integer
persisted_scope:
$ref: '#/components/schemas/BaselineScopeDocumentV2'
normalization_lineage:
$ref: '#/components/schemas/BaselineScopeNormalizationLineage'
summary:
type: array
items:
$ref: '#/components/schemas/BaselineScopeSummaryGroup'
BaselineScopeNormalizationLineage:
type: object
additionalProperties: false
required:
- source_shape
- normalized_on_read
- legacy_keys_present
- save_forward_required
properties:
source_shape:
type: string
enum:
- legacy
- canonical_v2
normalized_on_read:
type: boolean
legacy_keys_present:
type: array
items:
type: string
save_forward_required:
type: boolean
EffectiveBaselineScope:
type: object
additionalProperties: false
required:
- canonical_scope
- selected_type_keys
- allowed_type_keys
- limited_type_keys
- unsupported_type_keys
properties:
canonical_scope:
$ref: '#/components/schemas/BaselineScopeDocumentV2'
selected_type_keys:
type: array
items:
type: string
allowed_type_keys:
type: array
items:
type: string
limited_type_keys:
type: array
items:
type: string
unsupported_type_keys:
type: array
items:
type: string
capabilities_by_type:
type: object
additionalProperties: true
legacy_projection:
type:
- object
- 'null'
additionalProperties:
type: array
items:
type: string
BaselineOperationEnvelope:
type: object
additionalProperties: false
required:
- profile_id
- tenant_id
- operation_type
- effective_scope
properties:
profile_id:
type: integer
tenant_id:
type: integer
operation_type:
type: string
enum:
- baseline_capture
- baseline_compare
effective_scope:
$ref: '#/components/schemas/EffectiveBaselineScope'
run_id:
type:
- integer
- 'null'
BaselineScopeBackfillRequest:
type: object
additionalProperties: false
required:
- dry_run
properties:
dry_run:
type: boolean
default: true
write_confirmed:
type: boolean
default: false
BaselineScopeBackfillResult:
type: object
additionalProperties: false
required:
- mode
- candidate_count
- rewritten_count
- audit_logged
- scope_surface
properties:
mode:
type: string
enum:
- preview
- commit
candidate_count:
type: integer
rewritten_count:
type: integer
audit_logged:
type: boolean
scope_surface:
type: string
enum:
- baseline_profiles_only