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
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build 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
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (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 / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
- Implement comprehensive tests for PhpFrameworkSurface, covering scenarios such as empty surfaces, presence of routes, controllers, middlewares, CLI commands, cron jobs, and event listeners. - Validate metadata creation for route counts, HTTP methods, protected and public routes, and route patterns. - Introduce tests for PhpPharScanner, including handling of non-existent files, null or empty paths, invalid PHAR files, and minimal PHAR structures. - Ensure correct computation of SHA256 for valid PHAR files and validate the properties of PhpPharArchive, PhpPharEntry, and PhpPharScanResult.
1584 lines
41 KiB
YAML
1584 lines
41 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: StellaOps Findings Ledger API
|
|
version: 1.0.0
|
|
description: |
|
|
OpenAPI specification for the Findings Ledger service.
|
|
Unblocks LEDGER-OAS-61-001-DEV through LEDGER-OAS-63-001-DEV.
|
|
contact:
|
|
name: StellaOps API Team
|
|
email: api@stella-ops.org
|
|
license:
|
|
name: AGPL-3.0-or-later
|
|
identifier: AGPL-3.0-or-later
|
|
|
|
servers:
|
|
- url: https://api.stella-ops.org/v1
|
|
description: Production
|
|
- url: https://api.staging.stella-ops.org/v1
|
|
description: Staging
|
|
|
|
tags:
|
|
- name: findings
|
|
description: Finding management operations
|
|
- name: projections
|
|
description: Finding projections and views
|
|
- name: evidence
|
|
description: Evidence lookups and links
|
|
- name: snapshots
|
|
description: Time-travel and snapshot operations
|
|
- name: attestation
|
|
description: Attestation and verification
|
|
- name: export
|
|
description: Export and reporting
|
|
|
|
paths:
|
|
/findings:
|
|
get:
|
|
operationId: listFindings
|
|
summary: List findings with pagination and filtering
|
|
tags: [findings]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/ProjectId'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
- $ref: '#/components/parameters/SortBy'
|
|
- $ref: '#/components/parameters/SortOrder'
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/FindingStatus'
|
|
- name: severity
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Severity'
|
|
- name: component_purl
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by component PURL pattern
|
|
- name: vulnerability_id
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by CVE or vulnerability ID
|
|
- 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: Paginated list of findings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/FindingsListResponse'
|
|
headers:
|
|
ETag:
|
|
schema:
|
|
type: string
|
|
description: Entity tag for caching
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
|
|
post:
|
|
operationId: createFinding
|
|
summary: Create a new finding
|
|
tags: [findings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateFindingRequest'
|
|
responses:
|
|
'201':
|
|
description: Finding created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Finding'
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
|
|
/findings/{findingId}:
|
|
get:
|
|
operationId: getFinding
|
|
summary: Get finding by ID
|
|
tags: [findings]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
- name: include
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum: [evidence, attestations, history, projections]
|
|
description: Related data to include
|
|
responses:
|
|
'200':
|
|
description: Finding details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Finding'
|
|
headers:
|
|
ETag:
|
|
schema:
|
|
type: string
|
|
'304':
|
|
description: Not modified
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
patch:
|
|
operationId: updateFinding
|
|
summary: Update finding status or metadata
|
|
tags: [findings]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
- name: If-Match
|
|
in: header
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: ETag for optimistic concurrency
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateFindingRequest'
|
|
responses:
|
|
'200':
|
|
description: Finding updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Finding'
|
|
'412':
|
|
$ref: '#/components/responses/PreconditionFailed'
|
|
|
|
/findings/{findingId}/evidence:
|
|
get:
|
|
operationId: getFindingEvidence
|
|
summary: Get evidence linked to a finding
|
|
tags: [findings, evidence]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
- name: artifact_type
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum: [sbom, vex, scan_result, attestation, callgraph, runtime_facts]
|
|
responses:
|
|
'200':
|
|
description: Evidence list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EvidenceListResponse'
|
|
|
|
/findings/{findingId}/attestations:
|
|
get:
|
|
operationId: getFindingAttestations
|
|
summary: Get attestations for a finding
|
|
tags: [findings, attestation]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
responses:
|
|
'200':
|
|
description: Attestation list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AttestationListResponse'
|
|
|
|
/findings/{findingId}/attestation-pointers:
|
|
get:
|
|
operationId: getFindingAttestationPointers
|
|
summary: Get attestation pointers linking finding to verification reports and attestation envelopes
|
|
description: |
|
|
Returns all attestation pointers for a finding. Attestation pointers link findings
|
|
to verification reports, DSSE envelopes, SLSA provenance, VEX attestations, and other
|
|
cryptographic evidence for explainability and audit trails.
|
|
tags: [findings, attestation]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: List of attestation pointers
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AttestationPointer'
|
|
examples:
|
|
verified_finding:
|
|
summary: Finding with verified DSSE envelope
|
|
value:
|
|
- pointer_id: "a1b2c3d4-5678-90ab-cdef-123456789abc"
|
|
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
|
|
attestation_type: "DsseEnvelope"
|
|
relationship: "VerifiedBy"
|
|
attestation_ref:
|
|
digest: "sha256:abc123def456789012345678901234567890123456789012345678901234abcd"
|
|
storage_uri: "s3://attestations/envelope.json"
|
|
payload_type: "application/vnd.in-toto+json"
|
|
predicate_type: "https://slsa.dev/provenance/v1"
|
|
signer_info:
|
|
issuer: "https://fulcio.sigstore.dev"
|
|
subject: "build@stella-ops.org"
|
|
verification_result:
|
|
verified: true
|
|
verified_at: "2025-01-01T12:00:00Z"
|
|
verifier: "cosign"
|
|
verifier_version: "2.2.3"
|
|
checks:
|
|
- check_type: "SignatureValid"
|
|
passed: true
|
|
- check_type: "CertificateValid"
|
|
passed: true
|
|
created_at: "2025-01-01T10:00:00Z"
|
|
created_by: "scanner-service"
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/findings/{findingId}/attestation-summary:
|
|
get:
|
|
operationId: getFindingAttestationSummary
|
|
summary: Get summary of attestations for a finding
|
|
description: Returns aggregate counts and verification status for all attestations linked to a finding.
|
|
tags: [findings, attestation]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: Attestation summary
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AttestationSummary'
|
|
examples:
|
|
partially_verified:
|
|
summary: Finding with mixed verification status
|
|
value:
|
|
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
|
|
attestation_count: 3
|
|
verified_count: 2
|
|
latest_attestation: "2025-01-01T12:00:00Z"
|
|
attestation_types: ["DsseEnvelope", "SlsaProvenance", "VexAttestation"]
|
|
overall_verification_status: "PartiallyVerified"
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/attestation-pointers:
|
|
post:
|
|
operationId: createAttestationPointer
|
|
summary: Create an attestation pointer linking a finding to an attestation artifact
|
|
description: |
|
|
Creates a pointer linking a finding to a verification report, DSSE envelope, or other
|
|
attestation artifact. This enables explainability and cryptographic audit trails.
|
|
The operation is idempotent - creating the same pointer twice returns the existing record.
|
|
tags: [attestation]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateAttestationPointerRequest'
|
|
examples:
|
|
dsse_envelope:
|
|
summary: Link finding to DSSE envelope
|
|
value:
|
|
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
|
|
attestation_type: "DsseEnvelope"
|
|
relationship: "VerifiedBy"
|
|
attestation_ref:
|
|
digest: "sha256:abc123def456789012345678901234567890123456789012345678901234abcd"
|
|
storage_uri: "s3://attestations/envelope.json"
|
|
payload_type: "application/vnd.in-toto+json"
|
|
predicate_type: "https://slsa.dev/provenance/v1"
|
|
verification_result:
|
|
verified: true
|
|
verified_at: "2025-01-01T12:00:00Z"
|
|
verifier: "cosign"
|
|
responses:
|
|
'201':
|
|
description: Attestation pointer created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateAttestationPointerResponse'
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
'200':
|
|
description: Attestation pointer already exists (idempotent)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateAttestationPointerResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/attestation-pointers/{pointerId}:
|
|
get:
|
|
operationId: getAttestationPointer
|
|
summary: Get attestation pointer by ID
|
|
tags: [attestation]
|
|
parameters:
|
|
- name: pointerId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: Attestation pointer details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AttestationPointer'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/attestation-pointers/{pointerId}/verification:
|
|
put:
|
|
operationId: updateAttestationPointerVerification
|
|
summary: Update verification result for an attestation pointer
|
|
description: Updates or adds verification result to an existing attestation pointer.
|
|
tags: [attestation]
|
|
parameters:
|
|
- name: pointerId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- $ref: '#/components/parameters/TenantId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- verification_result
|
|
properties:
|
|
verification_result:
|
|
$ref: '#/components/schemas/VerificationResult'
|
|
responses:
|
|
'204':
|
|
description: Verification result updated
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/attestation-pointers/search:
|
|
post:
|
|
operationId: searchAttestationPointers
|
|
summary: Search attestation pointers with filters
|
|
description: |
|
|
Search for attestation pointers across findings using various filters.
|
|
Useful for auditing, compliance reporting, and finding findings with specific
|
|
attestation characteristics.
|
|
tags: [attestation]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AttestationPointerSearchRequest'
|
|
examples:
|
|
find_verified:
|
|
summary: Find all verified attestation pointers
|
|
value:
|
|
verification_status: "Verified"
|
|
limit: 100
|
|
find_by_type:
|
|
summary: Find SLSA provenance attestations
|
|
value:
|
|
attestation_types: ["SlsaProvenance"]
|
|
created_after: "2025-01-01T00:00:00Z"
|
|
find_by_signer:
|
|
summary: Find attestations by signer identity
|
|
value:
|
|
signer_identity: "build@stella-ops.org"
|
|
verification_status: "Verified"
|
|
responses:
|
|
'200':
|
|
description: Search results
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AttestationPointerSearchResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/findings/{findingId}/history:
|
|
get:
|
|
operationId: getFindingHistory
|
|
summary: Get finding status history
|
|
tags: [findings]
|
|
parameters:
|
|
- $ref: '#/components/parameters/FindingId'
|
|
responses:
|
|
'200':
|
|
description: History entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HistoryListResponse'
|
|
|
|
/projections:
|
|
get:
|
|
operationId: listProjections
|
|
summary: List available projections
|
|
tags: [projections]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: Projection list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProjectionListResponse'
|
|
|
|
/projections/{projectionId}:
|
|
get:
|
|
operationId: getProjection
|
|
summary: Get projection data
|
|
tags: [projections]
|
|
parameters:
|
|
- name: projectionId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: filter
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: JSON filter expression
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
responses:
|
|
'200':
|
|
description: Projection data
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProjectionDataResponse'
|
|
|
|
/snapshots:
|
|
get:
|
|
operationId: listSnapshots
|
|
summary: List available snapshots
|
|
tags: [snapshots]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/ProjectId'
|
|
responses:
|
|
'200':
|
|
description: Snapshot list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotListResponse'
|
|
|
|
post:
|
|
operationId: createSnapshot
|
|
summary: Create a point-in-time snapshot
|
|
tags: [snapshots]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSnapshotRequest'
|
|
responses:
|
|
'202':
|
|
description: Snapshot creation accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotJob'
|
|
|
|
/snapshots/{snapshotId}:
|
|
get:
|
|
operationId: getSnapshot
|
|
summary: Get snapshot details
|
|
tags: [snapshots]
|
|
parameters:
|
|
- name: snapshotId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'200':
|
|
description: Snapshot details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
|
|
/snapshots/{snapshotId}/findings:
|
|
get:
|
|
operationId: getSnapshotFindings
|
|
summary: Get findings from a snapshot (time-travel query)
|
|
tags: [snapshots]
|
|
parameters:
|
|
- name: snapshotId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/PageToken'
|
|
responses:
|
|
'200':
|
|
description: Findings at snapshot point
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/FindingsListResponse'
|
|
|
|
/evidence:
|
|
get:
|
|
operationId: listEvidence
|
|
summary: List evidence artifacts
|
|
tags: [evidence]
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- name: artifact_type
|
|
in: query
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
- name: digest
|
|
in: query
|
|
schema:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
responses:
|
|
'200':
|
|
description: Evidence list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EvidenceListResponse'
|
|
|
|
/evidence/{evidenceId}:
|
|
get:
|
|
operationId: getEvidence
|
|
summary: Get evidence artifact
|
|
tags: [evidence]
|
|
parameters:
|
|
- name: evidenceId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'200':
|
|
description: Evidence details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EvidenceArtifact'
|
|
|
|
/export:
|
|
post:
|
|
operationId: createExport
|
|
summary: Create export job for findings
|
|
tags: [export]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateExportRequest'
|
|
responses:
|
|
'202':
|
|
description: Export job created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ExportJob'
|
|
|
|
/export/{exportId}:
|
|
get:
|
|
operationId: getExport
|
|
summary: Get export job status and download
|
|
tags: [export]
|
|
parameters:
|
|
- name: exportId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'200':
|
|
description: Export job details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ExportJob'
|
|
|
|
/.well-known/openapi:
|
|
get:
|
|
operationId: getOpenApiSpec
|
|
summary: Get OpenAPI specification
|
|
description: Returns the OpenAPI specification for this API
|
|
responses:
|
|
'200':
|
|
description: OpenAPI specification
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
application/yaml:
|
|
schema:
|
|
type: object
|
|
|
|
components:
|
|
parameters:
|
|
TenantId:
|
|
name: X-Tenant-ID
|
|
in: header
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: Tenant identifier
|
|
|
|
ProjectId:
|
|
name: X-Project-ID
|
|
in: header
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: Project identifier
|
|
|
|
FindingId:
|
|
name: findingId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: Finding identifier
|
|
|
|
PageSize:
|
|
name: page_size
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
default: 100
|
|
|
|
PageToken:
|
|
name: page_token
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Continuation token for pagination
|
|
|
|
SortBy:
|
|
name: sort_by
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [created_at, updated_at, severity, status]
|
|
default: created_at
|
|
|
|
SortOrder:
|
|
name: sort_order
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [asc, desc]
|
|
default: desc
|
|
|
|
schemas:
|
|
Finding:
|
|
type: object
|
|
required:
|
|
- id
|
|
- tenant_id
|
|
- vulnerability_id
|
|
- component
|
|
- status
|
|
- severity
|
|
- created_at
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
tenant_id:
|
|
type: string
|
|
format: uuid
|
|
project_id:
|
|
type: string
|
|
format: uuid
|
|
vulnerability_id:
|
|
type: string
|
|
description: CVE ID or vulnerability identifier
|
|
component:
|
|
$ref: '#/components/schemas/Component'
|
|
status:
|
|
$ref: '#/components/schemas/FindingStatus'
|
|
severity:
|
|
$ref: '#/components/schemas/Severity'
|
|
cvss_score:
|
|
type: number
|
|
minimum: 0
|
|
maximum: 10
|
|
epss_score:
|
|
type: number
|
|
minimum: 0
|
|
maximum: 1
|
|
kev_listed:
|
|
type: boolean
|
|
reachability:
|
|
$ref: '#/components/schemas/ReachabilityInfo'
|
|
vex_status:
|
|
type: string
|
|
enum: [not_affected, affected, fixed, under_investigation]
|
|
fix_available:
|
|
type: boolean
|
|
fix_version:
|
|
type: string
|
|
source:
|
|
type: string
|
|
description: Source of the finding (scanner name)
|
|
labels:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
first_seen_at:
|
|
type: string
|
|
format: date-time
|
|
last_seen_at:
|
|
type: string
|
|
format: date-time
|
|
evidence_refs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EvidenceRef'
|
|
attestation_refs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AttestationRef'
|
|
|
|
FindingStatus:
|
|
type: string
|
|
enum:
|
|
- open
|
|
- triaged
|
|
- in_progress
|
|
- resolved
|
|
- ignored
|
|
- false_positive
|
|
|
|
Severity:
|
|
type: string
|
|
enum:
|
|
- critical
|
|
- high
|
|
- medium
|
|
- low
|
|
- info
|
|
|
|
Component:
|
|
type: object
|
|
required:
|
|
- purl
|
|
properties:
|
|
purl:
|
|
type: string
|
|
description: Package URL
|
|
name:
|
|
type: string
|
|
version:
|
|
type: string
|
|
ecosystem:
|
|
type: string
|
|
digest:
|
|
type: string
|
|
|
|
ReachabilityInfo:
|
|
type: object
|
|
properties:
|
|
state:
|
|
type: string
|
|
enum: [reachable, unreachable, potentially_reachable, unknown]
|
|
confidence:
|
|
type: number
|
|
minimum: 0
|
|
maximum: 1
|
|
entry_points:
|
|
type: array
|
|
items:
|
|
type: string
|
|
|
|
EvidenceRef:
|
|
type: object
|
|
required:
|
|
- id
|
|
- digest
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
artifact_type:
|
|
type: string
|
|
digest:
|
|
type: string
|
|
uri:
|
|
type: string
|
|
format: uri
|
|
|
|
AttestationRef:
|
|
type: object
|
|
required:
|
|
- id
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
type:
|
|
type: string
|
|
digest:
|
|
type: string
|
|
|
|
CreateFindingRequest:
|
|
type: object
|
|
required:
|
|
- vulnerability_id
|
|
- component
|
|
- severity
|
|
properties:
|
|
vulnerability_id:
|
|
type: string
|
|
component:
|
|
$ref: '#/components/schemas/Component'
|
|
severity:
|
|
$ref: '#/components/schemas/Severity'
|
|
source:
|
|
type: string
|
|
labels:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
evidence_refs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EvidenceRef'
|
|
|
|
UpdateFindingRequest:
|
|
type: object
|
|
properties:
|
|
status:
|
|
$ref: '#/components/schemas/FindingStatus'
|
|
severity:
|
|
$ref: '#/components/schemas/Severity'
|
|
labels:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
notes:
|
|
type: string
|
|
|
|
FindingsListResponse:
|
|
type: object
|
|
required:
|
|
- findings
|
|
- total_count
|
|
properties:
|
|
findings:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Finding'
|
|
total_count:
|
|
type: integer
|
|
next_page_token:
|
|
type: string
|
|
|
|
EvidenceArtifact:
|
|
type: object
|
|
required:
|
|
- id
|
|
- artifact_type
|
|
- digest
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
artifact_type:
|
|
type: string
|
|
digest:
|
|
type: string
|
|
content_type:
|
|
type: string
|
|
size_bytes:
|
|
type: integer
|
|
storage_uri:
|
|
type: string
|
|
format: uri
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
provenance:
|
|
type: object
|
|
|
|
EvidenceListResponse:
|
|
type: object
|
|
required:
|
|
- evidence
|
|
properties:
|
|
evidence:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EvidenceArtifact'
|
|
total_count:
|
|
type: integer
|
|
next_page_token:
|
|
type: string
|
|
|
|
AttestationListResponse:
|
|
type: object
|
|
required:
|
|
- attestations
|
|
properties:
|
|
attestations:
|
|
type: array
|
|
items:
|
|
type: object
|
|
total_count:
|
|
type: integer
|
|
|
|
AttestationPointer:
|
|
type: object
|
|
required:
|
|
- pointer_id
|
|
- finding_id
|
|
- attestation_type
|
|
- relationship
|
|
- attestation_ref
|
|
- created_at
|
|
- created_by
|
|
properties:
|
|
pointer_id:
|
|
type: string
|
|
format: uuid
|
|
finding_id:
|
|
type: string
|
|
attestation_type:
|
|
type: string
|
|
enum:
|
|
- VerificationReport
|
|
- DsseEnvelope
|
|
- SlsaProvenance
|
|
- VexAttestation
|
|
- SbomAttestation
|
|
- ScanAttestation
|
|
- PolicyAttestation
|
|
- ApprovalAttestation
|
|
relationship:
|
|
type: string
|
|
enum:
|
|
- VerifiedBy
|
|
- AttestedBy
|
|
- SignedBy
|
|
- ApprovedBy
|
|
- DerivedFrom
|
|
attestation_ref:
|
|
$ref: '#/components/schemas/AttestationRefDetail'
|
|
verification_result:
|
|
$ref: '#/components/schemas/VerificationResult'
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
created_by:
|
|
type: string
|
|
metadata:
|
|
type: object
|
|
additionalProperties: true
|
|
ledger_event_id:
|
|
type: string
|
|
format: uuid
|
|
|
|
AttestationRefDetail:
|
|
type: object
|
|
required:
|
|
- digest
|
|
properties:
|
|
digest:
|
|
type: string
|
|
pattern: '^sha256:[a-f0-9]{64}$'
|
|
attestation_id:
|
|
type: string
|
|
format: uuid
|
|
storage_uri:
|
|
type: string
|
|
format: uri
|
|
payload_type:
|
|
type: string
|
|
description: DSSE payload type (e.g., application/vnd.in-toto+json)
|
|
predicate_type:
|
|
type: string
|
|
description: SLSA/in-toto predicate type URI
|
|
subject_digests:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Digests of subjects covered by this attestation
|
|
signer_info:
|
|
$ref: '#/components/schemas/SignerInfo'
|
|
rekor_entry:
|
|
$ref: '#/components/schemas/RekorEntryRef'
|
|
|
|
SignerInfo:
|
|
type: object
|
|
properties:
|
|
key_id:
|
|
type: string
|
|
issuer:
|
|
type: string
|
|
description: OIDC issuer for keyless signing
|
|
subject:
|
|
type: string
|
|
description: OIDC subject/identity
|
|
certificate_chain:
|
|
type: array
|
|
items:
|
|
type: string
|
|
signed_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
RekorEntryRef:
|
|
type: object
|
|
properties:
|
|
log_index:
|
|
type: integer
|
|
format: int64
|
|
log_id:
|
|
type: string
|
|
uuid:
|
|
type: string
|
|
integrated_time:
|
|
type: integer
|
|
format: int64
|
|
description: Unix timestamp when entry was integrated into the log
|
|
|
|
VerificationResult:
|
|
type: object
|
|
required:
|
|
- verified
|
|
- verified_at
|
|
properties:
|
|
verified:
|
|
type: boolean
|
|
verified_at:
|
|
type: string
|
|
format: date-time
|
|
verifier:
|
|
type: string
|
|
description: Verification tool name (e.g., cosign, notation)
|
|
verifier_version:
|
|
type: string
|
|
policy_ref:
|
|
type: string
|
|
description: Reference to verification policy used
|
|
checks:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/VerificationCheck'
|
|
warnings:
|
|
type: array
|
|
items:
|
|
type: string
|
|
errors:
|
|
type: array
|
|
items:
|
|
type: string
|
|
|
|
VerificationCheck:
|
|
type: object
|
|
required:
|
|
- check_type
|
|
- passed
|
|
properties:
|
|
check_type:
|
|
type: string
|
|
enum:
|
|
- SignatureValid
|
|
- CertificateValid
|
|
- CertificateNotExpired
|
|
- CertificateNotRevoked
|
|
- RekorEntryValid
|
|
- TimestampValid
|
|
- PolicyMet
|
|
- IdentityVerified
|
|
- IssuerTrusted
|
|
passed:
|
|
type: boolean
|
|
details:
|
|
type: string
|
|
evidence:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
AttestationSummary:
|
|
type: object
|
|
required:
|
|
- finding_id
|
|
- attestation_count
|
|
- verified_count
|
|
- attestation_types
|
|
- overall_verification_status
|
|
properties:
|
|
finding_id:
|
|
type: string
|
|
attestation_count:
|
|
type: integer
|
|
verified_count:
|
|
type: integer
|
|
latest_attestation:
|
|
type: string
|
|
format: date-time
|
|
attestation_types:
|
|
type: array
|
|
items:
|
|
type: string
|
|
overall_verification_status:
|
|
type: string
|
|
enum:
|
|
- AllVerified
|
|
- PartiallyVerified
|
|
- NoneVerified
|
|
- NoAttestations
|
|
|
|
CreateAttestationPointerRequest:
|
|
type: object
|
|
required:
|
|
- finding_id
|
|
- attestation_type
|
|
- relationship
|
|
- attestation_ref
|
|
properties:
|
|
finding_id:
|
|
type: string
|
|
attestation_type:
|
|
type: string
|
|
enum:
|
|
- VerificationReport
|
|
- DsseEnvelope
|
|
- SlsaProvenance
|
|
- VexAttestation
|
|
- SbomAttestation
|
|
- ScanAttestation
|
|
- PolicyAttestation
|
|
- ApprovalAttestation
|
|
relationship:
|
|
type: string
|
|
enum:
|
|
- VerifiedBy
|
|
- AttestedBy
|
|
- SignedBy
|
|
- ApprovedBy
|
|
- DerivedFrom
|
|
attestation_ref:
|
|
$ref: '#/components/schemas/AttestationRefDetail'
|
|
verification_result:
|
|
$ref: '#/components/schemas/VerificationResult'
|
|
created_by:
|
|
type: string
|
|
metadata:
|
|
type: object
|
|
additionalProperties: true
|
|
|
|
CreateAttestationPointerResponse:
|
|
type: object
|
|
required:
|
|
- success
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
pointer_id:
|
|
type: string
|
|
format: uuid
|
|
ledger_event_id:
|
|
type: string
|
|
format: uuid
|
|
error:
|
|
type: string
|
|
|
|
AttestationPointerSearchRequest:
|
|
type: object
|
|
properties:
|
|
finding_ids:
|
|
type: array
|
|
items:
|
|
type: string
|
|
attestation_types:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- VerificationReport
|
|
- DsseEnvelope
|
|
- SlsaProvenance
|
|
- VexAttestation
|
|
- SbomAttestation
|
|
- ScanAttestation
|
|
- PolicyAttestation
|
|
- ApprovalAttestation
|
|
verification_status:
|
|
type: string
|
|
enum:
|
|
- Any
|
|
- Verified
|
|
- Unverified
|
|
- Failed
|
|
created_after:
|
|
type: string
|
|
format: date-time
|
|
created_before:
|
|
type: string
|
|
format: date-time
|
|
signer_identity:
|
|
type: string
|
|
description: Filter by signer subject/identity
|
|
predicate_type:
|
|
type: string
|
|
description: Filter by SLSA/in-toto predicate type
|
|
limit:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
default: 100
|
|
offset:
|
|
type: integer
|
|
minimum: 0
|
|
default: 0
|
|
|
|
AttestationPointerSearchResponse:
|
|
type: object
|
|
required:
|
|
- pointers
|
|
- total_count
|
|
properties:
|
|
pointers:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AttestationPointer'
|
|
total_count:
|
|
type: integer
|
|
|
|
HistoryListResponse:
|
|
type: object
|
|
required:
|
|
- entries
|
|
properties:
|
|
entries:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
actor:
|
|
type: string
|
|
action:
|
|
type: string
|
|
changes:
|
|
type: object
|
|
|
|
ProjectionListResponse:
|
|
type: object
|
|
required:
|
|
- projections
|
|
properties:
|
|
projections:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
|
|
ProjectionDataResponse:
|
|
type: object
|
|
required:
|
|
- data
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
type: object
|
|
total_count:
|
|
type: integer
|
|
next_page_token:
|
|
type: string
|
|
|
|
Snapshot:
|
|
type: object
|
|
required:
|
|
- id
|
|
- created_at
|
|
- status
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
point_in_time:
|
|
type: string
|
|
format: date-time
|
|
status:
|
|
type: string
|
|
enum: [pending, ready, expired, failed]
|
|
finding_count:
|
|
type: integer
|
|
digest:
|
|
type: string
|
|
|
|
SnapshotListResponse:
|
|
type: object
|
|
required:
|
|
- snapshots
|
|
properties:
|
|
snapshots:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
total_count:
|
|
type: integer
|
|
|
|
CreateSnapshotRequest:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
point_in_time:
|
|
type: string
|
|
format: date-time
|
|
description: Optional specific point in time (defaults to now)
|
|
|
|
SnapshotJob:
|
|
type: object
|
|
required:
|
|
- id
|
|
- status
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
status:
|
|
type: string
|
|
enum: [queued, processing, completed, failed]
|
|
snapshot_id:
|
|
type: string
|
|
format: uuid
|
|
progress:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 100
|
|
|
|
CreateExportRequest:
|
|
type: object
|
|
properties:
|
|
format:
|
|
type: string
|
|
enum: [json, csv, sarif, cyclonedx, spdx]
|
|
default: json
|
|
filters:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/FindingStatus'
|
|
severity:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Severity'
|
|
created_after:
|
|
type: string
|
|
format: date-time
|
|
created_before:
|
|
type: string
|
|
format: date-time
|
|
|
|
ExportJob:
|
|
type: object
|
|
required:
|
|
- id
|
|
- status
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
status:
|
|
type: string
|
|
enum: [queued, processing, completed, failed]
|
|
format:
|
|
type: string
|
|
download_url:
|
|
type: string
|
|
format: uri
|
|
expires_at:
|
|
type: string
|
|
format: date-time
|
|
finding_count:
|
|
type: integer
|
|
|
|
Error:
|
|
type: object
|
|
required:
|
|
- code
|
|
- message
|
|
properties:
|
|
code:
|
|
type: string
|
|
message:
|
|
type: string
|
|
details:
|
|
type: object
|
|
trace_id:
|
|
type: string
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
Unauthorized:
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
Forbidden:
|
|
description: Forbidden
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
NotFound:
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
Conflict:
|
|
description: Conflict
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
PreconditionFailed:
|
|
description: Precondition failed (ETag mismatch)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
|
|
oauth2:
|
|
type: oauth2
|
|
flows:
|
|
clientCredentials:
|
|
tokenUrl: https://auth.stella-ops.org/oauth/token
|
|
scopes:
|
|
findings:read: Read findings
|
|
findings:write: Write findings
|
|
evidence:read: Read evidence
|
|
snapshots:read: Read snapshots
|
|
snapshots:write: Create snapshots
|
|
export:write: Create exports
|
|
|
|
security:
|
|
- bearerAuth: []
|
|
- oauth2: [findings:read]
|