chainsaw sbom

Software Bill of Materials commands

Software Bill of Materials commands

SubcommandWhat it does
chainsaw sbom diffDiff two SBOMs (CycloneDX or in-toto), reporting added, removed, and version-changed components
chainsaw sbom exportExport org SBOM in CycloneDX format
chainsaw sbom verifyVerify a Sigstore-signed CycloneDX SBOM bundle
chainsaw sbom vexCycloneDX VEX commands
    chainsaw sbom vex exportExport org exceptions as a CycloneDX 1.6 VEX document
chainsaw sbom [command]

chainsaw sbom diff

Diff two SBOMs (CycloneDX or in-toto), reporting added, removed, and version-changed components

chainsaw sbom diff <a.json> <b.json> [flags]

Diff two SBOM files. The format of each input is auto-detected: CycloneDX documents (bomFormat=“CycloneDX”) and in-toto Statements wrapping a CycloneDX predicate are both accepted. Both inputs must be the same format — mixing CycloneDX and in-toto in a single diff is not supported in this iteration.

JSON output (–format json) is a versioned envelope:

{ “schemaVersion”: “chainsaw.sbomdiff/v1”, “added”: [ {“name”,“version”,“type”,“ecosystem”,“purl”}, … ], “removed”: [ … same shape … ], “changed”: [ {“name”,“type”,“ecosystem”,“oldVersion”,“newVersion”}, … ] }

The three arrays are always present and always arrays — an empty diff emits [] , never null, so a consumer can iterate unconditionally. Pin on schemaVersion: it is bumped only for a backward-incompatible change, and additive fields keep the same version.

Changed in v0.20.3: keys were previously the Go field names (“Added”, “Name”, “OldVersion”) and an empty diff emitted null. Scripts written against a pre-0.20.3 binary need updating.

Flags

FlagTypeDefaultDescription
--formatstringtextOutput format: text or json

The global flags apply here too.

chainsaw sbom export

Export org SBOM in CycloneDX format

chainsaw sbom export [flags]

Flags

FlagTypeDefaultDescription
--ecosystemstring—Filter by ecosystem (e.g. npm, pip, maven)
--formatstringcyclonedxSBOM format: cyclonedx (default) or spdx (SPDX 2.3, rendered client-side from the CycloneDX document)
--packagestring—Filter by package name@version
--with-attributionbool—Include per-component attribution properties (chainsaw:attribution:*) derived from existing audit data. Overrides the server’s sbom.attribution_enabled config for this export.

The global flags apply here too.

chainsaw sbom verify

Verify a Sigstore-signed CycloneDX SBOM bundle

chainsaw sbom verify [flags]

Verify a Sigstore-signed CycloneDX SBOM bundle against the SBOM document it attests to. Confirms:

  • The bundle’s signature validates against the live Sigstore trust root (Rekor + Fulcio).
  • The in-toto subject digest matches sha256(canonical(SBOM)).
  • The predicateType is CycloneDX (not a different in-toto predicate).

On success the verified signer identity is printed: source repository URL, builder OIDC subject, and OIDC issuer. Exits non-zero on any failure so CI pipelines can gate on the verify step.

Flags

FlagTypeDefaultDescription
--bomstring—Path to the CycloneDX SBOM JSON file the bundle attests to (required)
--bundlestring—Path to the Sigstore bundle JSON file (required)
--cache-dirstring—Optional Sigstore bundle cache directory (defaults to no caching)
--cache-ttlduration24h0m0sCache entry TTL when –cache-dir is set
--jsonbool—Emit machine-readable JSON instead of the human summary

The global flags apply here too.

chainsaw sbom vex

CycloneDX VEX commands

chainsaw sbom vex [command]

chainsaw sbom vex export

Export org exceptions as a CycloneDX 1.6 VEX document

chainsaw sbom vex export [flags]

Export active exceptions as CycloneDX VEX statements. Each active exception with a CVE reference becomes a vulnerabilities[] entry whose analysis.state reflects Chainsaw’s stance:

decision=allow → exploitable, response=[will_not_fix] decision=monitor → in_triage

A Chainsaw exception is a risk acceptance: the vulnerable package is present and you have chosen to ship it. That is exploitable, not not_affected — encoding it as not_affected tells a downstream scanner the vulnerable code is absent from your product and it will suppress the finding.

The exception’s note rides along in analysis.detail verbatim. It is not parsed into a justification: only you can assert reachability, and Chainsaw will not make that claim on your behalf.

Denied and expired exceptions are excluded, as are exceptions still awaiting approval — an unapproved exception grants nothing at enforcement time, so it must not be published as a compliance statement.

Flags
FlagTypeDefaultDescription
--orgstring—Org id (defaults to configured org)
-o, --outputstring—Write VEX to file instead of stdout

The global flags apply here too.