Here’s a crisp, practical game plan to take your SBOM/VEX pipeline from “SBOM‑only” → “VEX‑ready” → “signed, provable evidence graph” with Rekor inclusion‑proof checks—plus an explainability track you can ship alongside it. --- # 1) Freeze on SBOM specs (CycloneDX + SPDX) * **Adopt two inputs only:** CycloneDX v1.6 (Ecma ECMA‑424) and SPDX 3.0.1. Lock parsers and schemas; reject anything else at ingest. ([Ecma International][1]) * **Scope notes:** CycloneDX covers software/hardware/ML/config & provenance; SPDX 3.x brings a richer, granular data model. ([CycloneDX][2]) **Action:** * `Sbomer.Ingest` accepts `*.cdx.json` and `*.spdx.json` only. * Validate against ECMA‑424 (CycloneDX 1.6) and SPDX 3.0.1 canonical docs before storage. ([Ecma International][1]) --- # 2) Wire VEX predicates (VEXer) * **Model:** in‑toto Attestation layered as DSSE Envelope → in‑toto Statement → VEX predicate payload. ([Legit Security][3]) * **Why DSSE:** avoids fragile canonicalization; standard across in‑toto/Sigstore. ([Medium][4]) **Action:** * Accept VEX as an **attestation** (JSON) with `statementType: in-toto`, `predicateType: VEX`. Wrap/verify via DSSE at the edge. ([Legit Security][3]) --- # 3) Sign every artifact & edge (Authority) * **Artifacts to sign:** SBOM files, VEX attestations, and each **evidence edge** you materialize in the proof graph (e.g., “image X derives from build Y,” “package Z fixed in version…”)—all as DSSE envelopes. ([in-toto][5]) * **Sigstore/Cosign path:** Sign + optionally keyless; publish signatures/attestations; send to Rekor. ([Sigstore][6]) **Action:** * Output: `{ artifact, DSSE-envelope, signature, Rekor UUID }` per node/edge. * Keep offline mode by queueing envelopes; mirror later to Rekor. --- # 4) Rekor inclusion‑proofs (Proof Service) * **Goal:** For every submitted signature/attestation, store the Rekor *UUID*, *log index*, and verify **inclusion proofs** regularly. ([Sigstore][7]) **CLI contract (reference):** * `rekor-cli verify --rekor_server --signature --public-key --artifact ` (yields inclusion proof). ([Sigstore][8]) **Action:** * Background metrics: “% entries with valid inclusion proof,” “median verify latency,” “last inclusion‑proof age.” ([Sigstore][7]) --- # 5) Deterministic evidence graph (Graph & Ledger) * Store **hash‑addressed** nodes and signed edges; persist the DSSE for each. * Export a **deterministic ledger** dump (stable sort, normalized JSON) to guarantee byte‑for‑byte reproducible rebuilds. * Track **provenance chain** from container → build → source → SBOM → VEX. --- # 6) Explainability: Smart‑Diff + Reachability + Scores * **Human‑readable proof trails:** For every verdict, render the chain: finding → SBOM component → VEX predicate → reachability basis → runtime/CFG evidence → signature + Rekor proof. * **Smart‑Diff:** Image‑to‑image diff includes env/config deltas; highlight changes that flip reachability (e.g., library upgrade, flag on/off). * **Call‑stack reachability:** Add compositional call‑graph checks per language (Java/JS/Python/Go/C/C++/.NET) and label evidence origins. * **Deterministic scoring:** Pin a formula (e.g., `Score = weight(VEX status) + weight(Reachability) + weight(Exploit/EPSS) + weight(Runtime hit)`), emit the formula + inputs in the UI. * **Explicit UNKNOWNs:** When data is missing, mark `UNKNOWN` and run sandboxed probes to shrink unknowns over time; surface these as tasks. * **Track Rekor verification latency** as a UX health metric (evidence “time‑to‑trust”). ([Sigstore][7]) --- # 7) Minimal .NET 10 module checklist (Stella Ops) * **Sbomer**: strict CycloneDX/SPDX validation → normalize → hash. ([Ecma International][1]) * **Vexer**: ingest DSSE/in‑toto VEX; verify signature; map to components. ([Legit Security][3]) * **Authority**: DSSE signers (keyed + keyless) + Cosign integration. ([Sigstore][6]) * **Proof**: Rekor submit/verify; store UUID/index/inclusion‑proof. ([Sigstore][7]) * **Scanner**: reachability plugins per language; emit call‑chain evidence. * **UI**: proof‑trail pages; Smart‑Diff; deterministic score panel; UNKNOWN badge. --- # 8) Guardrails & defaults * **Only** CycloneDX 1.6 / SPDX 3.0.1 at ingest. Hard fail others. ([Ecma International][1]) * DSSE everywhere (even edges). ([in-toto][5]) * For online mode, default to public Rekor; for air‑gap, queue and verify later against your mirror. ([Sigstore][7]) * Persist inclusion‑proof artifacts so audits don’t require re-fetching. ([Sigstore][7]) --- # 9) Tiny starter backlog (ready to copy into SPRINT) 1. **Ingest Freeze:** Add format gate (CDX1.6/SPDX3.0.1 validators). ([Ecma International][1]) 2. **Attest API:** DSSE verify endpoint for VEX statements. ([Legit Security][3]) 3. **Signer:** Cosign wrapper for DSSE + push to Rekor; store UUID. ([Sigstore][6]) 4. **Proof‑Verifier:** `rekor-cli verify` integration + metrics. ([Sigstore][8]) 5. **Graph Store:** hash‑addressed nodes/edges; deterministic export. 6. **Explain UI:** proof trail, Smart‑Diff, reachability call‑chains, UNKNOWNs. If you want, I can turn this into concrete `.csproj` skeletons, validator stubs, DSSE signing/verify helpers, and a Rekor client wrapper next. [1]: https://ecma-international.org/publications-and-standards/standards/ecma-424/?utm_source=chatgpt.com "ECMA-424" [2]: https://cyclonedx.org/specification/overview/?utm_source=chatgpt.com "Specification Overview" [3]: https://www.legitsecurity.com/blog/slsa-provenance-blog-series-part-1-what-is-software-attestation?utm_source=chatgpt.com "SLSA Provenance Blog Series, Part 1: What Is Software ..." [4]: https://dlorenc.medium.com/signature-formats-9b7b2a127473?utm_source=chatgpt.com "Signature Formats. Envelopes and Wrappers and Formats, Oh…" [5]: https://in-toto.readthedocs.io/en/latest/model.html?utm_source=chatgpt.com "Metadata Model — in-toto 3.0.0 documentation" [6]: https://docs.sigstore.dev/cosign/verifying/attestation/?utm_source=chatgpt.com "In-Toto Attestations" [7]: https://docs.sigstore.dev/logging/overview/?utm_source=chatgpt.com "Rekor" [8]: https://docs.sigstore.dev/logging/cli/?utm_source=chatgpt.com "CLI" ## Stella Ops — what you get that “SBOM-only” tools don’t ### 1) **Proof-carrying security decisions** Stella Ops doesn’t just *compute* a verdict (“CVE present / fixed / not affected”). It produces a **verifiable story**: **SBOM → VEX → Reachability/runtime evidence → policy decision → signature(s) → transparency-log proof** * Every artifact (SBOM, VEX, scan results, “edge” in the evidence graph) is wrapped as an **in-toto attestation** and signed (DSSE) (Cosign uses DSSE for payload signing). ([Sigstore][1]) * Signatures/attestations are anchored in **Rekor**, and you can verify “proof of entry” with `rekor-cli verify`. ([Sigstore][2]) **Advantage:** audits, incident reviews, and partner trust become *mechanical verification* instead of “trust us”. --- ### 2) **Noise reduction that’s accountable** VEX is explicitly about exploitability in context (not just “a scanner saw it”). CycloneDX frames VEX as a way to prioritize by real-world exploitability. ([CycloneDX][3]) OpenVEX is designed to be SBOM-agnostic and minimal, though it’s still marked as a draft spec. ([GitHub][4]) **Advantage:** you can suppress false positives *with receipts* (justifications + signed statements), not tribal knowledge. --- ### 3) **Version-aware interoperability (without chaos)** * CycloneDX’s **current** release is **1.7** (2025‑10‑21). ([CycloneDX][5]) * The ECMA standard **ECMA‑424** corresponds to **CycloneDX v1.6**. ([Ecma International][6]) * SPDX has an official **3.0.1** spec. ([SPDX][7]) **Advantage:** Stella Ops can accept real-world supplier outputs, while still keeping your internal model stable and upgradeable. --- ### 4) **Deterministic evidence graph = fast “blast radius” answers** Because evidence is stored as a graph of content-addressed nodes/edges (hash IDs), you can answer: * “Which deployed images include package X@version Y?” * “Which builds were declared *not affected* by vendor VEX, and why?” * “What changed between build A and build B that made CVE reachable?” **Advantage:** incident response becomes query + verify, not archaeology. --- ### 5) **Security improvements beyond vulnerabilities** CycloneDX 1.6 added stronger cryptographic asset discovery/reporting to help manage crypto posture (including agility and policy compliance). ([CycloneDX][8]) **Advantage:** Stella Ops can expand beyond “CVEs” into crypto hygiene, provenance, and operational config integrity. --- # Developer guidelines (two audiences) ## A) Guidelines for *app teams* producing Stella-ready evidence ### 1) Pick formats + pin versions (don’t wing it) **SBOMs** * Prefer **CycloneDX 1.7** going forward; allow **1.6** when you need strict ECMA‑424 alignment. ([CycloneDX][5]) * Accept **SPDX 3.0.1** as the SPDX target. ([SPDX][7]) **VEX** * Prefer **OpenVEX** for a minimal, SBOM-agnostic VEX doc (but treat it as a draft spec and lock to a versioned context like `…/v0.2.0`). ([GitHub][4]) **Rule of thumb:** “Versioned in, versioned out.” Keep the original document bytes, plus a normalized internal form. --- ### 2) Use stable identities everywhere * **Subjects:** reference immutable artifacts (e.g., container image digest), not tags (`:latest`). * **Components:** use PURLs when possible, and include hashes when available. * **VEX “products”:** use the same identifiers your SBOM uses (PURLs are ideal). --- ### 3) Sign and attach evidence as attestations Cosign supports SBOM attestations and in-toto predicates; it supports SBOM formats including SPDX and CycloneDX. ([Sigstore][9]) Example: attach an SPDX SBOM as an attestation (Sigstore sample policy shows the exact pattern): ([Sigstore][10]) ```bash cosign attest --yes --type https://spdx.dev/Document \ --predicate sbom.spdx.json \ --key cosign.key \ "${IMAGE_DIGEST}" ``` OpenVEX examples in the ecosystem use a versioned predicate type like `https://openvex.dev/ns/v0.2.0`. ([Docker Documentation][11]) (Your Stella Ops policy can accept either `--type openvex` or the explicit URI; the explicit URI is easiest to reason about.) --- ### 4) Always log + verify transparency proofs Rekor’s CLI supports verifying inclusion proofs (proof-of-entry). ([Sigstore][2]) ```bash rekor-cli verify --rekor_server https://rekor.sigstore.dev \ --signature artifact.sig \ --public-key cosign.pub \ --artifact artifact.bin ``` **Team rule:** releases aren’t “trusted” until signatures + inclusion proofs verify. --- ### 5) Write VEX like it will be cross-examined A good VEX statement includes: * **status** (e.g., not_affected / affected / fixed) * **justification** (why) * **timestamp** and author * link to supporting evidence (ticket, code change, runtime data) If you can’t justify a “not_affected”, use “under investigation” and make it expire. --- ## B) Guidelines for *Stella Ops contributors* (platform developers) ### 1) Core principle: “Everything is evidence, evidence is immutable” * Treat every ingest as **untrusted input**: strict schema validation, size limits, decompression limits, deny SSRF in “external references”, etc. * Store artifacts as **content-addressed blobs**: `sha256(bytes)` is the primary ID. * Never mutate evidence; publish a *new* node/edge with its own signature. --- ### 2) Canonical internal model + lossless preservation **Store three things per document:** 1. raw bytes (for audits) 2. parsed form (for queries) 3. normalized canonical form (for deterministic hashing & diffs) **Why:** it lets you evolve internal representation without losing provenance. --- ### 3) Evidence graph rules (keep it explainable) * Nodes: `Artifact`, `Component`, `Vulnerability`, `Attestation`, `Build`, `Deployment`, `RuntimeSignal` * Edges: `DESCRIBES`, `AFFECTS`, `NOT_AFFECTED_BY`, `FIXED_IN`, `DERIVED_FROM`, `DEPLOYS`, `OBSERVED_AT_RUNTIME` * **Sign edges**, not just nodes (edge = claim). **UI rule:** every “status” shown to users must have a clickable proof trail ending in signatures + inclusion proof. --- ### 4) Attestation envelope standardization Use **in-toto statements in DSSE envelopes** for everything you sign (SBOM, VEX, scan predicates). Cosign’s attestation flow is built on DSSE. ([Sigstore][1]) **Fail closed:** if a policy requires an attestation and it’s missing/unverifiable, the decision should not silently pass. --- ### 5) Rekor proof lifecycle Persist per entry: * Rekor UUID * log index * integrated time * inclusion proof data (when available) And track health metrics: * % verified proofs * proof verification failures * “proof age” since last verification --- ### 6) Versioning strategy (avoid future pain) * Maintain an explicit compatibility matrix: * CycloneDX 1.6 (ECMA‑424) and 1.7 (current). ([Ecma International][6]) * SPDX 3.0.1. ([SPDX][7]) * Add new versions behind feature flags and “upgrade playbooks”. * Include the **media type + version** in stored metadata (CycloneDX supports a `version=` media type parameter). ([CycloneDX][5]) --- ### 7) “Definition of done” for any new scanner / evidence source A new plugin isn’t complete unless it: * outputs a **stable, hashable predicate** * links evidence to **subjects/components** using stable identifiers * emits **reason codes** + minimal repro info * produces a signed attestation and (optionally) Rekor entry * supports deterministic re-run (same inputs ⇒ same normalized output) --- If you want a one-page “Stella Ops Developer Contract” template (API shapes + required fields for SBOM/VEX/attestations + policy expectations), I can draft it in a copy/paste form suitable for a repo `docs/` folder. [1]: https://docs.sigstore.dev/cosign/verifying/attestation/ "In-Toto Attestations - Sigstore" [2]: https://docs.sigstore.dev/logging/cli/ "CLI - Sigstore" [3]: https://cyclonedx.org/capabilities/vex/?utm_source=chatgpt.com "Vulnerability Exploitability eXchange (VEX)" [4]: https://github.com/openvex/spec?utm_source=chatgpt.com "OpenVEX Specification" [5]: https://cyclonedx.org/specification/overview/ "Specification Overview | CycloneDX" [6]: https://ecma-international.org/publications-and-standards/standards/ecma-424/?utm_source=chatgpt.com "ECMA-424" [7]: https://spdx.github.io/spdx-spec/v3.0.1/?utm_source=chatgpt.com "SPDX Specification 3.0.1" [8]: https://cyclonedx.org/news/cyclonedx-v1.6-released/?utm_source=chatgpt.com "CycloneDX v1.6 Released, Advances Software Supply ..." [9]: https://docs.sigstore.dev/cosign/system_config/specifications/ "Specifications - Sigstore" [10]: https://docs.sigstore.dev/policy-controller/sample-policies/ "Sample Policies - Sigstore" [11]: https://docs.docker.com/scout/how-tos/create-exceptions-vex/?utm_source=chatgpt.com "Create an exception using the VEX"