Files
git.stella-ops.org/docs-archived/product/advisories/19-Feb-2026 - SBOM Evidence Verification and Auditability Pipeline.md
2026-02-19 22:07:11 +02:00

5.1 KiB

Advisory: SBOM Evidence Verification and Auditability Pipeline

Date: 2026-02-19 Status: ARCHIVED (translated to sprint tasks) Reviewed: 2026-02-19

Review Outcome

Advisory reviewed against current codebase. ~85% of proposed capabilities already exist in Stella Ops across Scanner, Signer, Attestor, Excititor, VexLens, Signals, EvidenceLocker, and ReachGraph modules.

Capabilities Confirmed (no action needed)

  • CycloneDX v1.7 SBOM generation (Scanner.Emit)
  • DSSE/in-toto attestation with 10+ predicate types (Attestor.Envelope)
  • Cosign-compatible signing via Signer (keyless Fulcio + keyful KMS/HSM)
  • Rekor v2 anchoring with RFC 6962 tile verification and offline mode (Attestor)
  • Deterministic VEX ingestion with AOC enforcement (Excititor + VexLens)
  • eBPF micro-witness collection with cross-distro replay (Signals + Scanner)
  • Evidence bundle storage with Merkle roots and portable audit packs (EvidenceLocker)
  • Offline verification for air-gapped deployments

Gaps Identified → Sprint Tasks Created

  1. Unified canonical_id contract → SPRINT_20260219_009 (CID-01, CID-02)
  2. Artifact Canonical Record → SPRINT_20260219_009 (CID-03, CID-04)
  3. Predicate Schema Registry → SPRINT_20260219_010 (PSR-01, PSR-02)
  4. CI Assertion Pack → SPRINT_20260219_011 (CIAP-01 through CIAP-04)
  5. Micro-witness → VEX Auto-Suppress workflow → SPRINT_20260219_012 (MWS-01 through MWS-03)

Proposals Explicitly Rejected

  • Replacing Signer with raw cosign CLI (Signer adds PoE, quotas, DPoP/mTLS)
  • Simplifying VEX handling (Excititor+VexLens+AOC is more sophisticated)
  • Adopting advisory's simplified schema URIs (keep existing Stella URIs, add to registry)
  • replay_token pointing to external S3 (keep CAS with BLAKE3 digests)

Original Advisory Content

(Inline advisory provided by user — full text preserved below for audit trail.)


Why this matters (quick primer)

  • SBOM (software bill of materials) says what's inside an artifact.
  • DSSE / in-toto wraps evidence in a tamper-evident envelope.
  • cosign signs/verifies those envelopes.
  • Rekor (transparency log) proves when/what was published.
  • VEX states whether known CVEs affect your artifact.
  • Micro-witnesses are runtime breadcrumbs you can join back to SBOM/VEX for triage.

NOW (MVP you can ship immediately)

Goal: Minimal, reproducible spine with canonical SBOMs, signed attestations, Rekor v2 anchoring, and deterministic VEX ingestion.

Canonical SBOM & ID

  1. Emit CycloneDX v1.7 JSON.
  2. Canonicalize via JSON-JCS -> canonical_id := sha256(JCS(sbom.json)).

DSSE attestation (SBOM predicate)

  • Wrap CycloneDX content (or pointer) in an in-toto Statement.
  • subject[0].digest.sha256 == canonical_id.
  • Sign with cosign (DSSE mode).
  • Capture Rekor v2 tile pointer / entry id and embed it in predicate metadata.

Rekor v2 anchoring

  • cosign publish creates the log entry.
  • Store the tile URL and entry id in your artifact record.

Deterministic VEX ingestion (OpenVEX & CycloneDX VEX)

  • Ingest OpenVEX or CycloneDX VEX, map to a canonical CycloneDX VEX form.
  • Apply strict merge rules (source priority, timestamp, exact canonical_id target).

CI assertions (must-pass)

  • Unit: cyclonedx-cli validate ./bom.json && jcs_canonicalize ./bom.json | sha256sum -> equals expected canonical_id.
  • Integration: cosign attest --predicate predicate.json --key cosign.key <subject-ref> cosign verify-attestation --key <pubkey> --type in-toto <subject-ref> Rekor proof: rekor-cli tile get --entry <entry_id> -> inclusion proof valid.
  • VEX mapping: jsonschema validate; assert vulnerabilities[].analysis.state and target match canonical_id.

LATER (scale/hardening)

  • Rekor v2 tile batching & multi-tile reconciliation.
  • Signed micro-witness aggregation service.
  • Deterministic replay harness (nightly) for large volumes.
  • Predicate schema registry (stable predicateType URIs, semver).

Flow A: Build-time SBOM + Attestation Anchor (end-to-end)

  1. Producer: CycloneDX v1.7 -> validate -> JCS canonicalize -> canonical_id = sha256(canonical_bytes).
  2. Predicate: in-toto Statement with CycloneDX JCS content.
  3. Sign & anchor: cosign attest -> capture Rekor tile URL and entry_id.
  4. Verify: Fetch referrers, extract DSSE, cosign verify-attestation, recompute canonical_id, validate Rekor inclusion proof.

Flow B: VEX -> Apply -> Runtime Micro-witness Join

  1. VEX provider: Publish OpenVEX or CycloneDX VEX; DSSE-sign; optionally anchor in Rekor.
  2. Ingest & map: OpenVEX -> canonical CycloneDX VEX; store DSSE + rekor_tile + provenance.
  3. Runtime micro-witness: Emit DSSE micro-witness predicate referencing canonical_id.
  4. Correlate: Join micro-witness DSSE with VEX; if not_affected -> auto-suppress; else surface audit pack.

Failure modes

  • Payload > Rekor limit: Put artifact in immutable store; Rekor entry contains digest + pointer.
  • Missing symbol bundle: Emit unknown_state micro-witness entry.
  • Digest mismatch anywhere: fail the build.