up
This commit is contained in:
663
docs/modules/export-center/openapi/export-center.v1.yaml
Normal file
663
docs/modules/export-center/openapi/export-center.v1.yaml
Normal file
@@ -0,0 +1,663 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: StellaOps ExportCenter API
|
||||
version: 1.0.0
|
||||
description: >-
|
||||
Export profiles, runs, and deterministic bundle downloads for air-gap and offline deployments.
|
||||
Supports attestation exports, mirror bundles, bootstrap packs, and portable evidence bundles.
|
||||
contact:
|
||||
name: StellaOps Exporter Service Guild
|
||||
x-stella-oas-revision: '2025-12-07'
|
||||
servers:
|
||||
- url: https://{env}.export.api.stellaops.local
|
||||
description: Default environment-scoped host
|
||||
variables:
|
||||
env:
|
||||
default: prod
|
||||
enum: [dev, staging, prod, airgap]
|
||||
- url: https://export.{region}.offline.bundle
|
||||
description: Offline bundle host for air-gapped deployments
|
||||
variables:
|
||||
region:
|
||||
default: local
|
||||
enum: [local]
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- mTLS: []
|
||||
paths:
|
||||
/.well-known/openapi:
|
||||
get:
|
||||
summary: OpenAPI discovery endpoint
|
||||
operationId: getOpenApiDiscovery
|
||||
tags: [discovery]
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: OpenAPI specification document
|
||||
headers:
|
||||
ETag:
|
||||
description: SHA-256 hash of the OAS document
|
||||
schema:
|
||||
type: string
|
||||
example: '"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"'
|
||||
X-Export-Oas-Version:
|
||||
description: OAS version identifier
|
||||
schema:
|
||||
type: string
|
||||
example: 'v1'
|
||||
Last-Modified:
|
||||
description: OAS document last modification time
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: '2025-01-01T00:00:00Z'
|
||||
Cache-Control:
|
||||
description: Cache directive
|
||||
schema:
|
||||
type: string
|
||||
example: 'private, must-revalidate'
|
||||
content:
|
||||
application/yaml:
|
||||
schema:
|
||||
type: string
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
|
||||
/v1/exports/profiles:
|
||||
get:
|
||||
summary: List available export profiles
|
||||
operationId: listExportProfiles
|
||||
tags: [profiles]
|
||||
parameters:
|
||||
- name: kind
|
||||
in: query
|
||||
description: Filter by profile kind
|
||||
schema:
|
||||
type: string
|
||||
enum: [attestation, mirror, bootstrap, airgap-evidence]
|
||||
- name: limit
|
||||
in: query
|
||||
description: Maximum number of profiles to return
|
||||
schema:
|
||||
type: integer
|
||||
default: 50
|
||||
maximum: 200
|
||||
- name: cursor
|
||||
in: query
|
||||
description: Pagination cursor from previous response
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: List of export profiles
|
||||
headers:
|
||||
X-Stella-Quota-Remaining:
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportProfilePage'
|
||||
example:
|
||||
profiles:
|
||||
- id: 'profile-attestation-v1'
|
||||
kind: 'attestation'
|
||||
description: 'Export attestation bundles with DSSE envelopes'
|
||||
version: 'v1'
|
||||
retentionDays: 90
|
||||
- id: 'profile-mirror-full'
|
||||
kind: 'mirror'
|
||||
description: 'Full mirror bundle with all advisories'
|
||||
version: 'v1'
|
||||
retentionDays: 365
|
||||
cursor: null
|
||||
hasMore: false
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/v1/exports/runs:
|
||||
get:
|
||||
summary: List export runs
|
||||
operationId: listExportRuns
|
||||
tags: [runs]
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
- name: profileId
|
||||
in: query
|
||||
description: Filter by export profile
|
||||
schema:
|
||||
type: string
|
||||
- name: status
|
||||
in: query
|
||||
description: Filter by status
|
||||
schema:
|
||||
type: string
|
||||
enum: [pending, running, completed, failed]
|
||||
- name: limit
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 50
|
||||
maximum: 200
|
||||
- name: cursor
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: List of export runs
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportRunPage'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/v1/exports/airgap/evidence/{bundleId}:
|
||||
post:
|
||||
summary: Create portable evidence export
|
||||
operationId: createEvidenceExport
|
||||
tags: [evidence]
|
||||
parameters:
|
||||
- name: bundleId
|
||||
in: path
|
||||
required: true
|
||||
description: Source evidence bundle identifier
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'202':
|
||||
description: Export request accepted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportStatus'
|
||||
example:
|
||||
exportId: '01234567-89ab-cdef-0123-456789abcdef'
|
||||
profileId: 'profile-airgap-evidence-v1'
|
||||
status: 'pending'
|
||||
bundleId: 'fedcba98-7654-3210-fedc-ba9876543210'
|
||||
createdAt: '2025-01-01T00:00:00Z'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/RateLimited'
|
||||
|
||||
/v1/exports/airgap/evidence/{exportId}:
|
||||
get:
|
||||
summary: Get evidence export status
|
||||
operationId: getEvidenceExportStatus
|
||||
tags: [evidence]
|
||||
parameters:
|
||||
- name: exportId
|
||||
in: path
|
||||
required: true
|
||||
description: Export run identifier
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'200':
|
||||
description: Export status
|
||||
headers:
|
||||
ETag:
|
||||
description: Status document hash
|
||||
schema:
|
||||
type: string
|
||||
Last-Modified:
|
||||
description: Status last update time
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportStatus'
|
||||
example:
|
||||
exportId: '01234567-89ab-cdef-0123-456789abcdef'
|
||||
profileId: 'profile-airgap-evidence-v1'
|
||||
status: 'completed'
|
||||
bundleId: 'fedcba98-7654-3210-fedc-ba9876543210'
|
||||
artifactSha256: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
||||
rootHash: 'sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210'
|
||||
portableVersion: 'v1'
|
||||
createdAt: '2025-01-01T00:00:00Z'
|
||||
completedAt: '2025-01-01T00:01:00Z'
|
||||
downloadUri: '/v1/exports/airgap/evidence/01234567-89ab-cdef-0123-456789abcdef/download'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/v1/exports/airgap/evidence/{exportId}/download:
|
||||
get:
|
||||
summary: Download evidence export bundle
|
||||
operationId: downloadEvidenceExport
|
||||
tags: [evidence]
|
||||
parameters:
|
||||
- name: exportId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'200':
|
||||
description: Portable evidence bundle archive
|
||||
headers:
|
||||
ETag:
|
||||
description: Archive SHA-256 hash
|
||||
schema:
|
||||
type: string
|
||||
example: '"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"'
|
||||
Last-Modified:
|
||||
description: Archive creation time
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
Content-Disposition:
|
||||
description: Suggested filename
|
||||
schema:
|
||||
type: string
|
||||
example: 'attachment; filename="export-portable-bundle-v1.tgz"'
|
||||
Cache-Control:
|
||||
schema:
|
||||
type: string
|
||||
example: 'private, must-revalidate'
|
||||
content:
|
||||
application/gzip:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/v1/exports/attestations/{attestationId}:
|
||||
post:
|
||||
summary: Create attestation export
|
||||
operationId: createAttestationExport
|
||||
tags: [attestations]
|
||||
parameters:
|
||||
- name: attestationId
|
||||
in: path
|
||||
required: true
|
||||
description: Source attestation identifier
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'202':
|
||||
description: Export request accepted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportStatus'
|
||||
example:
|
||||
exportId: '11111111-1111-1111-1111-111111111111'
|
||||
profileId: 'profile-attestation-v1'
|
||||
status: 'pending'
|
||||
attestationId: '22222222-2222-2222-2222-222222222222'
|
||||
createdAt: '2025-01-01T00:00:00Z'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/RateLimited'
|
||||
|
||||
/v1/exports/attestations/{exportId}:
|
||||
get:
|
||||
summary: Get attestation export status
|
||||
operationId: getAttestationExportStatus
|
||||
tags: [attestations]
|
||||
parameters:
|
||||
- name: exportId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'200':
|
||||
description: Export status
|
||||
headers:
|
||||
ETag:
|
||||
schema:
|
||||
type: string
|
||||
Last-Modified:
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExportStatus'
|
||||
example:
|
||||
exportId: '11111111-1111-1111-1111-111111111111'
|
||||
profileId: 'profile-attestation-v1'
|
||||
status: 'completed'
|
||||
attestationId: '22222222-2222-2222-2222-222222222222'
|
||||
artifactSha256: 'sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789'
|
||||
rootHash: 'sha256:9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba'
|
||||
statementDigest: 'sha256:1111111111111111111111111111111111111111111111111111111111111111'
|
||||
createdAt: '2025-01-01T00:00:00Z'
|
||||
completedAt: '2025-01-01T00:01:00Z'
|
||||
downloadUri: '/v1/exports/attestations/11111111-1111-1111-1111-111111111111/download'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/v1/exports/attestations/{exportId}/download:
|
||||
get:
|
||||
summary: Download attestation export bundle
|
||||
operationId: downloadAttestationExport
|
||||
tags: [attestations]
|
||||
parameters:
|
||||
- name: exportId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'200':
|
||||
description: Attestation bundle archive
|
||||
headers:
|
||||
ETag:
|
||||
description: Archive SHA-256 hash
|
||||
schema:
|
||||
type: string
|
||||
example: '"sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"'
|
||||
Last-Modified:
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
Content-Disposition:
|
||||
schema:
|
||||
type: string
|
||||
example: 'attachment; filename="export-attestation-bundle-v1.tgz"'
|
||||
Cache-Control:
|
||||
schema:
|
||||
type: string
|
||||
example: 'private, must-revalidate'
|
||||
content:
|
||||
application/gzip:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/v1/exports/runs/{exportId}/events:
|
||||
get:
|
||||
summary: Get export run events (stub)
|
||||
operationId: getExportRunEvents
|
||||
tags: [runs]
|
||||
x-stub: true
|
||||
description: >-
|
||||
Timeline/event stream pointer for export run progress. Returns pointer to
|
||||
notification/event stream when notifications are enabled. Stub until event
|
||||
envelopes fully land.
|
||||
parameters:
|
||||
- name: exportId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
responses:
|
||||
'200':
|
||||
description: Event stream reference
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
exportId:
|
||||
type: string
|
||||
format: uuid
|
||||
eventStreamUri:
|
||||
type: string
|
||||
format: uri
|
||||
status:
|
||||
type: string
|
||||
enum: [available, not-configured]
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: OAuth2 access token with export scopes
|
||||
mTLS:
|
||||
type: mutualTLS
|
||||
description: Mutual TLS client certificate authentication
|
||||
|
||||
parameters:
|
||||
TenantId:
|
||||
name: X-Stella-Tenant-Id
|
||||
in: header
|
||||
required: true
|
||||
description: Tenant identifier for multi-tenant scoping
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
schemas:
|
||||
ExportProfile:
|
||||
type: object
|
||||
required: [id, kind, description, version, retentionDays]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique profile identifier
|
||||
example: 'profile-attestation-v1'
|
||||
kind:
|
||||
type: string
|
||||
enum: [attestation, mirror, bootstrap, airgap-evidence]
|
||||
description: Profile type
|
||||
description:
|
||||
type: string
|
||||
description: Human-readable profile description
|
||||
version:
|
||||
type: string
|
||||
description: Profile schema version
|
||||
example: 'v1'
|
||||
retentionDays:
|
||||
type: integer
|
||||
description: Number of days exports are retained
|
||||
example: 90
|
||||
|
||||
ExportProfilePage:
|
||||
type: object
|
||||
required: [profiles, hasMore]
|
||||
properties:
|
||||
profiles:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ExportProfile'
|
||||
cursor:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Pagination cursor for next page
|
||||
hasMore:
|
||||
type: boolean
|
||||
description: Whether more results are available
|
||||
|
||||
ExportStatus:
|
||||
type: object
|
||||
required: [exportId, profileId, status, createdAt]
|
||||
properties:
|
||||
exportId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique export run identifier
|
||||
profileId:
|
||||
type: string
|
||||
description: Associated export profile
|
||||
status:
|
||||
type: string
|
||||
enum: [pending, running, completed, failed]
|
||||
description: Current export status
|
||||
artifactSha256:
|
||||
type: string
|
||||
nullable: true
|
||||
description: SHA-256 hash of the exported artifact
|
||||
example: 'sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
||||
rootHash:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Merkle root hash of bundle contents
|
||||
example: 'sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210'
|
||||
portableVersion:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Portable bundle format version
|
||||
attestationId:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Source attestation identifier (for attestation exports)
|
||||
bundleId:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Source bundle identifier (for evidence exports)
|
||||
statementDigest:
|
||||
type: string
|
||||
nullable: true
|
||||
description: SHA-256 of in-toto statement (for attestation exports)
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Export creation timestamp (ISO 8601)
|
||||
example: '2025-01-01T00:00:00Z'
|
||||
completedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: Export completion timestamp (ISO 8601)
|
||||
downloadUri:
|
||||
type: string
|
||||
format: uri
|
||||
nullable: true
|
||||
description: Relative URI for downloading the export artifact
|
||||
|
||||
ExportRunPage:
|
||||
type: object
|
||||
required: [runs, hasMore]
|
||||
properties:
|
||||
runs:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ExportStatus'
|
||||
cursor:
|
||||
type: string
|
||||
nullable: true
|
||||
hasMore:
|
||||
type: boolean
|
||||
|
||||
ErrorEnvelope:
|
||||
type: object
|
||||
required: [error]
|
||||
properties:
|
||||
error:
|
||||
type: object
|
||||
required: [code, message, correlationId]
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description: Machine-readable error code
|
||||
example: 'EXPORT_NOT_FOUND'
|
||||
message:
|
||||
type: string
|
||||
description: Human-readable error message
|
||||
example: 'Export with the specified ID was not found'
|
||||
correlationId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Request correlation ID for tracing
|
||||
retryAfterSeconds:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: Suggested retry delay for rate-limited requests
|
||||
|
||||
responses:
|
||||
Unauthorized:
|
||||
description: Authentication required or invalid credentials
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorEnvelope'
|
||||
example:
|
||||
error:
|
||||
code: 'UNAUTHORIZED'
|
||||
message: 'Valid authentication credentials required'
|
||||
correlationId: '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
NotFound:
|
||||
description: Resource not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorEnvelope'
|
||||
example:
|
||||
error:
|
||||
code: 'NOT_FOUND'
|
||||
message: 'The requested resource was not found'
|
||||
correlationId: '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
RateLimited:
|
||||
description: Rate limit exceeded
|
||||
headers:
|
||||
X-Stella-Quota-Remaining:
|
||||
schema:
|
||||
type: integer
|
||||
example: 0
|
||||
Retry-After:
|
||||
schema:
|
||||
type: integer
|
||||
example: 60
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorEnvelope'
|
||||
example:
|
||||
error:
|
||||
code: 'RATE_LIMITED'
|
||||
message: 'Rate limit exceeded. Please retry after the specified delay.'
|
||||
correlationId: '00000000-0000-0000-0000-000000000000'
|
||||
retryAfterSeconds: 60
|
||||
|
||||
tags:
|
||||
- name: discovery
|
||||
description: OpenAPI discovery and metadata
|
||||
- name: profiles
|
||||
description: Export profile management
|
||||
- name: runs
|
||||
description: Export run management and status
|
||||
- name: evidence
|
||||
description: Portable evidence bundle exports
|
||||
- name: attestations
|
||||
description: Attestation bundle exports
|
||||
Reference in New Issue
Block a user