Files
git.stella-ops.org/docs/schemas/policy-engine-rest.openapi.yaml
StellaOps Bot e53a282fbe
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
feat: Add native binary analyzer test utilities and implement SM2 signing tests
- Introduced `NativeTestBase` class for ELF, PE, and Mach-O binary parsing helpers and assertions.
- Created `TestCryptoFactory` for SM2 cryptographic provider setup and key generation.
- Implemented `Sm2SigningTests` to validate signing functionality with environment gate checks.
- Developed console export service and store with comprehensive unit tests for export status management.
2025-12-07 13:12:41 +02:00

2115 lines
56 KiB
YAML

openapi: 3.1.0
info:
title: StellaOps Policy Engine REST API
version: 1.0.0
description: |
REST API for the StellaOps Policy Engine providing risk profile management,
policy decisions, risk simulation, policy packs, and air-gap sealed mode operations.
This API supports tenant-scoped operations with OAuth 2.0 authentication and
scope-based authorization.
contact:
name: StellaOps Platform Team
url: https://stellaops.org
license:
name: AGPL-3.0-or-later
url: https://www.gnu.org/licenses/agpl-3.0.html
servers:
- url: https://api.stellaops.local
description: Local development server
- url: https://api.stellaops.io
description: Production server
security:
- bearerAuth: []
- oauth2: []
tags:
- name: Risk Profiles
description: Risk profile CRUD, versioning, and lifecycle management
- name: Policy Decisions
description: Policy evaluation and decision endpoints
- name: Risk Simulation
description: Risk scoring simulation and analysis
- name: Policy Packs
description: Policy pack and revision management
- name: AirGap
description: Sealed mode and air-gap operations
paths:
# ============================================================================
# Risk Profiles
# ============================================================================
/api/risk/profiles:
get:
operationId: ListRiskProfiles
summary: List all available risk profiles
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
responses:
'200':
description: List of risk profiles
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
post:
operationId: CreateRiskProfile
summary: Create a new risk profile version in draft status
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:edit]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateRiskProfileRequest'
responses:
'201':
description: Risk profile created
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/api/risk/profiles/{profileId}:
get:
operationId: GetRiskProfile
summary: Get a risk profile by ID
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
responses:
'200':
description: Risk profile details
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileResponse'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/versions:
get:
operationId: ListRiskProfileVersions
summary: List all versions of a risk profile
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
responses:
'200':
description: List of profile versions
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileVersionListResponse'
/api/risk/profiles/{profileId}/versions/{version}:
get:
operationId: GetRiskProfileVersion
summary: Get a specific version of a risk profile
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
- $ref: '#/components/parameters/Version'
responses:
'200':
description: Risk profile version details
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileResponse'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/versions/{version}:activate:
post:
operationId: ActivateRiskProfile
summary: Activate a draft risk profile, making it available for use
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:activate]
parameters:
- $ref: '#/components/parameters/ProfileId'
- $ref: '#/components/parameters/Version'
responses:
'200':
description: Profile activated
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileVersionInfoResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/versions/{version}:deprecate:
post:
operationId: DeprecateRiskProfile
summary: Deprecate an active risk profile
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:edit]
parameters:
- $ref: '#/components/parameters/ProfileId'
- $ref: '#/components/parameters/Version'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DeprecateRiskProfileRequest'
responses:
'200':
description: Profile deprecated
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileVersionInfoResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/versions/{version}:archive:
post:
operationId: ArchiveRiskProfile
summary: Archive a risk profile, removing it from active use
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:edit]
parameters:
- $ref: '#/components/parameters/ProfileId'
- $ref: '#/components/parameters/Version'
responses:
'200':
description: Profile archived
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileVersionInfoResponse'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/events:
get:
operationId: GetRiskProfileEvents
summary: Get lifecycle events for a risk profile
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
- name: limit
in: query
schema:
type: integer
default: 100
minimum: 1
maximum: 1000
responses:
'200':
description: Profile lifecycle events
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileEventListResponse'
/api/risk/profiles/{profileId}/hash:
get:
operationId: GetRiskProfileHash
summary: Get the deterministic hash of a risk profile
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
- name: contentOnly
in: query
schema:
type: boolean
default: false
description: If true, returns hash of content only (excludes metadata)
responses:
'200':
description: Profile hash
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileHashResponse'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/{profileId}/metadata:
get:
operationId: GetRiskProfileMetadata
summary: Export risk profile metadata for notification enrichment
description: Returns metadata suitable for notification context (POLICY-RISK-40-002)
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/ProfileId'
responses:
'200':
description: Profile metadata export
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileMetadataExportResponse'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/profiles/compare:
post:
operationId: CompareRiskProfiles
summary: Compare two risk profile versions and list differences
tags: [Risk Profiles]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CompareRiskProfilesRequest'
responses:
'200':
description: Comparison result
content:
application/json:
schema:
$ref: '#/components/schemas/RiskProfileComparisonResponse'
'400':
$ref: '#/components/responses/BadRequest'
# ============================================================================
# Policy Decisions
# ============================================================================
/policy/decisions:
post:
operationId: PolicyEngine.Decisions
summary: Request policy decisions with source evidence summaries
description: |
Returns policy decisions with source evidence summaries, top severity sources,
and conflict counts.
tags: [Policy Decisions]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyDecisionRequest'
responses:
'200':
description: Policy decisions
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyDecisionResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/policy/decisions/{snapshotId}:
get:
operationId: PolicyEngine.Decisions.BySnapshot
summary: Get policy decisions for a specific snapshot
tags: [Policy Decisions]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- name: snapshotId
in: path
required: true
schema:
type: string
- name: tenantId
in: query
schema:
type: string
- name: componentPurl
in: query
schema:
type: string
- name: advisoryId
in: query
schema:
type: string
- name: includeEvidence
in: query
schema:
type: boolean
default: true
- name: maxSources
in: query
schema:
type: integer
default: 5
responses:
'200':
description: Policy decisions for snapshot
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyDecisionResponse'
'404':
$ref: '#/components/responses/NotFound'
# ============================================================================
# Risk Simulation
# ============================================================================
/api/risk/simulation:
post:
operationId: RunRiskSimulation
summary: Run a risk simulation with score distributions and contribution breakdowns
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RiskSimulationRequest'
responses:
'200':
description: Simulation results
content:
application/json:
schema:
$ref: '#/components/schemas/RiskSimulationResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/simulation/quick:
post:
operationId: RunQuickRiskSimulation
summary: Run a quick risk simulation without detailed breakdowns
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QuickSimulationRequest'
responses:
'200':
description: Quick simulation results
content:
application/json:
schema:
$ref: '#/components/schemas/QuickSimulationResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/risk/simulation/compare:
post:
operationId: CompareProfileSimulations
summary: Compare risk scoring between two profile configurations
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileComparisonRequest'
responses:
'200':
description: Comparison results
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileComparisonResponse'
'400':
$ref: '#/components/responses/BadRequest'
/api/risk/simulation/whatif:
post:
operationId: RunWhatIfSimulation
summary: Run a what-if simulation with hypothetical signal changes
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WhatIfSimulationRequest'
responses:
'200':
description: What-if simulation results
content:
application/json:
schema:
$ref: '#/components/schemas/WhatIfSimulationResponse'
'400':
$ref: '#/components/responses/BadRequest'
/api/risk/simulation/studio/analyze:
post:
operationId: RunPolicyStudioAnalysis
summary: Run a detailed analysis for Policy Studio with full breakdown analytics
description: |
Provides comprehensive breakdown including signal analysis, override tracking,
score distributions, and component breakdowns for policy authoring.
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyStudioAnalysisRequest'
responses:
'200':
description: Studio analysis results
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyStudioAnalysisResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'503':
description: Breakdown service unavailable
/api/risk/simulation/studio/compare:
post:
operationId: CompareProfilesWithBreakdown
summary: Compare profiles with full breakdown analytics and trend analysis
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyStudioComparisonRequest'
responses:
'200':
description: Comparison with breakdown
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyStudioComparisonResponse'
'400':
$ref: '#/components/responses/BadRequest'
/api/risk/simulation/studio/preview:
post:
operationId: PreviewProfileChanges
summary: Preview impact of profile changes before committing
description: Simulates findings against both current and proposed profile to show impact
tags: [Risk Simulation]
security:
- bearerAuth: []
- oauth2: [policy:read]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileChangePreviewRequest'
responses:
'200':
description: Change preview results
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileChangePreviewResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
# ============================================================================
# Policy Packs
# ============================================================================
/api/policy/packs:
get:
operationId: ListPolicyPacks
summary: List policy packs for the current tenant
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:read]
responses:
'200':
description: List of policy packs
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PolicyPackSummary'
post:
operationId: CreatePolicyPack
summary: Create a new policy pack container
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:edit]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePolicyPackRequest'
responses:
'201':
description: Policy pack created
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyPack'
/api/policy/packs/{packId}/revisions:
post:
operationId: CreatePolicyRevision
summary: Create or update policy revision metadata
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:edit]
parameters:
- $ref: '#/components/parameters/PackId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePolicyRevisionRequest'
responses:
'201':
description: Revision created
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyRevision'
'400':
$ref: '#/components/responses/BadRequest'
/api/policy/packs/{packId}/revisions/{version}/bundle:
post:
operationId: CreatePolicyBundle
summary: Compile and sign a policy revision bundle for distribution
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:edit]
parameters:
- $ref: '#/components/parameters/PackId'
- $ref: '#/components/parameters/RevisionVersion'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyBundleRequest'
responses:
'201':
description: Bundle created
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyBundleResponse'
'400':
$ref: '#/components/responses/BadRequest'
/api/policy/packs/{packId}/revisions/{version}/evaluate:
post:
operationId: EvaluatePolicyRevision
summary: Evaluate a policy revision deterministically with in-memory caching
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:read]
parameters:
- $ref: '#/components/parameters/PackId'
- $ref: '#/components/parameters/RevisionVersion'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyEvaluationRequest'
responses:
'200':
description: Evaluation result
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyEvaluationResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/policy/packs/{packId}/revisions/{version}:activate:
post:
operationId: ActivatePolicyRevision
summary: Activate an approved policy revision
description: Enforces two-person approval when required by policy configuration
tags: [Policy Packs]
security:
- bearerAuth: []
- oauth2: [policy:activate]
parameters:
- $ref: '#/components/parameters/PackId'
- $ref: '#/components/parameters/RevisionVersion'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ActivatePolicyRevisionRequest'
responses:
'200':
description: Revision activated
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyRevisionActivationResponse'
'202':
description: Pending second approval
content:
application/json:
schema:
$ref: '#/components/schemas/PolicyRevisionActivationResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
# ============================================================================
# AirGap / Sealed Mode
# ============================================================================
/system/airgap/seal:
post:
operationId: AirGap.Seal
summary: Seal the environment
description: Activates sealed mode for the specified tenant (CONTRACT-SEALED-MODE-004)
tags: [AirGap]
security:
- bearerAuth: []
- oauth2: [airgap:seal]
parameters:
- $ref: '#/components/parameters/TenantIdHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SealRequest'
responses:
'200':
description: Environment sealed
content:
application/json:
schema:
$ref: '#/components/schemas/SealResponse'
'400':
$ref: '#/components/responses/BadRequest'
'500':
description: Seal operation failed
/system/airgap/unseal:
post:
operationId: AirGap.Unseal
summary: Unseal the environment
tags: [AirGap]
security:
- bearerAuth: []
- oauth2: [airgap:seal]
parameters:
- $ref: '#/components/parameters/TenantIdHeader'
responses:
'200':
description: Environment unsealed
content:
application/json:
schema:
$ref: '#/components/schemas/UnsealResponse'
'500':
description: Unseal operation failed
/system/airgap/status:
get:
operationId: AirGap.GetStatus
summary: Get sealed-mode status
tags: [AirGap]
security:
- bearerAuth: []
- oauth2: [airgap:status:read]
parameters:
- $ref: '#/components/parameters/TenantIdHeader'
responses:
'200':
description: Sealed mode status
content:
application/json:
schema:
$ref: '#/components/schemas/SealedModeStatus'
/system/airgap/verify:
post:
operationId: AirGap.VerifyBundle
summary: Verify a bundle against trust roots
tags: [AirGap]
security:
- bearerAuth: []
- oauth2: [airgap:verify]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BundleVerifyRequest'
responses:
'200':
description: Verification result
content:
application/json:
schema:
$ref: '#/components/schemas/BundleVerifyResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
description: Verification failed
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
oauth2:
type: oauth2
flows:
clientCredentials:
tokenUrl: /oauth/token
scopes:
policy:read: Read policy and risk profiles
policy:edit: Create and modify policies
policy:activate: Activate policies
airgap:seal: Seal/unseal environment
airgap:status:read: Read sealed mode status
airgap:verify: Verify bundles
parameters:
ProfileId:
name: profileId
in: path
required: true
schema:
type: string
description: Risk profile identifier
Version:
name: version
in: path
required: true
schema:
type: string
description: Profile version string
PackId:
name: packId
in: path
required: true
schema:
type: string
description: Policy pack identifier
RevisionVersion:
name: version
in: path
required: true
schema:
type: integer
description: Policy revision version number
TenantIdHeader:
name: X-Tenant-Id
in: header
schema:
type: string
default: default
description: Tenant identifier
responses:
BadRequest:
description: Bad request
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetails'
Unauthorized:
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetails'
Forbidden:
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetails'
NotFound:
description: Not found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetails'
schemas:
ProblemDetails:
type: object
properties:
type:
type: string
format: uri
title:
type: string
status:
type: integer
detail:
type: string
instance:
type: string
# ========== Risk Profiles ==========
RiskProfileListResponse:
type: object
required: [profiles]
properties:
profiles:
type: array
items:
$ref: '#/components/schemas/RiskProfileSummary'
RiskProfileSummary:
type: object
required: [profileId, version]
properties:
profileId:
type: string
version:
type: string
description:
type: string
nullable: true
RiskProfileResponse:
type: object
required: [profile, hash]
properties:
profile:
$ref: '#/components/schemas/RiskProfileModel'
hash:
type: string
description: Deterministic SHA-256 hash of the profile
versionInfo:
$ref: '#/components/schemas/RiskProfileVersionInfo'
RiskProfileModel:
type: object
required: [id, version, signals, overrides]
properties:
id:
type: string
version:
type: string
description:
type: string
nullable: true
extends:
type: string
nullable: true
description: Parent profile to inherit from
signals:
type: array
items:
$ref: '#/components/schemas/SignalDefinition'
overrides:
$ref: '#/components/schemas/ProfileOverrides'
metadata:
type: object
additionalProperties: true
nullable: true
SignalDefinition:
type: object
required: [name, weight]
properties:
name:
type: string
weight:
type: number
format: double
description:
type: string
nullable: true
ProfileOverrides:
type: object
properties:
severity:
type: array
items:
$ref: '#/components/schemas/SeverityOverride'
action:
type: array
items:
$ref: '#/components/schemas/ActionOverride'
SeverityOverride:
type: object
required: [set, when]
properties:
set:
type: string
enum: [critical, high, medium, low, info]
when:
type: object
additionalProperties: true
ActionOverride:
type: object
required: [set, when]
properties:
set:
type: string
enum: [block, warn, monitor, ignore]
when:
type: object
additionalProperties: true
RiskProfileVersionInfo:
type: object
required: [version, status, createdAt]
properties:
version:
type: string
status:
type: string
enum: [draft, active, deprecated, archived]
createdAt:
type: string
format: date-time
activatedAt:
type: string
format: date-time
nullable: true
deprecatedAt:
type: string
format: date-time
nullable: true
archivedAt:
type: string
format: date-time
nullable: true
successorVersion:
type: string
nullable: true
deprecationReason:
type: string
nullable: true
RiskProfileVersionListResponse:
type: object
required: [profileId, versions]
properties:
profileId:
type: string
versions:
type: array
items:
$ref: '#/components/schemas/RiskProfileVersionInfo'
RiskProfileVersionInfoResponse:
type: object
required: [versionInfo]
properties:
versionInfo:
$ref: '#/components/schemas/RiskProfileVersionInfo'
RiskProfileEventListResponse:
type: object
required: [profileId, events]
properties:
profileId:
type: string
events:
type: array
items:
$ref: '#/components/schemas/RiskProfileLifecycleEvent'
RiskProfileLifecycleEvent:
type: object
required: [eventType, timestamp]
properties:
eventType:
type: string
timestamp:
type: string
format: date-time
actorId:
type: string
nullable: true
details:
type: object
additionalProperties: true
RiskProfileHashResponse:
type: object
required: [profileId, version, hash, contentOnly]
properties:
profileId:
type: string
version:
type: string
hash:
type: string
contentOnly:
type: boolean
RiskProfileMetadataExportResponse:
type: object
required: [profileId, version, hash, status, signalNames, severityThresholds, exportedAt]
properties:
profileId:
type: string
version:
type: string
description:
type: string
nullable: true
hash:
type: string
status:
type: string
signalNames:
type: array
items:
type: string
severityThresholds:
type: array
items:
$ref: '#/components/schemas/SeverityThresholdInfo'
customMetadata:
type: object
additionalProperties: true
nullable: true
extendsProfile:
type: string
nullable: true
exportedAt:
type: string
format: date-time
SeverityThresholdInfo:
type: object
required: [targetSeverity, whenConditions]
properties:
targetSeverity:
type: string
whenConditions:
type: object
additionalProperties: true
RiskProfileComparisonResponse:
type: object
required: [comparison]
properties:
comparison:
$ref: '#/components/schemas/RiskProfileVersionComparison'
RiskProfileVersionComparison:
type: object
properties:
fromProfileId:
type: string
fromVersion:
type: string
toProfileId:
type: string
toVersion:
type: string
differences:
type: array
items:
$ref: '#/components/schemas/ProfileDifference'
ProfileDifference:
type: object
properties:
path:
type: string
changeType:
type: string
enum: [added, removed, modified]
oldValue:
nullable: true
newValue:
nullable: true
CreateRiskProfileRequest:
type: object
required: [profile]
properties:
profile:
$ref: '#/components/schemas/RiskProfileModel'
DeprecateRiskProfileRequest:
type: object
properties:
successorVersion:
type: string
nullable: true
reason:
type: string
nullable: true
CompareRiskProfilesRequest:
type: object
required: [fromProfileId, fromVersion, toProfileId, toVersion]
properties:
fromProfileId:
type: string
fromVersion:
type: string
toProfileId:
type: string
toVersion:
type: string
# ========== Policy Decisions ==========
PolicyDecisionRequest:
type: object
required: [snapshotId]
properties:
snapshotId:
type: string
tenantId:
type: string
nullable: true
componentPurl:
type: string
nullable: true
advisoryId:
type: string
nullable: true
includeEvidence:
type: boolean
default: true
maxSources:
type: integer
default: 5
PolicyDecisionResponse:
type: object
properties:
snapshotId:
type: string
decisions:
type: array
items:
$ref: '#/components/schemas/PolicyDecision'
timestamp:
type: string
format: date-time
PolicyDecision:
type: object
properties:
componentPurl:
type: string
advisoryId:
type: string
decision:
type: string
enum: [allow, deny, warn, pending]
severity:
type: string
evidenceSummary:
$ref: '#/components/schemas/EvidenceSummary'
EvidenceSummary:
type: object
properties:
sourceCount:
type: integer
topSources:
type: array
items:
$ref: '#/components/schemas/EvidenceSource'
conflictCount:
type: integer
EvidenceSource:
type: object
properties:
source:
type: string
severity:
type: string
confidence:
type: number
format: double
# ========== Risk Simulation ==========
RiskSimulationRequest:
type: object
required: [profileId, findings]
properties:
profileId:
type: string
profileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
includeContributions:
type: boolean
default: true
includeDistribution:
type: boolean
default: true
mode:
type: string
enum: [quick, full, whatIf]
default: full
SimulationFinding:
type: object
required: [findingId, signals]
properties:
findingId:
type: string
componentPurl:
type: string
nullable: true
advisoryId:
type: string
nullable: true
signals:
type: object
additionalProperties: true
RiskSimulationResponse:
type: object
required: [result]
properties:
result:
$ref: '#/components/schemas/RiskSimulationResult'
RiskSimulationResult:
type: object
required: [simulationId, profileId, profileVersion, timestamp, aggregateMetrics, findingScores, executionTimeMs]
properties:
simulationId:
type: string
profileId:
type: string
profileVersion:
type: string
timestamp:
type: string
format: date-time
aggregateMetrics:
$ref: '#/components/schemas/AggregateRiskMetrics'
findingScores:
type: array
items:
$ref: '#/components/schemas/FindingScore'
distribution:
$ref: '#/components/schemas/RiskDistribution'
contributions:
type: array
items:
$ref: '#/components/schemas/SignalContribution'
executionTimeMs:
type: number
format: double
AggregateRiskMetrics:
type: object
required: [meanScore, medianScore, criticalCount, highCount, mediumCount, lowCount, totalCount]
properties:
meanScore:
type: number
format: double
medianScore:
type: number
format: double
maxScore:
type: number
format: double
minScore:
type: number
format: double
criticalCount:
type: integer
highCount:
type: integer
mediumCount:
type: integer
lowCount:
type: integer
infoCount:
type: integer
totalCount:
type: integer
FindingScore:
type: object
required: [findingId, normalizedScore, severity, recommendedAction]
properties:
findingId:
type: string
rawScore:
type: number
format: double
normalizedScore:
type: number
format: double
severity:
type: string
enum: [critical, high, medium, low, info]
recommendedAction:
type: string
enum: [block, warn, monitor, ignore]
signalBreakdown:
type: object
additionalProperties:
type: number
format: double
RiskDistribution:
type: object
properties:
buckets:
type: array
items:
$ref: '#/components/schemas/DistributionBucket'
DistributionBucket:
type: object
properties:
min:
type: number
format: double
max:
type: number
format: double
count:
type: integer
SignalContribution:
type: object
properties:
signalName:
type: string
totalContribution:
type: number
format: double
averageContribution:
type: number
format: double
QuickSimulationRequest:
type: object
required: [profileId, findings]
properties:
profileId:
type: string
profileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
QuickSimulationResponse:
type: object
required: [simulationId, profileId, profileVersion, timestamp, aggregateMetrics, executionTimeMs]
properties:
simulationId:
type: string
profileId:
type: string
profileVersion:
type: string
timestamp:
type: string
format: date-time
aggregateMetrics:
$ref: '#/components/schemas/AggregateRiskMetrics'
distribution:
$ref: '#/components/schemas/RiskDistribution'
executionTimeMs:
type: number
format: double
ProfileComparisonRequest:
type: object
required: [baseProfileId, compareProfileId, findings]
properties:
baseProfileId:
type: string
baseProfileVersion:
type: string
nullable: true
compareProfileId:
type: string
compareProfileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
ProfileComparisonResponse:
type: object
required: [baseProfile, compareProfile, deltas]
properties:
baseProfile:
$ref: '#/components/schemas/ProfileSimulationSummary'
compareProfile:
$ref: '#/components/schemas/ProfileSimulationSummary'
deltas:
$ref: '#/components/schemas/ComparisonDeltas'
ProfileSimulationSummary:
type: object
required: [profileId, profileVersion, metrics]
properties:
profileId:
type: string
profileVersion:
type: string
metrics:
$ref: '#/components/schemas/AggregateRiskMetrics'
ComparisonDeltas:
type: object
properties:
meanScoreDelta:
type: number
format: double
medianScoreDelta:
type: number
format: double
criticalCountDelta:
type: integer
highCountDelta:
type: integer
mediumCountDelta:
type: integer
lowCountDelta:
type: integer
WhatIfSimulationRequest:
type: object
required: [profileId, findings, hypotheticalChanges]
properties:
profileId:
type: string
profileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
hypotheticalChanges:
type: array
items:
$ref: '#/components/schemas/HypotheticalChange'
HypotheticalChange:
type: object
required: [signalName]
properties:
signalName:
type: string
newValue:
nullable: true
applyToAll:
type: boolean
default: true
findingIds:
type: array
items:
type: string
WhatIfSimulationResponse:
type: object
required: [baselineResult, modifiedResult, impactSummary]
properties:
baselineResult:
$ref: '#/components/schemas/RiskSimulationResult'
modifiedResult:
$ref: '#/components/schemas/RiskSimulationResult'
impactSummary:
$ref: '#/components/schemas/WhatIfImpactSummary'
WhatIfImpactSummary:
type: object
properties:
findingsImproved:
type: integer
findingsWorsened:
type: integer
findingsUnchanged:
type: integer
averageScoreDelta:
type: number
format: double
severityShifts:
$ref: '#/components/schemas/SeverityShifts'
SeverityShifts:
type: object
properties:
toLower:
type: integer
toHigher:
type: integer
unchanged:
type: integer
PolicyStudioAnalysisRequest:
type: object
required: [profileId, findings]
properties:
profileId:
type: string
profileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
breakdownOptions:
$ref: '#/components/schemas/RiskSimulationBreakdownOptions'
RiskSimulationBreakdownOptions:
type: object
properties:
includeSignalAnalysis:
type: boolean
default: true
includeOverrideTracking:
type: boolean
default: true
includeScoreDistributions:
type: boolean
default: true
includeComponentBreakdowns:
type: boolean
default: true
PolicyStudioAnalysisResponse:
type: object
required: [result, breakdown, totalExecutionTimeMs]
properties:
result:
$ref: '#/components/schemas/RiskSimulationResult'
breakdown:
$ref: '#/components/schemas/RiskSimulationBreakdown'
totalExecutionTimeMs:
type: number
format: double
RiskSimulationBreakdown:
type: object
properties:
signalAnalysis:
type: object
additionalProperties: true
overrideTracking:
type: object
additionalProperties: true
scoreDistributions:
type: object
additionalProperties: true
componentBreakdowns:
type: object
additionalProperties: true
PolicyStudioComparisonRequest:
type: object
required: [baseProfileId, compareProfileId, findings]
properties:
baseProfileId:
type: string
compareProfileId:
type: string
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
breakdownOptions:
$ref: '#/components/schemas/RiskSimulationBreakdownOptions'
PolicyStudioComparisonResponse:
type: object
required: [baselineResult, compareResult, breakdown, executionTimeMs]
properties:
baselineResult:
$ref: '#/components/schemas/RiskSimulationResult'
compareResult:
$ref: '#/components/schemas/RiskSimulationResult'
breakdown:
$ref: '#/components/schemas/RiskSimulationBreakdown'
executionTimeMs:
type: number
format: double
ProfileChangePreviewRequest:
type: object
required: [currentProfileId, findings]
properties:
currentProfileId:
type: string
currentProfileVersion:
type: string
nullable: true
proposedProfileId:
type: string
nullable: true
proposedProfileVersion:
type: string
nullable: true
findings:
type: array
items:
$ref: '#/components/schemas/SimulationFinding'
proposedWeightChanges:
type: object
additionalProperties:
type: number
format: double
proposedOverrideChanges:
type: array
items:
$ref: '#/components/schemas/ProposedOverrideChange'
ProposedOverrideChange:
type: object
required: [overrideType, when, value]
properties:
overrideType:
type: string
when:
type: object
additionalProperties: true
value:
nullable: true
reason:
type: string
nullable: true
ProfileChangePreviewResponse:
type: object
required: [currentResult, proposedResult, impact, highImpactFindings]
properties:
currentResult:
$ref: '#/components/schemas/ProfileSimulationSummary'
proposedResult:
$ref: '#/components/schemas/ProfileSimulationSummary'
impact:
$ref: '#/components/schemas/ProfileChangeImpact'
highImpactFindings:
type: array
items:
$ref: '#/components/schemas/HighImpactFindingPreview'
ProfileChangeImpact:
type: object
properties:
findingsImproved:
type: integer
findingsWorsened:
type: integer
findingsUnchanged:
type: integer
severityEscalations:
type: integer
severityDeescalations:
type: integer
actionChanges:
type: integer
meanScoreDelta:
type: number
format: double
criticalCountDelta:
type: integer
highCountDelta:
type: integer
HighImpactFindingPreview:
type: object
required: [findingId, currentScore, proposedScore, scoreDelta]
properties:
findingId:
type: string
currentScore:
type: number
format: double
proposedScore:
type: number
format: double
scoreDelta:
type: number
format: double
currentSeverity:
type: string
proposedSeverity:
type: string
currentAction:
type: string
proposedAction:
type: string
impactReason:
type: string
# ========== Policy Packs ==========
CreatePolicyPackRequest:
type: object
properties:
packId:
type: string
nullable: true
displayName:
type: string
nullable: true
PolicyPack:
type: object
required: [packId, createdAt, revisions]
properties:
packId:
type: string
displayName:
type: string
nullable: true
createdAt:
type: string
format: date-time
revisions:
type: array
items:
$ref: '#/components/schemas/PolicyRevision'
PolicyPackSummary:
type: object
required: [packId, createdAt, versions]
properties:
packId:
type: string
displayName:
type: string
nullable: true
createdAt:
type: string
format: date-time
versions:
type: array
items:
type: integer
CreatePolicyRevisionRequest:
type: object
properties:
version:
type: integer
nullable: true
requiresTwoPersonApproval:
type: boolean
nullable: true
initialStatus:
type: string
enum: [draft, approved]
default: approved
PolicyRevision:
type: object
required: [packId, version, status, requiresTwoPersonApproval, createdAt, approvals]
properties:
packId:
type: string
version:
type: integer
status:
type: string
enum: [draft, approved, active, superseded]
requiresTwoPersonApproval:
type: boolean
createdAt:
type: string
format: date-time
activatedAt:
type: string
format: date-time
nullable: true
approvals:
type: array
items:
$ref: '#/components/schemas/PolicyActivationApproval'
PolicyActivationApproval:
type: object
required: [actorId, approvedAt]
properties:
actorId:
type: string
approvedAt:
type: string
format: date-time
comment:
type: string
nullable: true
ActivatePolicyRevisionRequest:
type: object
properties:
comment:
type: string
nullable: true
PolicyRevisionActivationResponse:
type: object
required: [status, revision]
properties:
status:
type: string
enum: [pending_second_approval, activated, already_active]
revision:
$ref: '#/components/schemas/PolicyRevision'
PolicyBundleRequest:
type: object
properties:
signBundle:
type: boolean
default: true
targetEnvironment:
type: string
nullable: true
PolicyBundleResponse:
type: object
required: [success]
properties:
success:
type: boolean
bundleId:
type: string
bundlePath:
type: string
hash:
type: string
signatureId:
type: string
nullable: true
errors:
type: array
items:
type: string
PolicyEvaluationRequest:
type: object
required: [packId, version, input]
properties:
packId:
type: string
version:
type: integer
input:
type: object
additionalProperties: true
PolicyEvaluationResponse:
type: object
required: [result]
properties:
result:
type: object
additionalProperties: true
deterministic:
type: boolean
cacheHit:
type: boolean
executionTimeMs:
type: number
format: double
# ========== AirGap ==========
SealRequest:
type: object
properties:
reason:
type: string
nullable: true
trustRoots:
type: array
items:
type: string
allowedSources:
type: array
items:
type: string
SealResponse:
type: object
required: [sealed, sealedAt]
properties:
sealed:
type: boolean
sealedAt:
type: string
format: date-time
reason:
type: string
nullable: true
UnsealResponse:
type: object
required: [sealed]
properties:
sealed:
type: boolean
unsealedAt:
type: string
format: date-time
SealedModeStatus:
type: object
required: [isSealed]
properties:
isSealed:
type: boolean
sealedAt:
type: string
format: date-time
nullable: true
unsealedAt:
type: string
format: date-time
nullable: true
trustRoots:
type: array
items:
type: string
lastVerifiedAt:
type: string
format: date-time
nullable: true
BundleVerifyRequest:
type: object
required: [bundlePath]
properties:
bundlePath:
type: string
expectedHash:
type: string
nullable: true
trustRootId:
type: string
nullable: true
BundleVerifyResponse:
type: object
required: [valid, verificationResult]
properties:
valid:
type: boolean
verificationResult:
$ref: '#/components/schemas/VerificationResult'
bundleInfo:
$ref: '#/components/schemas/BundleInfo'
VerificationResult:
type: object
properties:
signatureValid:
type: boolean
hashValid:
type: boolean
trustRootMatched:
type: boolean
error:
type: string
nullable: true
BundleInfo:
type: object
properties:
bundleId:
type: string
version:
type: string
createdAt:
type: string
format: date-time
hash:
type: string