Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
mock-dev-release / package-mock-release (push) Has been cancelled
- Added ConsoleExportClient for managing export requests and responses. - Introduced ConsoleExportRequest and ConsoleExportResponse models. - Implemented methods for creating and retrieving exports with appropriate headers. feat(crypto): Add Software SM2/SM3 Cryptography Provider - Implemented SmSoftCryptoProvider for software-only SM2/SM3 cryptography. - Added support for signing and verification using SM2 algorithm. - Included hashing functionality with SM3 algorithm. - Configured options for loading keys from files and environment gate checks. test(crypto): Add unit tests for SmSoftCryptoProvider - Created comprehensive tests for signing, verifying, and hashing functionalities. - Ensured correct behavior for key management and error handling. feat(api): Enhance Console Export Models - Expanded ConsoleExport models to include detailed status and event types. - Added support for various export formats and notification options. test(time): Implement TimeAnchorPolicyService tests - Developed tests for TimeAnchorPolicyService to validate time anchors. - Covered scenarios for anchor validation, drift calculation, and policy enforcement.
1472 lines
37 KiB
YAML
1472 lines
37 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: StellaOps Findings Ledger Time-Travel API
|
|
version: 1.0.0
|
|
description: |
|
|
API for querying the Findings Ledger at specific points in time, creating snapshots,
|
|
and performing historical analysis. Unblocks Export Center chains (73+ tasks).
|
|
|
|
This API enables:
|
|
- Point-in-time queries for findings, VEX statements, advisories, and SBOMs
|
|
- Snapshot creation and management for reproducible exports
|
|
- Historical comparison (diff) between two points in time
|
|
- Event replay for audit and debugging purposes
|
|
- Cross-enclave evidence verification
|
|
|
|
## Blocker References
|
|
- SPRINT_0160_export_evidence (15 tasks)
|
|
- SPRINT_0161_evidence_locker (7 tasks)
|
|
- SPRINT_0162_exportcenter_i (15 tasks)
|
|
- SPRINT_0163_exportcenter_ii (22 tasks)
|
|
- SPRINT_0164_exportcenter_iii (14 tasks)
|
|
contact:
|
|
name: StellaOps Platform Team
|
|
url: https://stella-ops.org
|
|
license:
|
|
name: AGPL-3.0-or-later
|
|
url: https://www.gnu.org/licenses/agpl-3.0.html
|
|
|
|
servers:
|
|
- url: https://api.stella-ops.org/v1
|
|
description: Production API
|
|
- url: https://api.staging.stella-ops.org/v1
|
|
description: Staging API
|
|
|
|
tags:
|
|
- name: snapshots
|
|
description: Ledger snapshot management
|
|
- name: time-travel
|
|
description: Point-in-time queries
|
|
- name: replay
|
|
description: Event replay operations
|
|
- name: diff
|
|
description: Historical comparison
|
|
- name: evidence
|
|
description: Evidence snapshot linking
|
|
|
|
paths:
|
|
/ledger/snapshots:
|
|
get:
|
|
operationId: listSnapshots
|
|
summary: List available snapshots
|
|
description: Returns a paginated list of ledger snapshots for the tenant
|
|
tags:
|
|
- snapshots
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotStatus'
|
|
- name: created_after
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: created_before
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
responses:
|
|
'200':
|
|
description: List of snapshots
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotListResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
|
|
post:
|
|
operationId: createSnapshot
|
|
summary: Create a new snapshot
|
|
description: |
|
|
Creates a point-in-time snapshot of the ledger state. Snapshots are immutable
|
|
and can be used for reproducible exports and historical analysis.
|
|
tags:
|
|
- snapshots
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSnapshotRequest'
|
|
responses:
|
|
'201':
|
|
description: Snapshot created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'409':
|
|
description: Snapshot with this label already exists
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/ledger/snapshots/{snapshot_id}:
|
|
get:
|
|
operationId: getSnapshot
|
|
summary: Get snapshot details
|
|
description: Returns details of a specific snapshot including its metadata and statistics
|
|
tags:
|
|
- snapshots
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/SnapshotId'
|
|
responses:
|
|
'200':
|
|
description: Snapshot details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
delete:
|
|
operationId: deleteSnapshot
|
|
summary: Delete a snapshot
|
|
description: |
|
|
Deletes a snapshot. Only snapshots in 'available' or 'expired' status can be deleted.
|
|
Active snapshots referenced by exports cannot be deleted.
|
|
tags:
|
|
- snapshots
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/SnapshotId'
|
|
responses:
|
|
'204':
|
|
description: Snapshot deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
description: Snapshot is in use and cannot be deleted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/ledger/at/{timestamp}:
|
|
get:
|
|
operationId: queryAtTimestamp
|
|
summary: Query ledger state at timestamp
|
|
description: |
|
|
Returns the ledger state as it existed at the specified timestamp.
|
|
This enables historical queries without creating a persistent snapshot.
|
|
tags:
|
|
- time-travel
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: timestamp
|
|
in: path
|
|
required: true
|
|
description: ISO 8601 timestamp to query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: entity_type
|
|
in: query
|
|
required: true
|
|
schema:
|
|
$ref: '#/components/schemas/EntityType'
|
|
- name: filters
|
|
in: query
|
|
style: deepObject
|
|
explode: true
|
|
schema:
|
|
$ref: '#/components/schemas/TimeQueryFilters'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
responses:
|
|
'200':
|
|
description: Historical state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HistoricalQueryResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'404':
|
|
description: No data available for the specified timestamp
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/ledger/at-sequence/{sequence}:
|
|
get:
|
|
operationId: queryAtSequence
|
|
summary: Query ledger state at sequence number
|
|
description: |
|
|
Returns the ledger state as it existed at the specified sequence number.
|
|
Provides deterministic point-in-time queries based on event sequence.
|
|
tags:
|
|
- time-travel
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: sequence
|
|
in: path
|
|
required: true
|
|
description: Ledger sequence number
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
- name: entity_type
|
|
in: query
|
|
required: true
|
|
schema:
|
|
$ref: '#/components/schemas/EntityType'
|
|
- name: filters
|
|
in: query
|
|
style: deepObject
|
|
explode: true
|
|
schema:
|
|
$ref: '#/components/schemas/TimeQueryFilters'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
responses:
|
|
'200':
|
|
description: Historical state at sequence
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HistoricalQueryResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'404':
|
|
description: Sequence number not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/ledger/replay:
|
|
post:
|
|
operationId: replayEvents
|
|
summary: Replay ledger events
|
|
description: |
|
|
Replays ledger events from a starting point. Useful for rebuilding projections,
|
|
debugging, and audit purposes. Returns events in deterministic order.
|
|
tags:
|
|
- replay
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ReplayRequest'
|
|
responses:
|
|
'200':
|
|
description: Replay results
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ReplayResponse'
|
|
application/x-ndjson:
|
|
schema:
|
|
$ref: '#/components/schemas/ReplayEvent'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/ledger/diff:
|
|
post:
|
|
operationId: computeDiff
|
|
summary: Compare ledger states
|
|
description: |
|
|
Computes the difference between two points in time. Returns added, modified,
|
|
and removed entities between the specified timestamps or sequence numbers.
|
|
tags:
|
|
- diff
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DiffRequest'
|
|
responses:
|
|
'200':
|
|
description: Diff results
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DiffResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/ledger/changes:
|
|
get:
|
|
operationId: getChanges
|
|
summary: Get change log
|
|
description: |
|
|
Returns a stream of changes (events) between two points in time.
|
|
Optimized for incremental synchronization and export.
|
|
tags:
|
|
- diff
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: since_timestamp
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: until_timestamp
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: since_sequence
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
- name: until_sequence
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
- name: entity_types
|
|
in: query
|
|
style: form
|
|
explode: false
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EntityType'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
responses:
|
|
'200':
|
|
description: Change log
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ChangeLogResponse'
|
|
application/x-ndjson:
|
|
schema:
|
|
$ref: '#/components/schemas/ChangeLogEntry'
|
|
|
|
/ledger/evidence/link:
|
|
post:
|
|
operationId: linkEvidence
|
|
summary: Link evidence to finding
|
|
description: |
|
|
Links a finding to an evidence snapshot in a portable bundle.
|
|
Creates an immutable ledger entry for audit purposes.
|
|
tags:
|
|
- evidence
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LinkEvidenceRequest'
|
|
responses:
|
|
'201':
|
|
description: Evidence linked
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LinkEvidenceResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'409':
|
|
description: Evidence already linked (idempotent)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LinkEvidenceResponse'
|
|
|
|
/ledger/evidence/{finding_id}:
|
|
get:
|
|
operationId: getEvidenceSnapshots
|
|
summary: Get evidence snapshots for finding
|
|
description: Returns all evidence snapshots linked to a specific finding
|
|
tags:
|
|
- evidence
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: finding_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Evidence snapshots
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EvidenceSnapshotsResponse'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/ledger/evidence/verify:
|
|
post:
|
|
operationId: verifyEvidence
|
|
summary: Verify cross-enclave evidence
|
|
description: |
|
|
Verifies that an evidence snapshot exists, is valid, and matches
|
|
the expected DSSE digest for cross-enclave verification.
|
|
tags:
|
|
- evidence
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/VerifyEvidenceRequest'
|
|
responses:
|
|
'200':
|
|
description: Verification result
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/VerifyEvidenceResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/ledger/export/historical:
|
|
post:
|
|
operationId: exportHistorical
|
|
summary: Export historical findings
|
|
description: |
|
|
Exports findings as they existed at a specific point in time.
|
|
Supports all standard export shapes (findings, vex, advisory, sbom).
|
|
tags:
|
|
- time-travel
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HistoricalExportRequest'
|
|
responses:
|
|
'200':
|
|
description: Historical export
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HistoricalExportResponse'
|
|
application/x-ndjson:
|
|
schema:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/FindingExportItem'
|
|
- $ref: '#/components/schemas/VexExportItem'
|
|
- $ref: '#/components/schemas/AdvisoryExportItem'
|
|
- $ref: '#/components/schemas/SbomExportItem'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/ledger/staleness:
|
|
get:
|
|
operationId: checkStaleness
|
|
summary: Check ledger staleness
|
|
description: |
|
|
Checks if the ledger data is stale compared to the configured thresholds.
|
|
Used for air-gap scenarios to determine if bundle refresh is needed.
|
|
tags:
|
|
- evidence
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: entity_types
|
|
in: query
|
|
style: form
|
|
explode: false
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EntityType'
|
|
responses:
|
|
'200':
|
|
description: Staleness check result
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/StalenessResponse'
|
|
|
|
components:
|
|
parameters:
|
|
TenantId:
|
|
name: X-Tenant-Id
|
|
in: header
|
|
required: true
|
|
description: Tenant identifier for multi-tenant isolation
|
|
schema:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 64
|
|
|
|
PageSize:
|
|
name: page_size
|
|
in: query
|
|
description: Number of items per page (default 500, max 5000)
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 5000
|
|
default: 500
|
|
|
|
PageToken:
|
|
name: page_token
|
|
in: query
|
|
description: Pagination token from previous response
|
|
schema:
|
|
type: string
|
|
|
|
SnapshotId:
|
|
name: snapshot_id
|
|
in: path
|
|
required: true
|
|
description: Snapshot unique identifier
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
|
|
schemas:
|
|
EntityType:
|
|
type: string
|
|
enum:
|
|
- finding
|
|
- vex
|
|
- advisory
|
|
- sbom
|
|
- evidence
|
|
description: Type of ledger entity
|
|
|
|
SnapshotStatus:
|
|
type: string
|
|
enum:
|
|
- creating
|
|
- available
|
|
- exporting
|
|
- expired
|
|
- deleted
|
|
description: Snapshot lifecycle status
|
|
|
|
Snapshot:
|
|
type: object
|
|
required:
|
|
- snapshot_id
|
|
- tenant_id
|
|
- status
|
|
- created_at
|
|
- sequence_number
|
|
properties:
|
|
snapshot_id:
|
|
type: string
|
|
format: uuid
|
|
tenant_id:
|
|
type: string
|
|
label:
|
|
type: string
|
|
description: Human-readable label for the snapshot
|
|
description:
|
|
type: string
|
|
status:
|
|
$ref: '#/components/schemas/SnapshotStatus'
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
expires_at:
|
|
type: string
|
|
format: date-time
|
|
sequence_number:
|
|
type: integer
|
|
format: int64
|
|
description: Ledger sequence number at snapshot time
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
description: Point-in-time timestamp
|
|
statistics:
|
|
$ref: '#/components/schemas/SnapshotStatistics'
|
|
merkle_root:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
description: Merkle tree root hash for integrity verification
|
|
dsse_digest:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
description: DSSE envelope digest if snapshot is signed
|
|
metadata:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
SnapshotStatistics:
|
|
type: object
|
|
properties:
|
|
findings_count:
|
|
type: integer
|
|
format: int64
|
|
vex_statements_count:
|
|
type: integer
|
|
format: int64
|
|
advisories_count:
|
|
type: integer
|
|
format: int64
|
|
sboms_count:
|
|
type: integer
|
|
format: int64
|
|
events_count:
|
|
type: integer
|
|
format: int64
|
|
size_bytes:
|
|
type: integer
|
|
format: int64
|
|
|
|
CreateSnapshotRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
label:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 128
|
|
description: Unique label for this snapshot within the tenant
|
|
description:
|
|
type: string
|
|
maxLength: 1024
|
|
at_timestamp:
|
|
type: string
|
|
format: date-time
|
|
description: Create snapshot at specific timestamp (default is now)
|
|
at_sequence:
|
|
type: integer
|
|
format: int64
|
|
description: Create snapshot at specific sequence number
|
|
expires_in:
|
|
type: string
|
|
format: duration
|
|
example: P30D
|
|
description: ISO 8601 duration after which snapshot expires
|
|
include_entity_types:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EntityType'
|
|
description: Entity types to include (default is all)
|
|
sign:
|
|
type: boolean
|
|
default: false
|
|
description: Sign the snapshot with DSSE envelope
|
|
metadata:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
SnapshotListResponse:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
next_page_token:
|
|
type: string
|
|
total_count:
|
|
type: integer
|
|
format: int64
|
|
|
|
TimeQueryFilters:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
severity_min:
|
|
type: number
|
|
severity_max:
|
|
type: number
|
|
policy_version:
|
|
type: string
|
|
artifact_id:
|
|
type: string
|
|
vuln_id:
|
|
type: string
|
|
labels:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
|
|
HistoricalQueryResponse:
|
|
type: object
|
|
required:
|
|
- query_point
|
|
- entity_type
|
|
- items
|
|
properties:
|
|
query_point:
|
|
$ref: '#/components/schemas/QueryPoint'
|
|
entity_type:
|
|
$ref: '#/components/schemas/EntityType'
|
|
items:
|
|
type: array
|
|
items:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/FindingExportItem'
|
|
- $ref: '#/components/schemas/VexExportItem'
|
|
- $ref: '#/components/schemas/AdvisoryExportItem'
|
|
- $ref: '#/components/schemas/SbomExportItem'
|
|
next_page_token:
|
|
type: string
|
|
total_count:
|
|
type: integer
|
|
format: int64
|
|
|
|
QueryPoint:
|
|
type: object
|
|
required:
|
|
- timestamp
|
|
- sequence_number
|
|
properties:
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
sequence_number:
|
|
type: integer
|
|
format: int64
|
|
snapshot_id:
|
|
type: string
|
|
format: uuid
|
|
description: If query was against a snapshot
|
|
|
|
ReplayRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
from_sequence:
|
|
type: integer
|
|
format: int64
|
|
description: Starting sequence number (default 0)
|
|
to_sequence:
|
|
type: integer
|
|
format: int64
|
|
description: Ending sequence number (default latest)
|
|
from_timestamp:
|
|
type: string
|
|
format: date-time
|
|
to_timestamp:
|
|
type: string
|
|
format: date-time
|
|
chain_ids:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Filter by specific chain IDs
|
|
event_types:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Filter by event types
|
|
include_payload:
|
|
type: boolean
|
|
default: true
|
|
output_format:
|
|
type: string
|
|
enum:
|
|
- json
|
|
- ndjson
|
|
default: json
|
|
page_size:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 10000
|
|
default: 1000
|
|
|
|
ReplayResponse:
|
|
type: object
|
|
required:
|
|
- events
|
|
- replay_metadata
|
|
properties:
|
|
events:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ReplayEvent'
|
|
next_page_token:
|
|
type: string
|
|
replay_metadata:
|
|
$ref: '#/components/schemas/ReplayMetadata'
|
|
|
|
ReplayEvent:
|
|
type: object
|
|
required:
|
|
- event_id
|
|
- sequence_number
|
|
- chain_id
|
|
- event_type
|
|
- recorded_at
|
|
properties:
|
|
event_id:
|
|
type: string
|
|
format: uuid
|
|
sequence_number:
|
|
type: integer
|
|
format: int64
|
|
chain_id:
|
|
type: string
|
|
chain_sequence:
|
|
type: integer
|
|
event_type:
|
|
type: string
|
|
occurred_at:
|
|
type: string
|
|
format: date-time
|
|
recorded_at:
|
|
type: string
|
|
format: date-time
|
|
actor_id:
|
|
type: string
|
|
actor_type:
|
|
type: string
|
|
artifact_id:
|
|
type: string
|
|
finding_id:
|
|
type: string
|
|
policy_version:
|
|
type: string
|
|
event_hash:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
previous_hash:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
payload:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
ReplayMetadata:
|
|
type: object
|
|
properties:
|
|
from_sequence:
|
|
type: integer
|
|
format: int64
|
|
to_sequence:
|
|
type: integer
|
|
format: int64
|
|
events_count:
|
|
type: integer
|
|
format: int64
|
|
has_more:
|
|
type: boolean
|
|
replay_duration_ms:
|
|
type: integer
|
|
format: int64
|
|
|
|
DiffRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
- from
|
|
- to
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
from:
|
|
$ref: '#/components/schemas/DiffPoint'
|
|
to:
|
|
$ref: '#/components/schemas/DiffPoint'
|
|
entity_types:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EntityType'
|
|
include_unchanged:
|
|
type: boolean
|
|
default: false
|
|
output_format:
|
|
type: string
|
|
enum:
|
|
- summary
|
|
- detailed
|
|
- full
|
|
default: summary
|
|
|
|
DiffPoint:
|
|
type: object
|
|
properties:
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
sequence_number:
|
|
type: integer
|
|
format: int64
|
|
snapshot_id:
|
|
type: string
|
|
format: uuid
|
|
|
|
DiffResponse:
|
|
type: object
|
|
required:
|
|
- from_point
|
|
- to_point
|
|
- summary
|
|
properties:
|
|
from_point:
|
|
$ref: '#/components/schemas/QueryPoint'
|
|
to_point:
|
|
$ref: '#/components/schemas/QueryPoint'
|
|
summary:
|
|
$ref: '#/components/schemas/DiffSummary'
|
|
changes:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/DiffEntry'
|
|
next_page_token:
|
|
type: string
|
|
|
|
DiffSummary:
|
|
type: object
|
|
properties:
|
|
added:
|
|
type: integer
|
|
modified:
|
|
type: integer
|
|
removed:
|
|
type: integer
|
|
unchanged:
|
|
type: integer
|
|
by_entity_type:
|
|
type: object
|
|
additionalProperties:
|
|
type: object
|
|
properties:
|
|
added:
|
|
type: integer
|
|
modified:
|
|
type: integer
|
|
removed:
|
|
type: integer
|
|
|
|
DiffEntry:
|
|
type: object
|
|
required:
|
|
- entity_type
|
|
- entity_id
|
|
- change_type
|
|
properties:
|
|
entity_type:
|
|
$ref: '#/components/schemas/EntityType'
|
|
entity_id:
|
|
type: string
|
|
change_type:
|
|
type: string
|
|
enum:
|
|
- added
|
|
- modified
|
|
- removed
|
|
from_state:
|
|
type: object
|
|
additionalProperties: true
|
|
to_state:
|
|
type: object
|
|
additionalProperties: true
|
|
changed_fields:
|
|
type: array
|
|
items:
|
|
type: string
|
|
|
|
ChangeLogResponse:
|
|
type: object
|
|
required:
|
|
- entries
|
|
properties:
|
|
entries:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ChangeLogEntry'
|
|
next_page_token:
|
|
type: string
|
|
from_sequence:
|
|
type: integer
|
|
format: int64
|
|
to_sequence:
|
|
type: integer
|
|
format: int64
|
|
|
|
ChangeLogEntry:
|
|
type: object
|
|
required:
|
|
- sequence_number
|
|
- timestamp
|
|
- entity_type
|
|
- entity_id
|
|
- event_type
|
|
properties:
|
|
sequence_number:
|
|
type: integer
|
|
format: int64
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
entity_type:
|
|
$ref: '#/components/schemas/EntityType'
|
|
entity_id:
|
|
type: string
|
|
event_type:
|
|
type: string
|
|
event_hash:
|
|
type: string
|
|
actor_id:
|
|
type: string
|
|
summary:
|
|
type: string
|
|
|
|
LinkEvidenceRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
- finding_id
|
|
- bundle_uri
|
|
- dsse_digest
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
finding_id:
|
|
type: string
|
|
bundle_uri:
|
|
type: string
|
|
format: uri
|
|
description: URI to the evidence bundle
|
|
dsse_digest:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
description: SHA-256 digest of the DSSE envelope
|
|
valid_for:
|
|
type: string
|
|
format: duration
|
|
example: P90D
|
|
description: ISO 8601 duration for validity period
|
|
|
|
LinkEvidenceResponse:
|
|
type: object
|
|
required:
|
|
- success
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
event_id:
|
|
type: string
|
|
format: uuid
|
|
description: Ledger event ID for the linkage
|
|
error:
|
|
type: string
|
|
|
|
EvidenceSnapshotsResponse:
|
|
type: object
|
|
required:
|
|
- finding_id
|
|
- snapshots
|
|
properties:
|
|
finding_id:
|
|
type: string
|
|
snapshots:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EvidenceSnapshot'
|
|
|
|
EvidenceSnapshot:
|
|
type: object
|
|
required:
|
|
- finding_id
|
|
- bundle_uri
|
|
- dsse_digest
|
|
- created_at
|
|
properties:
|
|
finding_id:
|
|
type: string
|
|
bundle_uri:
|
|
type: string
|
|
format: uri
|
|
dsse_digest:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
expires_at:
|
|
type: string
|
|
format: date-time
|
|
ledger_event_id:
|
|
type: string
|
|
format: uuid
|
|
|
|
VerifyEvidenceRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
- finding_id
|
|
- expected_dsse_digest
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
finding_id:
|
|
type: string
|
|
expected_dsse_digest:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
|
|
VerifyEvidenceResponse:
|
|
type: object
|
|
required:
|
|
- verified
|
|
properties:
|
|
verified:
|
|
type: boolean
|
|
snapshot:
|
|
$ref: '#/components/schemas/EvidenceSnapshot'
|
|
error_code:
|
|
type: string
|
|
enum:
|
|
- not_found
|
|
- expired
|
|
- digest_mismatch
|
|
error_message:
|
|
type: string
|
|
|
|
HistoricalExportRequest:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
- entity_type
|
|
- shape
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
entity_type:
|
|
$ref: '#/components/schemas/EntityType'
|
|
shape:
|
|
type: string
|
|
enum:
|
|
- compact
|
|
- standard
|
|
- full
|
|
description: Export shape controlling field inclusion
|
|
at_timestamp:
|
|
type: string
|
|
format: date-time
|
|
at_sequence:
|
|
type: integer
|
|
format: int64
|
|
snapshot_id:
|
|
type: string
|
|
format: uuid
|
|
description: Export from a specific snapshot
|
|
filters:
|
|
$ref: '#/components/schemas/TimeQueryFilters'
|
|
output_format:
|
|
type: string
|
|
enum:
|
|
- json
|
|
- ndjson
|
|
default: json
|
|
page_size:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 5000
|
|
default: 500
|
|
page_token:
|
|
type: string
|
|
filters_hash:
|
|
type: string
|
|
description: Hash of filters for pagination consistency
|
|
|
|
HistoricalExportResponse:
|
|
type: object
|
|
required:
|
|
- query_point
|
|
- entity_type
|
|
- items
|
|
properties:
|
|
query_point:
|
|
$ref: '#/components/schemas/QueryPoint'
|
|
entity_type:
|
|
$ref: '#/components/schemas/EntityType'
|
|
shape:
|
|
type: string
|
|
items:
|
|
type: array
|
|
items:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/FindingExportItem'
|
|
- $ref: '#/components/schemas/VexExportItem'
|
|
- $ref: '#/components/schemas/AdvisoryExportItem'
|
|
- $ref: '#/components/schemas/SbomExportItem'
|
|
next_page_token:
|
|
type: string
|
|
filters_hash:
|
|
type: string
|
|
export_metadata:
|
|
$ref: '#/components/schemas/ExportMetadata'
|
|
|
|
ExportMetadata:
|
|
type: object
|
|
properties:
|
|
total_count:
|
|
type: integer
|
|
format: int64
|
|
exported_count:
|
|
type: integer
|
|
export_duration_ms:
|
|
type: integer
|
|
format: int64
|
|
merkle_root:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
|
|
FindingExportItem:
|
|
type: object
|
|
required:
|
|
- event_sequence
|
|
- observed_at
|
|
- finding_id
|
|
- policy_version
|
|
- status
|
|
- cycle_hash
|
|
properties:
|
|
event_sequence:
|
|
type: integer
|
|
format: int64
|
|
observed_at:
|
|
type: string
|
|
format: date-time
|
|
finding_id:
|
|
type: string
|
|
policy_version:
|
|
type: string
|
|
status:
|
|
type: string
|
|
severity:
|
|
type: number
|
|
cycle_hash:
|
|
type: string
|
|
evidence_bundle_ref:
|
|
type: string
|
|
provenance:
|
|
$ref: '#/components/schemas/ExportProvenance'
|
|
labels:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
VexExportItem:
|
|
type: object
|
|
required:
|
|
- event_sequence
|
|
- observed_at
|
|
- vex_statement_id
|
|
- product_id
|
|
- status
|
|
- cycle_hash
|
|
properties:
|
|
event_sequence:
|
|
type: integer
|
|
format: int64
|
|
observed_at:
|
|
type: string
|
|
format: date-time
|
|
vex_statement_id:
|
|
type: string
|
|
product_id:
|
|
type: string
|
|
status:
|
|
type: string
|
|
statement_type:
|
|
type: string
|
|
known_exploited:
|
|
type: boolean
|
|
cycle_hash:
|
|
type: string
|
|
provenance:
|
|
$ref: '#/components/schemas/ExportProvenance'
|
|
|
|
AdvisoryExportItem:
|
|
type: object
|
|
required:
|
|
- event_sequence
|
|
- published
|
|
- advisory_id
|
|
- source
|
|
- title
|
|
- cycle_hash
|
|
properties:
|
|
event_sequence:
|
|
type: integer
|
|
format: int64
|
|
published:
|
|
type: string
|
|
format: date-time
|
|
advisory_id:
|
|
type: string
|
|
source:
|
|
type: string
|
|
title:
|
|
type: string
|
|
severity:
|
|
type: string
|
|
cvss_score:
|
|
type: number
|
|
cvss_vector:
|
|
type: string
|
|
kev:
|
|
type: boolean
|
|
cycle_hash:
|
|
type: string
|
|
provenance:
|
|
$ref: '#/components/schemas/ExportProvenance'
|
|
|
|
SbomExportItem:
|
|
type: object
|
|
required:
|
|
- event_sequence
|
|
- created_at
|
|
- sbom_id
|
|
- subject_digest
|
|
- sbom_format
|
|
- components_count
|
|
- cycle_hash
|
|
properties:
|
|
event_sequence:
|
|
type: integer
|
|
format: int64
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
sbom_id:
|
|
type: string
|
|
subject_digest:
|
|
type: string
|
|
sbom_format:
|
|
type: string
|
|
components_count:
|
|
type: integer
|
|
has_vulnerabilities:
|
|
type: boolean
|
|
cycle_hash:
|
|
type: string
|
|
provenance:
|
|
$ref: '#/components/schemas/ExportProvenance'
|
|
|
|
ExportProvenance:
|
|
type: object
|
|
properties:
|
|
policy_version:
|
|
type: string
|
|
cycle_hash:
|
|
type: string
|
|
ledger_event_hash:
|
|
type: string
|
|
|
|
StalenessResponse:
|
|
type: object
|
|
required:
|
|
- is_stale
|
|
- checked_at
|
|
properties:
|
|
is_stale:
|
|
type: boolean
|
|
checked_at:
|
|
type: string
|
|
format: date-time
|
|
last_event_at:
|
|
type: string
|
|
format: date-time
|
|
staleness_threshold:
|
|
type: string
|
|
format: duration
|
|
staleness_duration:
|
|
type: string
|
|
format: duration
|
|
by_entity_type:
|
|
type: object
|
|
additionalProperties:
|
|
type: object
|
|
properties:
|
|
is_stale:
|
|
type: boolean
|
|
last_event_at:
|
|
type: string
|
|
format: date-time
|
|
events_behind:
|
|
type: integer
|
|
format: int64
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error_code
|
|
- message
|
|
properties:
|
|
error_code:
|
|
type: string
|
|
message:
|
|
type: string
|
|
details:
|
|
type: object
|
|
additionalProperties: true
|
|
request_id:
|
|
type: string
|
|
format: uuid
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Invalid request parameters
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
Unauthorized:
|
|
description: Authentication required
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
Forbidden:
|
|
description: Insufficient permissions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
NotFound:
|
|
description: Resource not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
apiKey:
|
|
type: apiKey
|
|
in: header
|
|
name: X-API-Key
|
|
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|