sbom.day // manifest_inspector_v3.14.2
MANIFEST GENERATED: 2026-03-19T00:00:00Z
PUBLIC // OPEN SOURCE BUILD 4f9962ea OPERATIONAL
[ Z-B ] DEPENDENCY_TREE depth=6 nodes=42 root=acme-platform@2.7.1
$ cargo tree --all-features --depth 6 | healthy outdated vulnerable
acme-platform@2.7.1                       [OK]
├── @acme/auth-core@1.4.0                  [OK]
│   ├── jsonwebtoken@9.0.2                 [OK]
│   │   ├── jws@4.0.0                      [OK]
│   │   └── lodash.includes@4.3.0          [OUTDATED]
│   ├── argon2@0.31.2                      [OK]
│   └── rand_core@0.6.4                    [OK]
├── @acme/ledger@0.18.7                    [OUTDATED]
│   ├── rust_decimal@1.34.3                [OK]
│   ├── time@0.3.34                        [OK]
│   └── serde_yaml@0.9.27                  [DEPRECATED]
├── @acme/transport@2.0.0-rc.4             [CRITICAL]
│   ├── hyper@0.14.27                      [CVE-2026-01147]
│   │   ├── h2@0.3.21                      [CVE-2026-01147]
│   │   └── tokio@1.36.0                   [OK]
│   ├── tonic@0.11.0                       [OK]
│   └── rustls@0.21.10                     [OK]
├── @acme/observability@0.9.4              [OK]
│   ├── opentelemetry@0.22.0               [OK]
│   └── tracing@0.1.40                     [OK]
├── @acme/storage@3.2.1                    [OK]
│   ├── sqlx@0.7.4                         [OK]
│   ├── rusoto_s3@0.48.0                   [ARCHIVED]
│   └── redis@0.25.3                       [OK]
├── serde@1.0.197                          [OK]
│   └── serde_derive@1.0.197               [OK]
├── openssl@0.10.55                        [CVE-2026-00492]
│   └── openssl-sys@0.9.90                 [CVE-2026-00492]
└── @acme/cli@0.6.2                        [OK]
    ├── clap@4.5.1                         [OK]
    └── reqwest@0.11.27                    [OUTDATED]
[ Z-C ] COMPONENT_DETAIL no_selection
$ sbom inspect acme-platform@2.7.1
> resolving manifest...
> ok
nameacme-platform
version2.7.1
licenseApache-2.0
maintaineracme-corp
depth0
statusOK
advisorynone
// notes

Root distribution package. Aggregates the auth, ledger, and transport stacks. Hover any node in Zone B to read its dossier here.

$ _
[ Z-D ] SUPPLY_CHAIN_DAG orthogonal · L→R topological
acme-platform @acme/auth-core @acme/ledger @acme/transport @acme/storage jsonwebtoken argon2 rust_decimal sqlx hyper rustls jws lodash.includes h2 tokio openssl rand_core
healthy outdated vulnerable x-axis: depth · y-axis: position in topological order
§ 01 / 03

What is a Software Bill of Materials?

An SBOM is the manifest of every component, library, and dependency baked into a piece of software — direct, transitive, and inherited. It is the ingredients label of the digital supply chain.

// origin

The phrase entered policy vocabulary through Executive Order 14028 (May 2021) and has since become a precondition for federal procurement, a baseline for vulnerability triage, and a contractual artifact between vendors and their downstream consumers.

// formats

SPDX (ISO/IEC 5962) and CycloneDX (OWASP) are the two dominant interchange formats. Both encode component identity (PURL / CPE), licensing, hash, and pedigree. Tools like syft, cyclonedx-cli, and cargo-cyclonedx emit them at build time.

// signal

An SBOM alone is just a list. The value is unlocked when it is paired with an advisory feed — OSV, GHSA, NVD — and re-evaluated every time the feed updates. Yesterday's "OK" is today's "CRITICAL" as new disclosures land.

$ syft packages dir:./acme-platform -o spdx-json > sbom.spdx.json
$ grype sbom:./sbom.spdx.json --fail-on critical
§ 02 / 03

The Transitive Closure Problem

Most software does not depend on a few packages. It depends on a few packages that each depend on a few packages, and so on, until the closure is hundreds — sometimes thousands — of names long.

// arithmetic

A typical Rust binary pulls 200–500 crates. A Node.js application pulls 1,000–3,000 packages. A modern container image, end-to-end, may include 10,000+ artifacts. Each is a potential ingress.

// pedigree

Every component has a maintainer, a license, a release cadence, and a security history. A complete SBOM preserves all of these so that when a CVE is published, the answer to "are we affected?" takes seconds, not days.

// drift

Without continuous regeneration, SBOMs drift. Lock files mutate, transitive versions shift, and a manifest written on Monday no longer describes Friday's build. Treat SBOMs as artifacts of this exact build, not as living documents.

200–500 crates per Rust binary
1k–3k packages per Node app
10k+ artifacts per container
≤6h target advisory window
§ 03 / 03

From Inventory to Action

A bill of materials becomes operational when it is signed, stored, and queried. Otherwise it is just a JSON file in a CI artifact bucket nobody opens.

// sign

Attest the SBOM with an in-toto / SLSA attestation, signed via Sigstore Cosign. The signature ties the manifest to the build that produced it and to the identity that produced the build.

// store

Push the manifest to an OCI registry alongside the artifact, so that any consumer can pull both with a single image reference. SBOMs co-located with their binaries cannot diverge.

// query

Re-evaluate continuously: every new advisory triggers a sweep across every stored SBOM. The output is a deterministic list of affected services — not a panic, not a meeting, just a queue.

$ cosign attest --predicate sbom.spdx.json --type spdxjson \
    --key cosign.key  registry.acme.io/platform:2.7.1
> Pushed manifest sha256:4f9962ea69af… signed by acme-release-bot
$ manifest end // every dependency has a story // sbom.day