SBOM Upload to the SbomService Ledger
Overview
Operator-supplied (bring-your-own) SBOM uploads to SbomService accept SPDX and CycloneDX JSON and register them in the tenant’s SBOM ledger.
Scanner has a separate bring-your-own upload that submits an SBOM for scanning at
POST /api/v1/byos-sboms(see Scanner BYOS ingestion). This page covers only the SbomService ledger upload.
Supported formats
- CycloneDX JSON: 1.4, 1.5, 1.6, 1.7
- SPDX JSON: 2.3, 3.0
Upload endpoint
POST /sbom/uploadorPOST /api/v1/sbom/upload- Requires
sbom:write; the tenant is the authenticatedstellaops:tenantclaim. - Required:
artifactRef, plussbom(JSON object) orsbomBase64. - Optional:
formathint (cyclonedxorspdx),sourcemetadata,artifactDigest, and lineage hintsparentArtifactDigest,baseImageRef,baseImageDigest. - Success returns
202 Accepted; validation failure returns400.
Example:
{
"artifactRef": "acme/app:2.0",
"sbom": { "spdxVersion": "SPDX-2.3", "packages": [] },
"source": { "tool": "syft", "version": "1.9.0" }
}
Validation notes
- CycloneDX requires
bomFormatand supportedspecVersion. - Scanner’s CycloneDX 1.7 inventory JSON is accepted unchanged. Its current top-level
componentsprofile is normalized directly from JSON; this support does not describe an XML or Protobuf decoder. The raw-document sidecar and owner stream digest bind the exact first-writer UTF-8 bytes, including the original declared version and native package versions. - SPDX requires
spdxVersionand a supported version number. - Quality scoring prefers components with PURL, version, and license metadata.
- Lifecycle enrichment runs after format validation and normalization. It preserves lifecycle hints from SBOM component metadata and uses offline local catalog rules to flag known unsupported runtime lines.
- Accepted uploads can return
validationResult.tagsandvalidationResult.lifecycleFindings.runtime:eolmeans ingestion identified an EOL runtime component and Policy can consume the tag withsbom.has_tag("runtime:eol"). - Lifecycle catalog updates are an operator-maintained offline input. The upload path must stay deterministic and must not fetch lifecycle data from the internet.
Troubleshooting
- “sbom or sbomBase64 is required”: include an SBOM payload in the request.
- “Unable to detect SBOM format”: set
formatexplicitly or include required root fields. - Unsupported SBOM format/version: ensure CycloneDX JSON 1.4–1.7 or SPDX JSON 2.3/3.0.
SBOM contains a NUL character (U+0000) at '<pointer>': PostgreSQL cannot store U+0000, so the upload is refused with400and nothing is persisted. Each error names the JSON Pointer of one location (at most five); remove or replace the character in the producing tool. A request field such assource.toolwith U+0000 is refused the same way. Other control characters are accepted.- Low quality scores: include PURLs, versions, and license declarations where possible.
- Unexpected
runtime:eolwarning: inspectvalidationResult.lifecycleFindingsfor the matched component, source, EOL date, and tags, then refresh or correct the local lifecycle catalog if the source rule is stale.
