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
- 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.
2115 lines
56 KiB
YAML
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
|