344 lines
9.5 KiB
YAML
344 lines
9.5 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Stella Ops Artifact Store API
|
|
description: |
|
|
Unified artifact storage API with bom-ref support.
|
|
|
|
Sprint: SPRINT_20260118_017_Evidence_artifact_store_unification (AS-005, AS-007)
|
|
|
|
## Overview
|
|
|
|
The Artifact Store API provides unified storage and retrieval of evidence artifacts
|
|
(SBOMs, VEX, DSSE envelopes, Rekor proofs) using a bom-ref based path convention.
|
|
|
|
## Path Convention
|
|
|
|
Artifacts are stored at: `/artifacts/{bom-ref-encoded}/{serialNumber}/{artifactId}.json`
|
|
|
|
Where:
|
|
- `bom-ref-encoded`: URL-safe base64 encoded PURL
|
|
- `serialNumber`: CycloneDX serial number (URN UUID)
|
|
- `artifactId`: Unique artifact identifier
|
|
|
|
version: 1.0.0
|
|
contact:
|
|
name: Stella Ops Team
|
|
license:
|
|
name: AGPL-3.0-or-later
|
|
|
|
servers:
|
|
- url: /api/v1
|
|
description: API v1
|
|
|
|
tags:
|
|
- name: Artifacts
|
|
description: Artifact storage and retrieval operations
|
|
- name: Evidence
|
|
description: Evidence submission operations
|
|
|
|
paths:
|
|
/evidence:
|
|
post:
|
|
operationId: submitEvidence
|
|
tags: [Evidence]
|
|
summary: Submit evidence artifact
|
|
description: |
|
|
Ingests DSSE envelopes with SBOM references and stores in unified ArtifactStore.
|
|
Extracts and validates bom_ref and cyclonedx_serial from the envelope.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EvidenceSubmissionRequest'
|
|
responses:
|
|
'201':
|
|
description: Evidence stored successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ArtifactMetadata'
|
|
'400':
|
|
description: Invalid request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'409':
|
|
description: Artifact already exists
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ArtifactMetadata'
|
|
|
|
/artifacts:
|
|
get:
|
|
operationId: listArtifacts
|
|
tags: [Artifacts]
|
|
summary: List artifacts by bom-ref
|
|
description: |
|
|
Returns paginated list of artifacts for a given bom-ref.
|
|
Supports filtering by serial_number and time range.
|
|
parameters:
|
|
- name: bom_ref
|
|
in: query
|
|
required: true
|
|
description: Package URL or component reference
|
|
schema:
|
|
type: string
|
|
example: "pkg:docker/acme/api@sha256:abc123"
|
|
- name: serial_number
|
|
in: query
|
|
required: false
|
|
description: CycloneDX serial number filter
|
|
schema:
|
|
type: string
|
|
example: "urn:uuid:12345678-1234-1234-1234-123456789012"
|
|
- name: from
|
|
in: query
|
|
required: false
|
|
description: Start date filter (ISO 8601)
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: to
|
|
in: query
|
|
required: false
|
|
description: End date filter (ISO 8601)
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: limit
|
|
in: query
|
|
required: false
|
|
description: Maximum results per page (default 50, max 1000)
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 1000
|
|
default: 50
|
|
- name: continuation_token
|
|
in: query
|
|
required: false
|
|
description: Token for pagination
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Artifacts retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ArtifactListResponse'
|
|
|
|
/artifacts/{artifact_id}:
|
|
get:
|
|
operationId: getArtifact
|
|
tags: [Artifacts]
|
|
summary: Get artifact by ID
|
|
description: Returns artifact metadata and optionally content
|
|
parameters:
|
|
- name: artifact_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- name: include_content
|
|
in: query
|
|
required: false
|
|
description: Include artifact content in response
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
'200':
|
|
description: Artifact retrieved
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ArtifactResponse'
|
|
'404':
|
|
description: Artifact not found
|
|
|
|
delete:
|
|
operationId: deleteArtifact
|
|
tags: [Artifacts]
|
|
summary: Delete artifact (soft delete)
|
|
description: Marks artifact as deleted without removing from storage
|
|
parameters:
|
|
- name: artifact_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'204':
|
|
description: Artifact deleted
|
|
'404':
|
|
description: Artifact not found
|
|
|
|
/artifacts/{artifact_id}/content:
|
|
get:
|
|
operationId: getArtifactContent
|
|
tags: [Artifacts]
|
|
summary: Get artifact content
|
|
description: Returns the raw artifact content
|
|
parameters:
|
|
- name: artifact_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'200':
|
|
description: Artifact content
|
|
content:
|
|
application/octet-stream:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
application/vnd.dsse+json:
|
|
schema:
|
|
type: object
|
|
application/vnd.cyclonedx+json:
|
|
schema:
|
|
type: object
|
|
'404':
|
|
description: Artifact not found
|
|
|
|
components:
|
|
schemas:
|
|
EvidenceSubmissionRequest:
|
|
type: object
|
|
required:
|
|
- bom_ref
|
|
properties:
|
|
bom_ref:
|
|
type: string
|
|
description: Package URL or component reference
|
|
example: "pkg:docker/acme/api@sha256:abc123def456"
|
|
cyclonedx_serial:
|
|
type: string
|
|
description: CycloneDX serial number (URN UUID)
|
|
example: "urn:uuid:12345678-1234-1234-1234-123456789012"
|
|
dsse_uri:
|
|
type: string
|
|
description: URI to DSSE envelope (s3://, file://, https://)
|
|
example: "s3://evidence-bucket/path/to/envelope.json"
|
|
rekor_uuid:
|
|
type: string
|
|
description: Rekor log entry UUID
|
|
example: "f1a2b3c4d5e6f7a8"
|
|
content:
|
|
type: string
|
|
format: byte
|
|
description: Base64-encoded artifact content (alternative to dsse_uri)
|
|
content_type:
|
|
type: string
|
|
description: MIME type of content
|
|
example: "application/vnd.dsse+json"
|
|
metadata:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Additional metadata key-value pairs
|
|
|
|
ArtifactMetadata:
|
|
type: object
|
|
required:
|
|
- artifact_id
|
|
- bom_ref
|
|
- storage_key
|
|
- sha256
|
|
- created_at
|
|
properties:
|
|
artifact_id:
|
|
type: string
|
|
format: uuid
|
|
description: Unique artifact identifier
|
|
bom_ref:
|
|
type: string
|
|
description: Package URL or component reference
|
|
serial_number:
|
|
type: string
|
|
nullable: true
|
|
description: CycloneDX serial number
|
|
storage_key:
|
|
type: string
|
|
description: Storage path for artifact
|
|
content_type:
|
|
type: string
|
|
description: MIME type
|
|
size_bytes:
|
|
type: integer
|
|
format: int64
|
|
description: Content size in bytes
|
|
sha256:
|
|
type: string
|
|
description: SHA-256 hash of content
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
description: Creation timestamp
|
|
rekor_uuid:
|
|
type: string
|
|
nullable: true
|
|
description: Rekor log entry UUID if linked
|
|
metadata:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Additional metadata
|
|
|
|
ArtifactListResponse:
|
|
type: object
|
|
required:
|
|
- artifacts
|
|
- total
|
|
properties:
|
|
artifacts:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ArtifactMetadata'
|
|
total:
|
|
type: integer
|
|
description: Total matching artifacts
|
|
continuation_token:
|
|
type: string
|
|
nullable: true
|
|
description: Token for next page
|
|
|
|
ArtifactResponse:
|
|
allOf:
|
|
- $ref: '#/components/schemas/ArtifactMetadata'
|
|
- type: object
|
|
properties:
|
|
content:
|
|
type: string
|
|
format: byte
|
|
nullable: true
|
|
description: Base64-encoded content (if include_content=true)
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error
|
|
- message
|
|
properties:
|
|
error:
|
|
type: string
|
|
description: Error code
|
|
message:
|
|
type: string
|
|
description: Human-readable error message
|
|
details:
|
|
type: object
|
|
additionalProperties: true
|
|
description: Additional error details
|