This commit is contained in:
StellaOps Bot
2025-12-07 22:49:53 +02:00
parent 11597679ed
commit 7c24ed96ee
204 changed files with 23313 additions and 1430 deletions

View 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