This page is generated from the real command-line parser; a drift test fails if it falls behind the shipped CLI, so what you read here is exactly what --help prints. It covers the primary operator workflow in order, then the grouped index of every command, then every command's options table. Each command's full page — examples, exit codes, outputs and see-also — is on its group page (cli-<group>.md) and in sbomflow help <command>.
Offline
Every command here is offline by default; network access happens only through one of the 15 opt-in network switches the network-policy registry declares: - named flags: --apply, --resolve-west-imports, --source csaf-provider, --use-epss, --use-kev, --use-nvd, --use-osv - explicit invocations: explicit component-support fetch invocation, explicit vulndb update invocation, subcommand: fetch, subcommand: update - configuration alone (no flag): config: exploitation.use_kev/use_epss=true with scan.offline=false, config: osv/nvd enabled with scan.offline=false, each job's own config: exploitation.use_kev/use_epss=true with scan.offline=false, each job's own config: osv/nvd enabled with scan.offline=false
Pick what you came to do. Every goal runs on its own, and every step each goal prints is executed offline by the test suite against the bundled demo fixture. sbomflow help goal <id> prints the exact steps, what you bring, the outputs, what stays human, the network posture and a docs link. The list, exactly as sbomflow help goals prints it:
text
Goals — pick the one you need; each works on its own:
sbom Produce SBOMs for a release or a questionnaire
vulnerabilities Triage vulnerabilities with context
release-gate Gate a release in CI
sign-off Sign off a release with named human review
history Track what changed between releases
handoff Hand release evidence to a customer or auditor
custody Keep runtime and test evidence by identity (experimental)
firmware Record firmware and embedded build evidence
post-market Work a post-market vulnerability case (experimental)
ai-evidence Record AI components and AI scan results (in development)
Requirement regimes (optional; CRA available today):
cra Prepare EU CRA release evidence (optional regime)
`sbomflow help goal <id>` prints who a goal is for, what you bring, the exact
steps, what stays human, the network posture and a docs link.
SBOMFlow is the system of record for software and connected-device release
evidence (SBOMs, vulnerabilities and VEX, test and runtime evidence, named human
review) on a deterministic offline engine; regulatory views such as the EU CRA
are optional.
usage: sbomflow setup [-h] [--no-input] [--no-color] [--as-of AS_OF]
[--product-name PRODUCT_NAME] [--product-version PRODUCT_VERSION]
[--product-class CLASS] [--output OUTPUT]
[--style {system,dark,light,high-contrast,ansi,none}] [target]
Guided, interactive first-run onboarding: detect the product, confirm
identity and output location, preview exactly what will be written, then
run the first offline audit and explain the result.
Requires a real terminal; it never prompts in CI or redirected IO, and
without a terminal it prints the scriptable path (`sbomflow quickstart .`)
and exits 2.
positional arguments:
target Product directory.
options:
-h, --help show this help message and exit
--no-input, --non-interactive
Never prompt; exit with guidance to the scriptable
path (for CI/automation).
--no-color Disable ANSI color output.
--as-of AS_OF Optional ISO timestamp for a deterministic first
audit.
--product-name PRODUCT_NAME
Use this as the editable detected-name default.
--product-version PRODUCT_VERSION
Use this as the editable detected-version default.
--product-class CLASS
Use this as the editable declared-class default;
SBOMFlow does not classify the product. One of:
default, important-class-i, important-class-ii,
critical.
--output OUTPUT Use this as the editable output-directory default
(directory).
--style {system,dark,light,high-contrast,ansi,none}
Use this terminal output style without prompting for a
style.
Next: sbomflow review <output-dir> · open the evidence-bundle.html
Reads the target directory, and your answers at the prompts of a real
terminal.
Writes evidence-pack.json (the first pack, after a preview you confirm);
sbomflow.yaml, never over one unconfirmed
Exit 0 ok · 2 no real terminal, or a usage error
Examples:
# In a terminal, walk the guided first run; with no terminal (CI, a pipe) it
# prints the scriptable path instead and exits 2.
sbomflow setup .
# Never prompt: print the scriptable path for automation and exit 2.
sbomflow setup . --no-input
# Pre-fill the editable defaults the wizard offers; with no terminal it
# still asks nothing and exits 2.
sbomflow setup . --product-name Gateway --product-version 2.4.1 --output \
evidence
# Run the wizard in the current directory; with no terminal it prints the
# scriptable path instead and exits 2.
sbomflow setup
See also: `sbomflow quickstart`, `sbomflow doctor`, `sbomflow help goal sbom`.
Network behavior: offline. This command has no network-capable path.
Machine output: human-only-by-design — interactive, TTY-gated onboarding;
refuses CI and redirected IO by design.
usage: sbomflow quickstart [-h] [--output OUTPUT] [--product-name PRODUCT_NAME]
[--product-version PRODUCT_VERSION] [--requirement-regime {cra,none}]
[--no-init] [--zip] [--tour] [--as-of AS_OF] [--ci {github}] [--force]
[--yes] [--json] [target]
The fastest first run: detect the project type, scaffold sbomflow.yaml
(unless --no-init), run a fully offline audit, and print a short summary.
Before the first write it discloses the scope: scan root, output, detected
inputs, a bounded file count, the network posture and what already exists.
It asks only when no target is given; naming a directory, or --yes,
proceeds without a question, so scripts and CI never prompt.
positional arguments:
target Project directory to scan (default: the current
directory).
options:
-h, --help show this help message and exit
--output OUTPUT Where the evidence pack is written (directory).
Default: <target>/sbomflow-evidence.
--product-name PRODUCT_NAME
Override the auto-detected product name.
--product-version PRODUCT_VERSION
Override the auto-detected product version.
--requirement-regime {cra,none}
Which requirement regime this run is executed under:
cra (default) derives the CRA Annex I requirement
graph, gaps and coverage; none declares that no
requirement regime applies, so no requirement is
assessed and the run records that declaration. Under
none the empty evidence gaps mean NOT ASSESSED, never
'no gaps'. Overrides requirement_regime in
sbomflow.yaml.
--no-init Do not scaffold sbomflow.yaml (audit with detected
defaults only).
--zip Also write the deterministic bundle zip.
--tour After the summary, print a numbered, copy-paste guided
tour through the release workflow, filled with this
run's real paths. Pure print, CI-safe.
--as-of AS_OF Pinned timestamp for a reproducible first run.
--ci {github} Instead of auditing, emit a ready-to-commit CI
workflow (offline audit + gate + PR annotations +
evidence upload). Currently: github.
--force With --ci, overwrite an existing workflow file
(default: refuse).
--yes Accept the disclosed scope without being asked. Only a
run with no target given is ever asked; the disclosure
itself is always printed.
--json Emit the pre-write disclosure as deterministic JSON
and exit without writing anything or auditing. Same
facts as the text form, including the labelled
bounded-count state and the output-directory state.
Next: open <output>/evidence-bundle.html · sbomflow review <output>
Reads the target directory only.
Writes evidence-pack.json (and the rest of the pack, into --output);
sbomflow.yaml, never over an existing one; stdout (the disclosure;
--json prints only that)
Exit 0 ok, including a declined confirmation · 2 usage or input error
Examples:
# Scan the project, scaffold its config and run the first offline audit.
sbomflow quickstart . --output evidence --as-of 2026-06-26T12:00:00+00:00
# Print the pre-write disclosure as JSON and exit without writing anything.
sbomflow quickstart . --json
# Run with no requirement regime assessed and no config scaffolded, then
# print the guided tour.
sbomflow quickstart . --output evidence --requirement-regime none \
--no-init --tour
# Write a ready-to-commit GitHub Actions workflow instead of auditing.
sbomflow quickstart . --ci github
# Naming the directory is the go-ahead: detect, scaffold config, run an
# offline audit and summarize, with no question asked.
sbomflow quickstart .
See also: `sbomflow audit`, `sbomflow doctor`, `sbomflow init`,
`sbomflow help goal sbom`.
Network behavior: offline. This command has no network-capable path.
Machine output: has-json — one versioned JSON document on stdout
(`sbomflow-quickstart-preflight-v1`, or
`sbomflow-quickstart-ci-preflight-v1` under `--ci` — two shapes, so two
names). The RUN's machine interface is still the artifact set it writes;
`--json` serves the *pre-write disclosure* instead — the same document the
terminal form renders, so a caller reading JSON and a caller reading the
terminal cannot reach different conclusions about the scan root, the bounded
and labelled file count, or which of the five states the output directory is
in. It emits that document and exits without writing, auditing or
consenting.
usage: sbomflow doctor [-h] [--json] [--pilot] [--fix] [--apply]
[--release-manifest RELEASE_MANIFEST] [--public-key PUBLIC_KEYS]
[--vulndb-dir VULNDB_DIR] [--analysis-control PATH]
[--observed-at TIMESTAMP] [target]
Report local environment and config facts before a first run: Python version,
optional extras, config discovery/validity, and what a scan would pick up. It
fabricates nothing and changes nothing.
--pilot adds the machine-checkable half of the pilot-readiness checklist: a
smoke analysis of a synthetic product, a pinned determinism double-run, disk
space, and target writability (a temporary directory and a deleted write-probe
in the target). It reports whether the ENVIRONMENT is ready — never the
product, the evidence, or the review workflow.
TARGET is one existing place, and doctor never substitutes another for it.
Accepted: an existing directory (the project root), or an existing SBOMFlow
config file — sbomflow.yaml / sbomflow.yml / sbomflow.json, the project marker
— whose directory is the root. Refused, with a stable code and before anything
is read or written: a path that does not exist (E001), one that cannot be
examined (E004), a symbolic link named as the target, a regular file that is
not a config file, and any other file type (E019). There is no fallback to the
parent directory, a neighbour, or the current directory, and a repair never
creates a directory. `..` is resolved, not refused, so every path printed is
the physical one that will be touched.
--fix prints a plan of provably safe, reversible remediations (a mischosen
config-key casing, a missing inert *.TEMPLATE.json review scaffold) — never a
reviewer decision file or evidence artifact. Without --apply it is the dry
run: it reads only, writes nothing, and lists every proposed path,
precondition and reversal. --apply executes only the actions still valid at
apply time, each re-checked against the resolved target immediately before its
write, so a plan cannot authorise a write into a substituted path. A
precondition that has drifted since the plan was built is skipped with a
reason and every other action still proceeds (exit 0); a target that changed
under the run, or a write the filesystem refused, is reported per action and
exits 2. Rolling back is the reversal line printed beside each action.
--analysis-control PATH runs the offline runtime control receipt: a packaged
reserved synthetic corpus is executed in a throwaway directory and PATH
records which named controls THIS INSTALLATION could perform. It reads no
customer project and reaches no verdict about one. Exit 0 only when every
declared control passed; a written degraded/failed/indeterminate receipt exits
6.
positional arguments:
target Target dir or config file.
options:
-h, --help show this help message and exit
--json Emit machine-readable doctor output.
--pilot Also run the design-partner pilot preflight: smoke
analysis, pinned determinism double-run, disk space,
and target writability. Checks the environment only,
never product or evidence readiness.
--fix Print a plan of safe, reversible remediations. Print-
first: plans nothing to disk by itself.
--apply With --fix, execute the plan's still-valid actions
(skips any with a drifted precondition).
--release-manifest RELEASE_MANIFEST
Signed release-manifest.json to compare the installed
version and local vulndb snapshot against, fully
offline (never fetched, never auto-updated).
--public-key PUBLIC_KEYS
PEM public key to trust for --release-manifest
verification (repeatable).
--vulndb-dir VULNDB_DIR
Local vulndb snapshot directory for --release-manifest
freshness comparison (default: .sbomflow-vulndb,
matching `sbomflow vulndb --dir`).
--analysis-control PATH
Run the offline runtime control receipt against the
packaged reserved diagnostic corpus and write it to
PATH. Reads no customer project, writes nothing else,
and reaches no verdict about any product.
--observed-at TIMESTAMP
Observation time to record on the --analysis-control
receipt (RFC 3339). Omitted, no time is recorded
rather than invented.
Next: sbomflow quickstart . · sbomflow audit . --output evidence
Reads the target directory or config file, and this installation.
Writes stdout (the report; --json prints JSON);
analysis-control-receipt.json (with --analysis-control); --fix
--apply: only its planned repairs
Exit 0 ok, even when the report names problems · 2 refused target or
unwritable path · 6 control receipt written, not healthy
Examples:
# Report the environment and config facts for a project.
sbomflow doctor .
# Print a plan of safe, reversible repairs without writing anything.
sbomflow doctor . --fix
# Write this installation's offline control receipt.
sbomflow doctor . --analysis-control analysis-control-receipt.json
See also: `sbomflow quickstart`, `sbomflow validate-config`,
`sbomflow support-bundle`, `sbomflow help exit`.
Network behavior: offline. This command has no network-capable path.
Machine output: has-json — one versioned JSON document on stdout.
usage: sbomflow init [-h] [--force] [--with-review-templates]
[--with-source-stubs] [--product-name PRODUCT_NAME]
[--product-version PRODUCT_VERSION] [--product-class CLASS]
[--requirement-regime {cra,none}] [target]
Write a placeholder sbomflow.yaml for a project: product identity,
the declared class and the requirement regime, each a value you edit.
The template flags add inert *.TEMPLATE.json reviewer files and routing
stubs; they record no decision, and init never classifies the product.
An existing config is refused (exit 3) unless --force is given.
positional arguments:
target Directory to write sbomflow.yaml into (default: the
current directory).
options:
-h, --help show this help message and exit
--force Overwrite an existing sbomflow.yaml.
--with-review-templates
Write TEMPLATE reviewer files with no real decisions.
--with-source-stubs Write TEMPLATE gap-owner routing and reviewer-role
policy stubs (no decisions).
--product-name PRODUCT_NAME
Initial product.name value.
--product-version PRODUCT_VERSION
Initial product.version value.
--product-class CLASS
Initial declared product.class value. SBOMFlow does
not classify the product. One of: default, important-
class-i, important-class-ii, critical.
--requirement-regime {cra,none}
Initial requirement_regime value (default: cra).
`none` scaffolds a config with no product.class,
technical_documentation, annex_i_evidence or
due_diligence keys, so a following run is a none run
that trips no requirement-regime preflight refusal.
Reads the target directory, to see whether a config is already there.
Writes sbomflow.yaml, and inert *.TEMPLATE.json files
Exit 0 ok · 2 usage or input error · 3 a config exists and --force was not
given
Examples:
# Overwrite the project's config with a fresh scaffold.
sbomflow init . --force
# Scaffold a config that assesses no requirement regime.
sbomflow init . --force --requirement-regime none
# Also write inert reviewer templates that record no decision.
sbomflow init . --force --with-review-templates
# Refuse to overwrite a config that is already there.
sbomflow init .
See also: `sbomflow validate-config`, `sbomflow quickstart`,
`sbomflow doctor`.
Network behavior: offline. This command has no network-capable path.
Machine output: artifact-suffices — scaffolds `sbomflow.yaml` and inert review
templates; the scaffolded files are the product.
usage: sbomflow validate-config [-h] path
Validate one sbomflow.yaml or .json against the config schema and report each
error and warning with the key it concerns. Read-only; it scans nothing. A
config that is missing or invalid exits 2.
positional arguments:
path Config file to validate.
options:
-h, --help show this help message and exit
Reads one config file (sbomflow.yaml or .json).
Writes stdout (each error and warning with its key)
Exit 0 valid, or valid with warnings · 2 a missing or invalid config
Examples:
# Validate the project's config.
sbomflow validate-config ./sbomflow.yaml
# Validate a freshly scaffolded config.
sbomflow validate-config ./sbomflow.yaml
# Refuse a config file that is not there.
sbomflow validate-config missing.yaml
See also: `sbomflow config show`, `sbomflow init`, `sbomflow doctor`,
`sbomflow validate-graph`.
Network behavior: offline. This command has no network-capable path.
Machine output: artifact-suffices — the same config validation surfaces
machine-readably in `doctor` `--json` (config block: errors and warnings).
Served by `sbomflow doctor`.
usage: sbomflow audit [-h] [--report-theme {light,dark}] --output OUTPUT
[--on-existing-output {overlay,clean,refuse}] [--config CONFIG]
[--store DIR] [--product-name PRODUCT_NAME]
[--product-version PRODUCT_VERSION] [--product-class CLASS]
[--requirement-regime {cra,none}] [--as-of AS_OF]
[--import-sbom IMPORT_SBOMS]
[--import-custom-manifest IMPORT_CUSTOM_MANIFESTS]
[--supplier-vex SUPPLIER_VEX] [--test-results TEST_RESULTS]
[--assessment-findings PATH] [--ai-manifest AI_MANIFEST]
[--debian-tracker-snapshot DEBIAN_TRACKER_SNAPSHOT]
[--alpine-secdb-snapshot ALPINE_SECDB_SNAPSHOTS]
[--build-provenance BUILD_PROVENANCE]
[--build-provenance-public-key PEM_FILE]
[--support-policy SUPPORT_POLICY] [--offline] [--use-osv]
[--use-sample-feed] [--osv-snapshot OSV_SNAPSHOT] [--vulndb-dir DIR]
[--osv-timeout OSV_TIMEOUT] [--osv-base-url OSV_BASE_URL]
[--osv-cache-dir OSV_CACHE_DIR] [--use-nvd] [--nvd-file NVD_FILE]
[--nvd-timeout NVD_TIMEOUT] [--nvd-base-url NVD_BASE_URL] [--use-kev]
[--kev-file KEV_FILE] [--use-epss] [--epss-file EPSS_FILE]
[--resolve-west-imports] [--west-name-allowlist WEST_NAME_ALLOWLIST]
[--west-name-blocklist WEST_NAME_BLOCKLIST] [--release-id RELEASE_ID]
[--release-channel RELEASE_CHANNEL] [--release-variant RELEASE_VARIANT]
[--build-id BUILD_ID] [--source-repository SOURCE_REPOSITORY]
[--source-revision SOURCE_REVISION] [--build-started-at BUILD_STARTED_AT]
[--build-finished-at BUILD_FINISHED_AT]
[--support-period-ends-at SUPPORT_PERIOD_ENDS_AT]
[--support-promise KIND=DATE] [--previous-output PREVIOUS_OUTPUT]
[--reviews REVIEWS] [--vulnerability-reviews VULNERABILITY_REVIEWS]
[--reachability-evidence REACHABILITY_EVIDENCE]
[--tree-sitter-reachability] [--approvals APPROVALS] [--waivers WAIVERS]
[--require-role ROLE] [--policy POLICY] [--policy-profile NAME]
[--gate-dry-run] [--fail-on-gaps] [--fail-on-unreviewed]
[--fail-on-vulnerabilities] [--fail-on-kev] [--fail-on-denied-license]
[--fail-on-reachable-vulnerabilities] [--fail-on-new-vulnerabilities]
[--fail-on-new-kev] [--fail-on-new-reachable-vulnerabilities]
[--fail-on-new-critical-or-high] [--fail-on-evidence-regression]
[--fail-on-support-period-missing] [--fail-on-missing-approvals]
[--epss-threshold EPSS_THRESHOLD]
[--severity-threshold {none,low,medium,high,critical}] [--emit-sarif]
[--emit-spdx3] [--emit-mlbom] [--emit-aibom] [--emit-traceability]
[--share-profile {importer,distributor,customer}] [--emit-metrics]
[--emit-issues-csv] [--emit-pdf] [--zip]
[--scan-cache-dir SCAN_CACHE_DIR] [--scan-jobs N] [--strict]
[--break-stale-lock] [--json] target
One-command release audit: analyze the build, emit the default evidence
artifacts plus the reviewer bundle, and validate everything it wrote.
The audit composes existing deterministic artifacts; it adds no authority
and makes no conformity claim. Human review stays separate and explicit.
Shorter view: `sbomflow help audit` — required inputs, common options and the
option groups by job; `sbomflow help audit <group>` opens one group. Nothing
is hidden there: that layer is shorter, not smaller.
positional arguments:
target Product source/build directory to scan.
options:
-h, --help show this help message and exit
--report-theme {light,dark}
Palette for generated HTML surfaces (default: light).
Print output is always light.
--break-stale-lock Remove a provably-stale .sbomflow.lock (crashed run)
from the output directory before running. Never
automatic; confirm no other run is active first.
product identity & config:
--output OUTPUT Where the evidence outputs are written (directory).
--on-existing-output {overlay,clean,refuse}
What to do when --output already holds a previous run:
overlay (default, write over it), clean (first remove
SBOMFlow's own artifacts, never your files), or refuse
(write nothing, exit 2).
--config CONFIG Path to a sbomflow.yaml/.json config file.
--store DIR Local evidence store holding prior releases of this
product. When given, writes cross-release context
(offline, read-only): evidence-aging.json (releases
since a human last accepted each requirement),
finding-regressions.json (resolved findings that
reappeared), and carry-forward.json (prior human
decisions on findings seen again here).
--product-name PRODUCT_NAME
Override the product name.
--product-version PRODUCT_VERSION
Override the product version.
--product-class CLASS
Declared product class to record. The engine does not
classify the product. One of: default, important-
class-i, important-class-ii, critical.
--requirement-regime {cra,none}
Which requirement regime this run is executed under:
cra (default) derives the CRA Annex I requirement
graph, gaps and coverage; none declares that no
requirement regime applies, so no requirement is
assessed and the run records that declaration. Under
none the empty evidence gaps mean NOT ASSESSED, never
'no gaps'. Overrides requirement_regime in
sbomflow.yaml.
--as-of AS_OF ISO timestamp to use as 'now' (for
reproducible/freshness-pinned runs).
local evidence inputs (offline; hashed as provenance):
--import-sbom IMPORT_SBOMS
Import a local supplier CycloneDX/SPDX JSON SBOM as
observed evidence. Repeatable.
--import-custom-manifest IMPORT_CUSTOM_MANIFESTS
Import a local SBOMFlow custom manifest (explicit
component + dependency evidence). Repeatable; offline.
--supplier-vex SUPPLIER_VEX
Import a local supplier OpenVEX/CSAF/CycloneDX VEX
document as context only. Repeatable.
--test-results TEST_RESULTS
Attach a local JUnit XML, TAP or Robot Framework
output.xml result file as observed test evidence.
Repeatable.
--assessment-findings PATH
A local sbomflow-assessment-findings-v1 file restating
the findings an assessment report listed (penetration
test, lab evaluation, audit, bug bounty). Writes
assessment-findings-ledger.json: each finding stays
open until a named reviewer records a decision under
assessment:<source>:<id> in the reviews input.
Observations only; never a gate input. Offline.
--ai-manifest AI_MANIFEST
Read a local declared AI manifest (models, datasets,
prompts, services, agents) and record it beside what
the scan observed, in `ai-evidence.json`. Offline: one
local file, no lookup. A declaration is what somebody
SAID; where it disagrees with an observation both are
kept and the disagreement is surfaced for a human,
never resolved.
--debian-tracker-snapshot DEBIAN_TRACKER_SNAPSHOT
Read a pinned local Debian security-tracker JSON
snapshot and annotate findings with the distro's
patched-status (no network).
--alpine-secdb-snapshot ALPINE_SECDB_SNAPSHOTS
Read a pinned local Alpine secdb branch file and
annotate findings with the distro's patched-status (no
network). Repeatable.
--build-provenance BUILD_PROVENANCE
Local in-toto/SLSA-shaped statement or DSSE envelope
to record.
--build-provenance-public-key PEM_FILE
Local PEM public key for optional DSSE signature
verification (sbomflow[attest]).
--support-policy SUPPORT_POLICY
Local support-policy artifact to hash into the release
record.
advisory & exploitation sources (local snapshots; --use-* reaches the network):
--offline Force offline mode, overriding config.
--use-osv Query the real OSV API (osv.dev) over the network. Off
by default.
--use-sample-feed Use the bundled SYNTHETIC sample advisory feed (CVE-
SAMPLE-*). Illustrative demo/example data only, never
intelligence about your product.
--osv-snapshot OSV_SNAPSHOT
Local OSV-format advisory snapshot (JSON list,
`{'vulns': [...]}`, JSONL, or an OSV per-ecosystem
all.zip) matched offline with the range engine instead
of the non-real sample feed. Config: osv.snapshot.
Never a live lookup.
--vulndb-dir DIR Local vulndb store whose active CSAF advisory mirror
(`vulndb update --source-type csaf-directory`) is
matched in this run. Offline: that store's index and
its active csaf-directory snapshot are read, nothing
is fetched, and the store becomes the run's recorded
source set. No default is assumed: without it no store
is guessed from the working directory or
configuration. Refused if it is not a directory, or if
another option names a different store.
--osv-timeout OSV_TIMEOUT
OSV request timeout in seconds.
--osv-base-url OSV_BASE_URL
Override the OSV API base URL.
--osv-cache-dir OSV_CACHE_DIR
Directory to cache OSV records (keyed by id,
invalidated by modified time).
--use-nvd Enrich CVE findings from the live NIST NVD API
(network). Off by default.
--nvd-file NVD_FILE Local NVD CVE API 2.0 snapshot to enrich offline (no
network): a .json file, a .json.gz file, or a .zip
holding one .json document.
--nvd-timeout NVD_TIMEOUT
NVD request timeout in seconds.
--nvd-base-url NVD_BASE_URL
Override the NVD CVE API base URL.
--use-kev Enrich findings against the live CISA KEV catalog
(network). Off by default.
--kev-file KEV_FILE Local CISA KEV catalog JSON snapshot to enrich offline
(no network).
--use-epss Enrich findings with live FIRST EPSS scores (network).
Off by default.
--epss-file EPSS_FILE
Local FIRST EPSS snapshot (.csv or .json) to enrich
offline (no network).
--resolve-west-imports
Resolve Zephyr west 'import:' manifests over the
network. Off by default.
--west-name-allowlist WEST_NAME_ALLOWLIST
Comma-separated project names to include from resolved
west imports.
--west-name-blocklist WEST_NAME_BLOCKLIST
Comma-separated project names to exclude from resolved
west imports.
release metadata (declared by you/CI; local/offline):
--release-id RELEASE_ID
Manufacturer/CI-declared release id.
--release-channel RELEASE_CHANNEL
Release channel, e.g. stable/beta.
--release-variant RELEASE_VARIANT
Hardware/software release variant.
--build-id BUILD_ID CI/build-system identifier for this release.
--source-repository SOURCE_REPOSITORY
Source repository URL or local identifier.
--source-revision SOURCE_REVISION
Source revision used for this release.
--build-started-at BUILD_STARTED_AT
Build start timestamp from CI metadata.
--build-finished-at BUILD_FINISHED_AT
Build completion timestamp from CI metadata.
--support-period-ends-at SUPPORT_PERIOD_ENDS_AT
Manufacturer-declared support-period end.
--support-promise KIND=DATE
What this release promises until DATE, one kind per
use: KIND is security_updates, software_maintenance or
hardware_availability. Repeatable; replaces
release.support_promises for that kind. Each kind is
read on its own (a hardware date never answers a
security-update question).
--previous-output PREVIOUS_OUTPUT
Previous SBOMFlow output directory; enables release-
drift.json.
human review & approvals (read here; written by review/approve):
--reviews REVIEWS Evidence reviewer-decisions file to apply; without it
(or reviews: in sbomflow.yaml) no decision is applied.
--vulnerability-reviews VULNERABILITY_REVIEWS
Vulnerability VEX-triage decisions file to apply.
--reachability-evidence REACHABILITY_EVIDENCE
Manufacturer-supplied reachability evidence inputs
(context, never a decision).
--tree-sitter-reachability
Opt in to bounded Tree-sitter C/C++ call-context
observations (sbomflow[reachability]).
--approvals APPROVALS
Release-approval ledger (approvals.json) consulted by
the gate.
--waivers WAIVERS Reviewer-owned waivers file; an unexpired waiver marks
its item 'waived' (still listed).
--require-role ROLE Required release-approval role (repeatable); additive
over a policy profile.
release-gate policy (informational unless a flag is set):
--policy POLICY Standalone named/versioned release-gate policy profile
(.json/.yaml).
--policy-profile NAME
Apply a shipped, versioned policy preset by name.
Overridden by --policy.
--gate-dry-run Rehearse the gate: evaluate and report fully, mark
release-gate.json dry_run, and always exit 0 (never
blocks). For CI adoption before enforcing.
--fail-on-gaps Exit non-zero if missing-evidence gaps meet the
severity threshold.
--fail-on-unreviewed Exit non-zero if observed evidence has not been human-
reviewed.
--fail-on-vulnerabilities
Exit non-zero if advisory findings meet the severity
threshold.
--fail-on-kev Exit non-zero if any finding is in the CISA KEV
catalog (known exploited).
--fail-on-denied-license
Exit non-zero if a component declares a license on
your policy's license_policy.deny list (engineering
context against your own list, never legal advice;
only for single valid SPDX expressions).
--fail-on-reachable-vulnerabilities
Exit non-zero for source-referenced findings meeting
the threshold/policy context.
--fail-on-new-vulnerabilities
Exit non-zero when release drift contains new advisory
findings.
--fail-on-new-kev Exit non-zero when release drift contains newly known-
exploited findings.
--fail-on-new-reachable-vulnerabilities
Exit non-zero when release drift contains newly
source-referenced findings.
--fail-on-new-critical-or-high
Exit non-zero when release drift contains new or
escalated critical/high findings.
--fail-on-evidence-regression
Exit non-zero when release drift contains new gaps,
regressions, or re-review needs.
--fail-on-support-period-missing
Exit non-zero when current release metadata lacks
support_period_ends_at.
--fail-on-missing-approvals
Exit non-zero when required approval roles are unmet
and no override is recorded.
--epss-threshold EPSS_THRESHOLD
Exit non-zero if any finding's FIRST EPSS score is >=
this value (0..1).
--severity-threshold {none,low,medium,high,critical}
Severity floor for --fail-on-gaps / --fail-on-
vulnerabilities (default: low).
extra outputs & sharing (all optional):
--emit-sarif Also write findings.sarif (SARIF 2.1.0) for observed
gaps and findings.
--emit-spdx3 Also write spdx3-sbom.json (SPDX 3.0.1 JSON-LD).
--emit-mlbom Also write cyclonedx-mlbom.json (CycloneDX 1.6 ML-BOM;
BOM-Linked to the SBOM).
--emit-aibom Also write spdx3-aibom.json (SPDX 3.0.1 AI + Dataset
profiles).
--emit-traceability Also write traceability.json (cross-entity node/edge
index; a derived view).
--share-profile {importer,distributor,customer}
Also write a redacted evidence-sharing pack for the
chosen profile (sharing-pack.json/html/zip). Adds no
authority and no conformity claim.
--emit-metrics Also write local metrics.json (aggregate counts, gate
state, phase durations, tool metadata, and declared
release metadata).
--emit-issues-csv Also write issues.csv, a spreadsheet-friendly
projection of issues.json.
--emit-pdf Also write evidence-summary.pdf and include it in the
bundle.
--zip Write evidence-bundle.zip.
performance & cache (never change output bytes):
--scan-cache-dir SCAN_CACHE_DIR
Optional content-addressed scan cache for faster
repeat scans of unchanged files.
--scan-jobs N Hash files with N parallel workers (default 1);
ignored with --scan-cache-dir.
machine output & strictness:
--strict Enforce the manufacturer's strict policy set. This is
not a CRA conformity determination.
--json Emit one machine-readable summary.
Next: sbomflow review evidence · sbomflow explain evidence --gate
Reads the build directory, optional sbomflow.yaml and local inputs the
flags name.
Writes evidence-pack.json (and the default artifacts, into --output);
release-gate.json; artifact-manifest.json (the reviewer bundle);
evidence-bundle.zip with --zip; stdout (the summary; --json prints
JSON)
Exit 0 ok · 1 an enforced gate blocked the release · 2 usage, input, IO or
config error · 4 a written artifact failed validation
Examples:
# Run the full offline evidence pack for one release.
sbomflow audit . --output out
# Also write the deterministic evidence-bundle.zip to hand over.
sbomflow audit . --output evidence --zip
# Enforce the evidence-gap gate; it blocks this demo and exits 1 with every
# artifact written.
sbomflow audit . --output evidence --fail-on-gaps
# Print one machine-readable summary instead of the text report.
sbomflow audit . --output evidence --json
# Audit with no requirement regime assessed.
sbomflow audit . --output evidence --requirement-regime none
# Write one release's full offline evidence pack into evidence, the
# directory the first steps read.
sbomflow audit . --output evidence
See also: `sbomflow analyze`, `sbomflow review`, `sbomflow bundle`,
`sbomflow explain`, `sbomflow help auditing`, `sbomflow help goal sign-off`.
Network behavior: opt-in-network. The default path is offline; only the listed
flags/config enable egress. Gates: --use-osv, --use-nvd, --use-kev,
--use-epss, --resolve-west-imports, config: osv/nvd enabled with
scan.offline=false, config: exploitation.use_kev/use_epss=true with
scan.offline=false.
Machine output: has-json — read/status surface; one versioned JSON document on
stdout.
usage: sbomflow analyze [-h] [--report-theme {light,dark}] --output OUTPUT
[--on-existing-output {overlay,clean,refuse}] [--config CONFIG]
[--store DIR] [--product-name PRODUCT_NAME]
[--product-version PRODUCT_VERSION] [--product-class CLASS]
[--requirement-regime {cra,none}] [--use-osv] [--use-sample-feed]
[--osv-snapshot OSV_SNAPSHOT] [--vulndb-dir DIR] [--offline]
[--resolve-west-imports] [--west-import-dir DIR]
[--west-name-allowlist WEST_NAME_ALLOWLIST]
[--west-name-blocklist WEST_NAME_BLOCKLIST] [--osv-timeout OSV_TIMEOUT]
[--osv-base-url OSV_BASE_URL] [--osv-cache-dir OSV_CACHE_DIR]
[--scan-cache-dir SCAN_CACHE_DIR] [--scan-jobs N] [--use-nvd]
[--nvd-file NVD_FILE] [--nvd-timeout NVD_TIMEOUT]
[--nvd-base-url NVD_BASE_URL] [--policy POLICY] [--policy-profile NAME]
[--use-kev] [--kev-file KEV_FILE] [--use-epss] [--epss-file EPSS_FILE]
[--reviews REVIEWS] [--vulnerability-reviews VULNERABILITY_REVIEWS]
[--reachability-evidence REACHABILITY_EVIDENCE]
[--ai-manifest AI_MANIFEST]
[--debian-tracker-snapshot DEBIAN_TRACKER_SNAPSHOT]
[--alpine-secdb-snapshot ALPINE_SECDB_SNAPSHOTS]
[--tree-sitter-reachability] [--ssvc-context SSVC_CONTEXT]
[--incident-awareness-at INCIDENT_AWARENESS_AT]
[--incident-measure-available-at INSTANT]
[--incident-notification-submitted-at INSTANT]
[--import-sbom IMPORT_SBOMS]
[--import-custom-manifest IMPORT_CUSTOM_MANIFESTS]
[--supplier-vex SUPPLIER_VEX] [--test-results TEST_RESULTS]
[--assessment-findings PATH] [--as-of AS_OF] [--release-id RELEASE_ID]
[--release-channel RELEASE_CHANNEL] [--release-variant RELEASE_VARIANT]
[--build-id BUILD_ID] [--source-repository SOURCE_REPOSITORY]
[--source-revision SOURCE_REVISION] [--build-started-at BUILD_STARTED_AT]
[--build-finished-at BUILD_FINISHED_AT]
[--support-period-ends-at SUPPORT_PERIOD_ENDS_AT]
[--support-promise KIND=DATE] [--support-policy SUPPORT_POLICY]
[--previous-output PREVIOUS_OUTPUT] [--build-provenance BUILD_PROVENANCE]
[--build-provenance-public-key PEM_FILE] [--gate-dry-run]
[--fail-on-gaps] [--fail-on-unreviewed] [--fail-on-vulnerabilities]
[--fail-on-kev] [--fail-on-denied-license]
[--fail-on-reachable-vulnerabilities] [--fail-on-new-vulnerabilities]
[--fail-on-new-kev] [--fail-on-new-reachable-vulnerabilities]
[--fail-on-new-critical-or-high] [--fail-on-evidence-regression]
[--fail-on-support-period-missing] [--fail-on-missing-approvals]
[--require-role ROLE] [--approvals APPROVALS] [--waivers WAIVERS]
[--epss-threshold EPSS_THRESHOLD]
[--severity-threshold {none,low,medium,high,critical}] [--emit-vex]
[--emit-vdr] [--emit-techdoc] [--emit-incident-report] [--emit-ssvc]
[--emit-sarif] [--emit-spdx3] [--emit-mlbom] [--emit-aibom]
[--drift-html] [--emit-traceability] [--emit-issues-csv] [--emit-pdf]
[--emit-bundle] [--share-profile {importer,distributor,customer}]
[--emit-metrics] [--break-stale-lock] [--strict [STRICT_WARNINGS]] target
Scan one product/build directory and write the default deterministic
evidence artifacts (evidence pack, SBOMs, coverage, gate, report, ...).
`sbomflow audit` wraps this with the reviewer bundle and validation.
Shorter view: `sbomflow help analyze` — required inputs, common options and
the option groups by job; `sbomflow help analyze <group>` opens one group.
Nothing is hidden there: that layer is shorter, not smaller.
positional arguments:
target Product source/build directory to scan.
options:
-h, --help show this help message and exit
--report-theme {light,dark}
Palette for generated HTML surfaces (default: light).
Print output is always light.
--output OUTPUT Where the evidence outputs are written (directory).
--on-existing-output {overlay,clean,refuse}
What to do when --output already holds a previous run:
overlay (default, write over it), clean (first remove
SBOMFlow's own artifacts, never your files), or refuse
(write nothing, exit 2).
--config CONFIG Path to a sbomflow.yaml/.json config file.
--store DIR Local evidence store holding prior releases of this
product. When given, writes cross-release context
(offline, read-only): evidence-aging.json (releases
since a human last accepted each requirement),
finding-regressions.json (resolved findings that
reappeared), and carry-forward.json (prior human
decisions on findings seen again here).
--product-name PRODUCT_NAME
Override the product name.
--product-version PRODUCT_VERSION
Override the product version.
--product-class CLASS
Declared product class to record. The engine does not
classify the product. One of: default, important-
class-i, important-class-ii, critical.
--requirement-regime {cra,none}
Which requirement regime this run is executed under:
cra (default) derives the CRA Annex I requirement
graph, gaps and coverage; none declares that no
requirement regime applies, so no requirement is
assessed and the run records that declaration. Under
none the empty evidence gaps mean NOT ASSESSED, never
'no gaps'. Overrides requirement_regime in
sbomflow.yaml.
--policy POLICY Standalone named/versioned release-gate policy profile
(.json/.yaml).
--policy-profile NAME
Apply a shipped, versioned policy preset by name (cra-
critical, cra-default, cra-important, strict-ci).
Overridden by --policy; CLI --fail-on-* flags are
additive.
--as-of AS_OF ISO timestamp to use as 'now' (for
reproducible/freshness-pinned runs).
--break-stale-lock Remove a provably-stale .sbomflow.lock (crashed run)
from the output directory before running. Never
automatic; confirm no other run is active first.
--strict [STRICT_WARNINGS]
Treat scan warnings as errors after artifacts are
written. Use --strict for any warning except the
disclosure-only scan_directory_excluded_by_marker, or
--strict=code1,code2 to scope by warning code (naming
that code counts it) (distinct exit code 5).
OSV advisory lookup & west resolution (network only when enabled):
--use-osv Query the real OSV API (osv.dev) over the network. Off
by default.
--use-sample-feed Use the bundled SYNTHETIC sample advisory feed (CVE-
SAMPLE-*). Illustrative demo/example data only, never
intelligence about your product: artifacts mark it
synthetic and it never counts as usable intelligence.
Without a real source (--use-osv/--osv-snapshot) and
without this flag, no advisory matching is performed
at all.
--osv-snapshot OSV_SNAPSHOT
Local OSV-format advisory snapshot (JSON list,
`{'vulns': [...]}`, JSONL, or an OSV per-ecosystem
all.zip) matched offline with the range engine instead
of the non-real sample feed. Config: osv.snapshot.
Never a live lookup.
--vulndb-dir DIR Local vulndb store whose active CSAF advisory mirror
(`vulndb update --source-type csaf-directory`) is
matched in this run. Offline: that store's index and
its active csaf-directory snapshot are read, nothing
is fetched, and the store becomes the run's recorded
source set. No default is assumed: without it no store
is guessed from the working directory or
configuration. Refused if it is not a directory, or if
another option names a different store.
--offline Force offline mode (never query OSV or resolve west
imports), overriding config.
--resolve-west-imports
Resolve Zephyr west 'import:' directives over the
network (like --use-osv): fetch each imported manifest
and add its modules as components. Off by default;
dropped under --offline.
--west-import-dir DIR
Resolve Zephyr west 'import:' directives from a local
mirror instead of the network: DIR holds one checkout
per project (DIR/<project>/west.yml). Stays OFFLINE
and never falls back to the network. Mutually
exclusive with --resolve-west-imports.
--west-name-allowlist WEST_NAME_ALLOWLIST
Comma-separated project names to include from resolved
west imports.
--west-name-blocklist WEST_NAME_BLOCKLIST
Comma-separated project names to exclude from resolved
west imports.
--osv-timeout OSV_TIMEOUT
OSV request timeout in seconds.
--osv-base-url OSV_BASE_URL
Override the OSV API base URL.
--osv-cache-dir OSV_CACHE_DIR
Directory to cache OSV records (keyed by id,
invalidated by modified time).
performance & cache (never change output bytes):
--scan-cache-dir SCAN_CACHE_DIR
Directory for an optional content-addressed scan cache
that speeds repeat scans of unchanged files. The cache
only speeds up scanning; output is byte-identical with
or without it.
--scan-jobs N Hash files with N parallel workers for large trees
(default 1). Output is byte-identical to a single-
threaded scan; ignored when --scan-cache-dir is set.
NVD CVE enrichment (CVSS/CPE context; off by default):
--use-nvd Enrich CVE findings from the live NIST NVD API
(network). Off by default.
--nvd-file NVD_FILE Local NVD CVE API 2.0 snapshot to enrich offline (no
network): a .json file, a .json.gz file, or a .zip
holding one .json document.
--nvd-timeout NVD_TIMEOUT
NVD request timeout in seconds.
--nvd-base-url NVD_BASE_URL
Override the NVD CVE API base URL.
exploitation intelligence (CISA KEV / FIRST EPSS; off by default):
--use-kev Enrich findings against the live CISA KEV catalog
(network). Off by default.
--kev-file KEV_FILE Local CISA KEV catalog JSON snapshot to enrich offline
(no network).
--use-epss Enrich findings with live FIRST EPSS scores (network).
Off by default.
--epss-file EPSS_FILE
Local FIRST EPSS snapshot (.csv or .json) to enrich
offline (no network).
local evidence & review inputs (offline; hashed as provenance):
--reviews REVIEWS Evidence reviewer-decisions file to apply; without it
(or reviews: in sbomflow.yaml) no decision is applied.
--vulnerability-reviews VULNERABILITY_REVIEWS
Path to a vulnerability VEX-triage decisions file (for
--emit-vex).
--reachability-evidence REACHABILITY_EVIDENCE
Path to manufacturer-supplied reachability evidence
inputs.
--ai-manifest AI_MANIFEST
Read a local declared AI manifest (models, datasets,
prompts, services, agents) and record it beside what
the scan observed, in `ai-evidence.json`. Offline: one
local file, no lookup. A declaration is what somebody
SAID; where it disagrees with an observation both are
kept and the disagreement is surfaced for a human,
never resolved.
--debian-tracker-snapshot DEBIAN_TRACKER_SNAPSHOT
Read a pinned local Debian security-tracker JSON
snapshot and annotate findings with the distro's
patched-status (no network).
--alpine-secdb-snapshot ALPINE_SECDB_SNAPSHOTS
Read a pinned local Alpine secdb branch file and
annotate findings with the distro's patched-status (no
network). Repeatable.
--tree-sitter-reachability
Opt in to bounded Tree-sitter C/C++ call-context
observations. Requires sbomflow[reachability]; regex
scanning remains the baseline.
--ssvc-context SSVC_CONTEXT
Path to manufacturer SSVC context (Automatable /
Mission & Well-being defaults and optional per-finding
overrides) for --emit-ssvc.
--incident-awareness-at INCIDENT_AWARENESS_AT
Instant the manufacturer recorded becoming aware.
Starts the CRA Article 14 24-hour and 72-hour windows
shown in --emit-incident-report. Recorded by you;
never inferred, and never a decision that anything is
reportable.
--incident-measure-available-at INSTANT
Instant a corrective or mitigating measure became
available. Starts the Article 14(2)(c) 14-day final-
report window (actively exploited vulnerability track)
— which does NOT run from awareness.
--incident-notification-submitted-at INSTANT
Instant the manufacturer recorded submitting the
Article 14(4)(b) incident notification, elsewhere.
Starts the Article 14(4)(c) one-month final-report
window (severe-incident track). Recording it here is a
note to yourself; SBOMFlow never submits anything.
--import-sbom IMPORT_SBOMS
Import a local supplier CycloneDX/SPDX JSON SBOM as
observed component evidence. Repeatable; offline and
local-file-only.
--import-custom-manifest IMPORT_CUSTOM_MANIFESTS
Import a local SBOMFlow custom manifest (sbomflow-
custom-manifest v1): explicit component + dependency
evidence a manufacturer declares directly. Repeatable;
offline and local-file-only. See
docs/CUSTOM_MANIFEST.md.
--supplier-vex SUPPLIER_VEX
Import a local supplier OpenVEX/CSAF/CycloneDX JSON
VEX document as context for matching findings.
Repeatable; never suppresses gates by itself.
--test-results TEST_RESULTS
Attach a local JUnit XML, TAP or Robot Framework
output.xml test-result file as observed security-test
evidence for human review. Repeatable; offline only.
--assessment-findings PATH
A local sbomflow-assessment-findings-v1 file restating
the findings an assessment report listed (penetration
test, lab evaluation, audit, bug bounty). Writes
assessment-findings-ledger.json: each finding stays
open until a named reviewer records a decision under
assessment:<source>:<id> in the reviews input.
Observations only; never a gate input. Offline.
release history metadata (local/offline):
--release-id RELEASE_ID
Manufacturer/CI-declared release id.
--release-channel RELEASE_CHANNEL
Release channel, e.g. stable/beta.
--release-variant RELEASE_VARIANT
Hardware/software release variant.
--build-id BUILD_ID CI/build-system identifier for this release.
--source-repository SOURCE_REPOSITORY
Source repository URL or local identifier.
--source-revision SOURCE_REVISION
Source revision used for this release.
--build-started-at BUILD_STARTED_AT
Build start timestamp from CI metadata.
--build-finished-at BUILD_FINISHED_AT
Build completion timestamp from CI metadata.
--support-period-ends-at SUPPORT_PERIOD_ENDS_AT
Manufacturer-declared support-period end.
--support-promise KIND=DATE
What this release promises until DATE, one kind per
use: KIND is security_updates, software_maintenance or
hardware_availability. Repeatable; replaces
release.support_promises for that kind. Each kind is
read on its own (a hardware date never answers a
security-update question).
--support-policy SUPPORT_POLICY
Local support-policy artifact to hash into the release
record.
--previous-output PREVIOUS_OUTPUT
Previous SBOMFlow output directory used to emit
release-drift.json.
--build-provenance BUILD_PROVENANCE
Local in-toto/SLSA-shaped statement or DSSE envelope
to record.
--build-provenance-public-key PEM_FILE
Local PEM public key for optional DSSE build-
provenance signature verification. Requires
sbomflow[attest].
release gate (non-blocking unless a flag is set):
--gate-dry-run Rehearse the gate: evaluate and report fully, mark
release-gate.json dry_run, and always exit 0 (never
blocks). For CI adoption before enforcing.
--fail-on-gaps Exit non-zero if missing-evidence gaps meet the
severity threshold.
--fail-on-unreviewed Exit non-zero if observed evidence has not been human-
reviewed.
--fail-on-vulnerabilities
Exit non-zero if advisory findings meet the severity
threshold.
--fail-on-kev Exit non-zero if any finding is in the CISA KEV
catalog (known exploited).
--fail-on-denied-license
Exit non-zero if a component declares a license on
your policy's license_policy.deny list (engineering
context against your own list, never legal advice;
only for single valid SPDX expressions).
--fail-on-reachable-vulnerabilities
Exit non-zero for source-referenced advisory findings
that meet the severity threshold or enabled KEV/EPSS
policy context.
--fail-on-new-vulnerabilities
Exit non-zero when release drift contains new advisory
findings.
--fail-on-new-kev Exit non-zero when release drift contains newly known-
exploited findings.
--fail-on-new-reachable-vulnerabilities
Exit non-zero when release drift contains newly
source-referenced findings.
--fail-on-new-critical-or-high
Exit non-zero when release drift contains new or
escalated critical/high findings.
--fail-on-evidence-regression
Exit non-zero when release drift contains new gaps,
status regressions, or re-review needs.
--fail-on-support-period-missing
Exit non-zero when current release metadata lacks
support_period_ends_at.
--fail-on-missing-approvals
Exit non-zero when required release-approval roles are
unmet (or a separation-of-duties violation exists) and
no active override is recorded.
--require-role ROLE Required release-approval role (repeatable); additive
over a policy profile.
--approvals APPROVALS
Release-approval ledger (approvals.json) consulted by
the gate.
--waivers WAIVERS Reviewer-owned waivers file (waivers.json) consulted
by the gate. An unexpired waiver moves its exact
gap/finding to 'waived' (still listed); it never
accepts evidence, sets VEX, or claims conformity.
--epss-threshold EPSS_THRESHOLD
Exit non-zero if any finding's FIRST EPSS score is >=
this value (0..1).
--severity-threshold {none,low,medium,high,critical}
Severity floor for --fail-on-gaps / --fail-on-
vulnerabilities (default: low).
extra outputs & exports (all optional):
--emit-vex Also write vex.json (OpenVEX; all statements default
to under_investigation).
--emit-vdr Also write cyclonedx-vdr.json (CycloneDX Vulnerability
Disclosure Report: every known finding, including
untriaged ones, which carry no analysis).
--emit-techdoc Also write the CRA Annex VII technical-documentation
pack index and UNSIGNED DRAFT EU declaration
workspace.
--emit-incident-report
Also write the CRA Article 14 UNSIGNED DRAFT
incident/vulnerability notification pack (early
warning / notification / final report). SBOMFlow never
files, transmits, or submits any report.
--emit-ssvc Also write ssvc.json: a suggested CISA SSVC action
priority (Track / Track* / Attend / Act) per finding
for human review. Not a remediation mandate and not a
conformity claim.
--emit-sarif Also write findings.sarif (SARIF 2.1.0) for observed
gaps and vulnerability findings. SARIF level is
severity, not a release decision.
--emit-spdx3 Also write spdx3-sbom.json (SPDX 3.0.1 JSON-LD). SPDX
2.3 remains the default SBOM for broad
interoperability.
--emit-mlbom Also write cyclonedx-mlbom.json: a CycloneDX 1.6 ML-
BOM over the AI evidence graph. Links to the software
SBOM by BOM-Link; never copies its components. An
inventory, not a safety or conformity claim.
--emit-aibom Also write spdx3-aibom.json: an SPDX 3.0.1 AI +
Dataset profile document over the same AI evidence
graph. Add --emit-spdx3 to have it import that
document's product element instead of restating it.
--drift-html When release drift is produced (with --previous-
output), also write release-drift.html, a human-
readable release-diff report.
--emit-traceability Also write traceability.json: a cross-entity node/edge
index linking product, release, components,
vulnerabilities, requirements, evidence, gaps, issues,
and scanned source bytes. A derived view that adds no
claims.
--emit-issues-csv Also write issues.csv, a spreadsheet-friendly
projection of issues.json. This is a data export only,
not a release or legal decision.
--emit-pdf Also write evidence-summary.pdf, a deterministic text
summary for auditor handoff. HTML/JSON stay canonical;
the PDF adds no claims.
--emit-bundle Also write evidence-bundle.json/html for reviewer
handoff.
--share-profile {importer,distributor,customer}
Also write a redacted evidence-sharing pack for the
chosen profile (sharing-pack.json/html/zip): a
documented SBOM subset plus coverage summary,
declaration-draft status, and support period. Internal
reviewer notes are redacted; it adds no authority and
no conformity claim.
--emit-metrics Also write local metrics.json with aggregate counts,
gate state, phase durations, tool metadata, and
declared release metadata (no source content,
credentials, or contact details; inspect release
metadata before sharing).
Next: sbomflow review out · sbomflow explain out --gate · sbomflow bundle out
Reads the target directory, optional sbomflow.yaml and local inputs the
flags name.
Writes evidence-pack.json (and the default artifacts, into --output);
release-gate.json; release-record.json; scan-warnings.json
Exit 0 ok · 1 an enforced gate blocked the release · 2 usage, input, IO or
config error · 5 --strict matched a scan warning
Examples:
# Scan a source tree and write the evidence artifacts.
sbomflow analyze . --output out --product-name Gateway --product-version \
2.4.1
# Refuse to write into a directory that already holds a run.
sbomflow analyze . --output out --on-existing-output refuse
# Emit a VEX document alongside the pack, for downstream consumers.
sbomflow analyze . --output out --emit-vex
# Write the SBOMs with no requirement regime assessed.
sbomflow analyze . --output out --requirement-regime none
# Compare with the previous release's pack and write the drift report as
# HTML too.
sbomflow analyze . --output out --previous-output out-prev --drift-html
See also: `sbomflow audit`, `sbomflow review`, `sbomflow explain`,
`sbomflow compare-releases`, `sbomflow help auditing`,
`sbomflow help goal sbom`.
Network behavior: opt-in-network. The default path is offline; only the listed
flags/config enable egress. Gates: --use-osv, --use-nvd, --use-kev,
--use-epss, --resolve-west-imports, config: osv/nvd enabled with
scan.offline=false, config: exploitation.use_kev/use_epss=true with
scan.offline=false.
Machine output: artifact-suffices — writes the full evidence artifact set
(SBOM, findings, gate, and under the cra regime the gaps and CRA report…);
the files are the API.
usage: sbomflow review [-h] [--template CISA_JUSTIFICATION] [--reviews REVIEWS]
[--vulnerability-reviews VULNERABILITY_REVIEWS] [--accept KEY]
[--reject KEY] [--needs-more-evidence KEY] [--triage VULN_ID]
[--status STATUS] [--justification JUSTIFICATION]
[--evidence-ref EVIDENCE_REF] [--waive-gap GAP_ID]
[--waive-finding VULN_ID] [--renew-waiver-gap GAP_ID]
[--renew-waiver-finding VULN_ID] [--revoke-waiver-gap GAP_ID]
[--revoke-waiver-finding VULN_ID] [--dispute-match FINDING_KEY]
[--reason REASON] [--expires-at EXPIRES_AT] [--start KEY] [--as ROLE]
[--force] [--bulk FILE] [--reviewer REVIEWER] [--note NOTE]
[--reviewed-at REVIEWED_AT] [--idempotency-key KEY] [--assign ROLE]
[--as-of AS_OF] [--filter EXPR|@name] [--store DIR] [--json] [--digest]
[--since SINCE] [EVIDENCE_DIR]
Show what still needs a human decision, or record exactly one decision.
It records YOUR decision - it never decides.
review-queue.json is rewritten only when its content changed, so reading
the queue never invalidates a bundle sealed before it. A decision appends
to reviews.json / vulnerability_reviews.json / waivers.json plus a
hash-chained audit event, and then says to rebuild the bundle. A refused
decision (not_affected without a valid CISA justification, say) exits 2
and records nothing.
With no decision flags this is read-only apart from review-queue.json.
Shorter view: `sbomflow help review` — required inputs, common options and the
option groups by job; `sbomflow help review <group>` opens one group. Nothing
is hidden there: that layer is shorter, not smaller.
positional arguments:
EVIDENCE_DIR Directory produced by 'analyze'/'audit' (omit only
with --template).
options:
-h, --help show this help message and exit
--template CISA_JUSTIFICATION
Print a starting justification scaffold for the given
CISA category and exit (you edit it into a real
explanation; it is never submitted). One of:
component_not_present, vulnerable_code_not_present,
vulnerable_code_not_in_execute_path,
vulnerable_code_cannot_be_controlled_by_adversary,
inline_mitigations_already_exist.
--reviews REVIEWS Evidence reviews file to read/update (default:
<output>/reviews.json).
--vulnerability-reviews VULNERABILITY_REVIEWS
Vulnerability VEX-triage file to read/update (default:
<output>/vulnerability_reviews.json).
--reviewer REVIEWER Reviewer identity recorded with the decision.
--note NOTE Reviewer note recorded with the decision (required,
with --reviewer, for a preserved-artifact key: the
conclusion and its limits).
--reviewed-at REVIEWED_AT
ISO timestamp for the decision (default: now/--as-of).
--idempotency-key KEY
Optional stable key so a retried vulnerability triage
converges to ONE operation instead of recording a
second one. Same key + same decision returns the
existing operation; same key + a different decision is
refused. 1-128 chars [A-Za-z0-9._-]. SCOPE:
convergence is per OUTPUT DIRECTORY — the same key
used against a different output dir is a separate
operation, not a retry.
--assign ROLE Annotate the queue with an assigned reviewer role.
--as-of AS_OF Pinned timestamp for the queue / audit event.
--filter EXPR|@name Narrow the queue view with comma-joined FIELD OP VALUE
terms (severity/epss/kev/status/ssvc/kind/assigned/com
ponent), e.g. 'severity>=high,kev=true'; or @name for
a filter saved under review.filters in sbomflow.yaml.
A filter narrows what you look at — it never changes a
decision, a status, or the gate.
--store DIR Local evidence store to read prior reviewer decisions
from (offline). Surfaces this product's earlier per-
finding decisions as review context; it never
suppresses a finding or changes VEX status.
--json Emit the review queue as JSON.
--digest Print a session digest of decisions recorded in this
audit log (accepted/rejected/needs-more-evidence,
findings triaged, waivers, approvals), grouped with
event-hash references, and write session-digest.md.
Read-only; records nothing.
--since SINCE With --digest: only include decisions recorded at or
after this ISO-8601 timestamp.
record one decision (omit all of these to just show the queue):
--accept KEY Accept the evidence item with this key, or the
preserved artifact whose review key (preserved-
artifact:sha256:<hex>, listed in preserved-
artifacts.json) this is; a preserved-artifact decision
requires --reviewer and --note.
--reject KEY Reject the evidence item or preserved artifact KEY.
--needs-more-evidence KEY
Mark the evidence item or preserved artifact with this
key as needing more evidence.
--triage VULN_ID Record a VEX triage decision for this vulnerability id
(with --status).
--status STATUS VEX status for --triage. One of: affected, fixed,
not_affected, under_investigation.
--justification JUSTIFICATION
CISA justification (required when --status
not_affected).
--evidence-ref EVIDENCE_REF
Optional evidence reference for a VEX triage.
--waive-gap GAP_ID Record a time-boxed waiver for this gap id (requires
--reason and --expires-at).
--waive-finding VULN_ID
Record a time-boxed waiver for this finding id
(requires --reason and --expires-at).
--renew-waiver-gap GAP_ID
Renew the existing waiver for this gap id with a fresh
--reason and a later --expires-at (the reason must
differ from the one it renews).
--renew-waiver-finding VULN_ID
Renew the existing waiver for this finding id with a
fresh --reason and a later --expires-at (the reason
must differ from the one it renews).
--revoke-waiver-gap GAP_ID
Revoke the existing waiver for this gap id (requires
--reason and --reviewer). The record stays in
waivers.json marked revoked — history preserved — and
immediately stops applying; a revoked waiver cannot be
renewed (record a fresh waiver instead).
--revoke-waiver-finding VULN_ID
Revoke the existing waiver for this finding id
(requires --reason and --reviewer). The record stays
in waivers.json marked revoked — history preserved —
and immediately stops applying; a revoked waiver
cannot be renewed (record a fresh waiver instead).
--dispute-match FINDING_KEY
Dispute the advisory match itself for this finding_key
(requires --reason and --reviewer: a dispute
suppresses a blocking finding, so it must name the
human who asserted the match is wrong). Distinct from
VEX: excludes the finding from vex.json/cyclonedx-
vex.json/csaf-vex.json entirely, labels it (never
excludes it) in cyclonedx-vdr.json, and suppresses it
from the gate under its own disputed_matches list;
reappears automatically if the match evidence
(aliases/range/purl) changes on a later run.
--reason REASON Mandatory reason recorded with a waiver, a waiver
revocation, or a match dispute.
--expires-at EXPIRES_AT
Mandatory ISO expiry recorded with a waiver.
--start KEY Claim an evidence key, vulnerability id, or gap id:
moves it to 'in_review' so two reviewers don't
silently duplicate work (requires --as ROLE). A claim
carries no evidence authority — it never accepts
evidence or sets a status.
--as ROLE Reviewer role claiming the item with --start.
--force With --start: reclaim an item already claimed by
someone else (the prior claim stays in the audit log).
--bulk FILE Record many VEX triage decisions from a pre-reviewed
.csv or .json worksheet (columns/keys: finding_key,
status, justification, reviewer, note, evidence_ref —
finding_key is the vulnerability id, same as
--triage). Each row is validated and recorded
independently with its own audit event; invalid rows
are listed and skipped, valid rows still apply. There
is no 'accept all' — every row states its own status
and justification.
Next: re-run your gate with --reviews out/reviews.json, or sign off:
sbomflow approve out --role product-security --reviewer sec@example.com
Reads an existing analyze or audit output directory.
Writes a decision appends to reviews.json, vulnerability_reviews.json or
waivers.json; review-queue.json, only when its content changed;
stdout (the review queue; --json prints JSON)
Exit 0 ok · 2 usage error or a refused decision
Examples:
# Print the human review queue for a finished run.
sbomflow review out
# Accept one evidence item, naming who decided and why.
sbomflow review out --accept vulnerability_disclosure_policy --reviewer \
you@example.com --note 'Mailbox monitored.'
# Record a VEX triage: not affected, with its CISA justification.
sbomflow review out --triage CVE-SAMPLE-OPENSSL-001 --status not_affected \
--justification vulnerable_code_not_in_execute_path --reviewer \
you@example.com --note 'Not reachable.'
# Accept a preserved trace by its review key, in a run whose sbomflow.yaml
# declared it under preserved_artifacts: (here
# `sbomflow analyze sensor-node --output sensor-evidence`); a
# preserved-artifact decision needs --reviewer and --note.
sbomflow review sensor-evidence --accept \
preserved-artifact:sha256:c640b55149337567f8395db0fd66102ecb98006a9762a\
67cbf62114a6932d7a2 \
--reviewer lab-lead --note \
'Trace covers boot to idle; no fault path exercised.'
# Waive one evidence gap until a stated date, with the reason.
sbomflow review out --waive-gap GAP-CRA-A1-P1-2m-secure_data_erasure \
--reason 'Erasure test scheduled.' --expires-at 2999-12-31T23:59:59Z \
--reviewer you@example.com
# Refuse not_affected without a CISA justification; nothing is recorded.
sbomflow review out --triage CVE-SAMPLE-OPENSSL-001 --status not_affected \
--reviewer you@example.com
# See what still needs a human decision in the pack
# `sbomflow audit . --output evidence` wrote.
sbomflow review ./evidence
See also: `sbomflow approve`, `sbomflow review-view`, `sbomflow explain`,
`sbomflow help reviewing`, `sbomflow help goal sign-off`.
Network behavior: offline. This command has no network-capable path.
Machine output: has-json — shows the review queue, or records one decision and
then shows the refreshed queue; one versioned JSON document on stdout, and a
recording action's receipt goes to stderr.
usage: sbomflow approve [-h] [--approvals APPROVALS] [--require-role ROLE]
[--policy POLICY] [--role ROLE] [--revoke] [--override]
[--reviewer REVIEWER] [--author AUTHOR] [--delegate-of REVIEWER]
[--expires-at EXPIRES_AT] [--reason REASON] [--note NOTE]
[--idempotency-key KEY] [--as-of AS_OF] [--json] [--export-audit DIR]
[--format {csv,json}] [--share-profile {importer,distributor,customer}]
EVIDENCE_DIR
Show multi-role release-approval status, or record one sign-off action.
Status display alone writes nothing; an action writes approvals.json plus
a hash-chained audit event. Separation of duties is enforced: an approver
may not be the declared release author, and one reviewer may not cover
two required roles; a refused action exits 2.
SBOMFlow records the sign-off; it never grants an approval itself. An
override lets the gate proceed but never hides the missing roles.
Shorter view: `sbomflow help approve` — required inputs, common options and
the option groups by job; `sbomflow help approve <group>` opens one group.
Nothing is hidden there: that layer is shorter, not smaller.
positional arguments:
EVIDENCE_DIR Directory produced by 'analyze'/'audit'.
options:
-h, --help show this help message and exit
--approvals APPROVALS
Approval ledger to read/update (default:
<output>/approvals.json).
--require-role ROLE Required role(s) for the status display (repeatable).
Also the set the separation-of-duties rule reads: 'two
required roles' means two of these, so without
--require-role or --policy no role is required and an
approver covering a second role is neither refused nor
reported.
--policy POLICY Policy profile supplying required_approval_roles for
the status display.
--reviewer REVIEWER Reviewer identity recorded with the action. MANDATORY
when approving a role and when recording --override:
an unattributed approval satisfies no role, and an
unattributed override suppresses nothing. Optional
only for --revoke, which withdraws authority and so
fails closed.
--author AUTHOR Declared release author (separation of duties: an
approver may not be the author).
--delegate-of REVIEWER
Record this approval as a delegate standing in for
REVIEWER (e.g. a release manager on leave). Requires
--expires-at (delegation is always time-boxed);
delegating for someone who is themselves currently
delegating is refused (one hop only).
--expires-at EXPIRES_AT
ISO expiry. Optional for an approval; MANDATORY for
--override and with --delegate-of.
--reason REASON Reason for a revocation, or the mandatory override
reason.
--note NOTE Optional note recorded with an approval.
--idempotency-key KEY
Optional stable key so a retried approval or
revocation converges to ONE operation instead of
recording a second. Same key + same action returns the
existing operation; same key + a different action is
refused. 1-128 chars [A-Za-z0-9._-]. SCOPE:
convergence is per OUTPUT DIRECTORY — the same key
used against a different output dir is a separate
operation, not a retry.
--as-of AS_OF Pinned timestamp for the status / audit event.
--json Emit the approval status as JSON.
record one action (omit all of these to just show the approval status):
--role ROLE Role to approve, or to revoke with --revoke.
--revoke Revoke the active approval for --role.
--override Record an emergency override of missing approvals
(requires --reason).
auditor export (restates recorded sign-offs; writes nothing to the ledger):
--export-audit DIR Export the approvals ledger for an auditor to
DIR/approvals-audit-export.* instead of showing or
recording status (refuses on a tampered audit chain).
--format {csv,json} Format for --export-audit (default: csv).
--share-profile {importer,distributor,customer}
Redaction profile for --export-audit (redacts reviewer
identity and reason text).
Next: enforce with `sbomflow audit . --output evidence \
--require-role product-security --fail-on-missing-approvals`
Reads an existing analyze or audit output directory.
Writes approvals.json and an audit event, when an action is recorded;
approvals-audit-export.* with --export-audit; stdout (the approval
status; --json prints JSON)
Exit 0 ok · 2 usage error or a refused action
Examples:
# Show which required roles have signed off.
sbomflow approve out --require-role product-security
# Record one named approval for a role.
sbomflow approve out --role product-security --reviewer sec@example.com
# Export the approvals ledger for an auditor.
sbomflow approve out --export-audit audit-export
# Refuse an approver who is also the declared release author.
sbomflow approve out --role product-security --reviewer sec@example.com \
--author sec@example.com
See also: `sbomflow review`, `sbomflow audit`, `sbomflow gate simulate`,
`sbomflow help goal sign-off`.
Network behavior: offline. This command has no network-capable path.
Machine output: has-json — shows the approval status, or records one approval
action and then shows it; the status is one versioned JSON document on
stdout and a recording action's receipt goes to stderr.
usage: sbomflow explain [-h]
(--gap GAP_ID | --finding VULN_ID | --gate | --ai-entity ENTITY_ID | --preserved-artifact KEY | --explain-terms [TERM] | --warning [CODE])
[EVIDENCE_DIR]
Print a sourced, human-readable explanation of one gap, finding, the
gate decision, a scan-warning code or a preserved artifact - composed
purely from existing artifacts (no AI).
positional arguments:
EVIDENCE_DIR Directory produced by 'analyze' (not needed for
--explain-terms).
options:
-h, --help show this help message and exit
--gap GAP_ID Explain this evidence gap id.
--finding VULN_ID Explain this advisory finding id/alias.
--gate Explain release-gate.json.
--ai-entity ENTITY_ID
Explain one AI evidence entity end to end: what was
observed, what was declared, where each fact came
from, and what is being asked of a reviewer. A unique
id prefix is accepted.
--preserved-artifact KEY
Explain one preserved artifact in this run: its
declared record, the original, the identity the record
states, the run's checks, the review decision and the
files that name it. A full review key or a unique
digest prefix of at least 12 hex characters.
--explain-terms [TERM]
Plain-language definitions of the core vocabulary
(SBOM, VEX, CVSS, purl, gate, KEV, EPSS, SSVC, ...).
Omit TERM for all of them; needs no output directory.
--warning [CODE] Explain a scan-warning code and this run's occurrences
(omit CODE to list the codes seen in this run).
Next: sbomflow review ./evidence to record the human decision.
Reads an existing analyze or audit output directory; --explain-terms needs
none.
Writes stdout (the explanation; nothing is written)
Exit 0 ok · 2 unknown id or missing artifact
Examples:
# Explain why the release gate decided what it decided.
sbomflow explain out --gate
# Explain one scan-warning code, sourced from the catalog.
sbomflow explain out --warning unparseable_manifest
# Explain one advisory finding: where it matched and what a reviewer
# decided.
sbomflow explain out --finding CVE-SAMPLE-OPENSSL-001
# List the warning codes this run actually emitted.
sbomflow explain out --warning
# Define a term; no output directory is needed.
sbomflow explain --explain-terms kev
# Explain one preserved artifact in a run that declared it: its record,
# original, stated identity, the run's checks, the review decision and the
# files that name it.
sbomflow explain sensor-evidence --preserved-artifact c640b5514933
See also: `sbomflow review`, `sbomflow next-actions`, `sbomflow help`,
`sbomflow help warning`.
Network behavior: offline. This command has no network-capable path.
Machine output: human-only-by-design — renders a prose explanation composed
from artifacts that are already machine-readable on disk.
usage: sbomflow bundle [-h] [--zip ZIP] [--as-of AS_OF] [--with-prov]
EVIDENCE_DIR
Create or refresh the portable reviewer handoff (evidence-bundle.json,
evidence-bundle.html, optional deterministic ZIP) for an existing run.
A bundle copies and hashes existing artifacts; it adds no authority and
no new claims.
positional arguments:
EVIDENCE_DIR Directory produced by analyze/audit.
options:
-h, --help show this help message and exit
--zip ZIP Optional path for a deterministic evidence ZIP.
--as-of AS_OF Pinned ZIP timestamp.
--with-prov Also map the run's traceability.json to a W3C PROV-DM subset
(prov-mapping.json) and include it in the bundle (requires
the run to have been produced with --emit-traceability).
Next: sbomflow verify-bundle ./evidence · share the ZIP with your reviewer
Reads an existing analyze or audit output directory.
Writes artifact-manifest.json (with evidence-bundle.json and
evidence-bundle.html, into the directory); the deterministic ZIP with
--zip
Exit 0 ok · 2 usage or input error
Examples:
# Assemble a portable reviewer handoff from an existing run.
sbomflow bundle out
# Also write the deterministic evidence ZIP inside the run.
sbomflow bundle out --zip out/evidence-bundle.zip
# Write the ZIP beside the run, with a pinned timestamp.
sbomflow bundle out --zip evidence-bundle.zip --as-of 2026-07-01T00:00:00Z
See also: `sbomflow sign-bundle`, `sbomflow verify-bundle`,
`sbomflow auditor-pack`, `sbomflow help goal handoff`.
Network behavior: offline. This command has no network-capable path.
Machine output: artifact-suffices — writes `evidence-bundle.json` / `.zip`,
the portable reviewer handoff.
usage: sbomflow validate [-h] [--json] EVIDENCE_DIR
Check one analyze or audit output directory: every artifact it holds is parsed
and checked against its published schema, the recorded hashes are re-verified,
and the run's completion seal is compared with the bytes on disk. It writes
nothing. A malformed or changed artifact exits 4, and so does a pack whose
recorded producer (0.5.0 or later) always writes run-completion.json but has
none; a directory that cannot be used exits 2.
positional arguments:
EVIDENCE_DIR Directory produced by 'analyze'.
options:
-h, --help show this help message and exit
--json Machine-readable report on stdout (schema_version sbomflow-
validate-report-v1); same exit codes as the human output.
Reads an existing analyze or audit output directory.
Writes stdout (the report; --json prints JSON)
Exit 0 every present artifact is valid · 2 the directory is missing or
unusable · 4 an artifact is malformed or changed, or a pack whose
producer always writes run-completion.json has none
Examples:
# Check that an output directory is a complete, well-formed run.
sbomflow validate out
# Print the same report as one JSON document, with the same exit.
sbomflow validate out --json
# Refuse a pack whose evidence-pack.json fails its schema.
sbomflow validate broken-evidence
See also: `sbomflow audit`, `sbomflow verify-bundle`, `sbomflow store verify`,
`sbomflow help exit`.
Network behavior: offline. This command has no network-capable path.
Machine output: has-json — read/status surface; one versioned JSON document on
stdout.
usage: sbomflow compare-releases [-h] [--report-theme {light,dark}]
--previous PREVIOUS --current CURRENT --output OUTPUT
[--require-both-releases] [--html] [--release-notes FILE]
[--release-notes-format FORMAT] [--as-of AS_OF]
Compare two existing runs of the same product and report what changed:
components, findings, KEV/EPSS, reachability, gaps, reviews to recheck,
support period, artifact hashes, and gate policy.
Preserved artifacts (traces, dumps, test results declared under
preserved_artifacts:) are compared by digest and written to
preserved-artifact-changes.json, beside release-drift.json, never in it.
Drift is comparison context only - it never replaces human review or
closes tracker issues.
options:
-h, --help show this help message and exit
--report-theme {light,dark}
Palette for generated HTML surfaces (default: light).
Print output is always light.
--previous PREVIOUS Previous output directory.
--current CURRENT Current output directory.
--output OUTPUT Where release-drift.json is written (directory).
--require-both-releases
Automation contract: exit 2 when either release
directory is unavailable, instead of writing a drift
in which nothing was compared. release-drift.json is
still written first, so the reason survives the
refusal. Without this flag exit codes are unchanged.
--html Also write release-drift.html, a human-readable
release-diff report.
--release-notes FILE Also write template-locked engineering security
release notes (markdown): counts plus the list of
fixed advisory ids. No free prose, no severities, and
no still-open advisory ids.
--release-notes-format FORMAT
Which rendering(s) of the release note to write.
'markdown' (the default) is --release-notes FILE
alone. 'cyclonedx' writes only engineering-release-
notes.cdx.json - a standalone CycloneDX 1.7 document -
into --output. 'both' writes both, and then --release-
notes names the markdown destination. Both renderings
project one normalized view, so they carry the same
facts; the CycloneDX document adds no claim of its
own.
--as-of AS_OF Pinned comparison timestamp.
Next: sbomflow explain out/v2 --gate · review new findings in out/v2
Reads two analyze or audit output directories of the same product.
Writes release-drift.json into --output; with --html also
release-drift.html; preserved-artifact-changes.json into --output,
beside release-drift.json; the release notes with --release-notes
Exit 0 ok, including a comparison where one side was unavailable · 2 usage
or input error, or with --require-both-releases a missing side
Examples:
# Report what changed between two releases, with shareable notes.
sbomflow compare-releases --previous out-prev --current out --output drift \
--release-notes drift/RELEASE-NOTES.md
# Also write the human-readable drift report as HTML.
sbomflow compare-releases --previous out-prev --current out --output drift \
--html
# Refuse, after writing the drift, when a release directory is missing.
sbomflow compare-releases --previous missing-dir --current out --output \
drift --require-both-releases
See also: `sbomflow analyze`, `sbomflow store timeline`,
`sbomflow release-chain verify`, `sbomflow help goal history`.
Network behavior: offline. This command has no network-capable path.
Machine output: artifact-suffices — writes `release-drift.json`.
The full command surface, grouped by job, exactly as sbomflow help all prints it. sbomflow help prints the group index alone, sbomflow help <group> one group, and sbomflow help topics every help topic:
text
SBOMFlow commands, grouped: 95 top-level commands in 13 group(s).
Offline by default. Engineering evidence only; not a conformity claim.
Get started [start]
Check the setup, scaffold a config, run a first pack.
setup Guided interactive first-run onboarding (a real
terminal only; never in CI).
quickstart First run: detect the project, scaffold config,
run an offline audit, summarize.
init Scaffold sbomflow.yaml and optional
reviewer templates.
doctor Run offline environment/config preflight checks.
examples Print worked examples that are executed by the
test suite.
Run a release audit [auditing]
Produce a release-evidence pack from a build and read it.
audit Run analyze + full opt-in packs + bundle +
validation in one command.
analyze Scan a product directory and write its evidence
pack (audit adds the bundle).
batch-run Run analyze across every product declared in one
batch manifest.
validate Validate a generated evidence output directory.
explain Explain one gap, finding, gate decision, warning
or preserved artifact from existing artifacts.
next-actions Release-scoped ship-readiness line plus the top
few outstanding actions.
report Derived, read-only planning reports composed from
a finished run.
Review decisions, approvals & the release gate [reviewing]
Record named human decisions and approvals; apply a gate.
review Show the review queue, or record one human
sign-off decision with an audit event.
review-view Write reviewer.html: queue, findings, requirement
coverage, gate and approvals for an output dir.
review-merge Merge two reviewer decision files by key,
reporting conflicts (offline).
approve Show release-approval status, or record one
approval, revocation or override.
decisions Inspect and recover crash-interrupted human
decision transactions (offline).
gate Release-gate tools that record nothing
(read-only, offline).
policy Inspect or diff release-gate policy profiles
(read-only, offline).
annotate Render an output directory's gate verdict as
native CI annotations (offline).
Vulnerabilities, VEX & exploitation context [vulnerabilities]
Local advisory data and scanner results, matched offline.
vulndb Manage local pinned vulnerability-data snapshots
(OSV dump / CVE List V5).
recheck Re-evaluate a shipped release against newer local
advisory data (offline).
ingest-trivy Ingest a Trivy JSON report as sourced observations
(offline; never native findings/VEX/gate).
ingest-grype Ingest a Grype JSON report as sourced observations
(offline; never native findings/VEX/gate).
ingest-sarif Ingest a SARIF 2.1.0 log
(CodeQL/Semgrep/clang-tidy/…) as sourced
observations (offline).
ingest-codex-security Import a LOCAL completed Codex Security scan as
external AI-assisted observations.
ingest-build-cve-report Read a Yocto or Buildroot build's own CVE report
as build-tool claims (offline; never a
VEX status).
validate-ssvc-model Validate the packaged or supplied CISA SSVC
coordinator decision model.
ingest-cyclonedx-vdr Import a tool's CycloneDX VDR/VEX export as the
tool's claims (offline; never a VEX status).
Build, firmware & update inputs [build-inputs]
Builds, firmware, container images and update packages.
cmake-evidence Import a CMake File API reply into deterministic
build evidence (offline).
linker-map-evidence Parse a GNU ld / LLVM lld map into a deterministic
object/section graph (offline).
zephyr-evidence Import a Zephyr `west spdx` set into deterministic
build evidence (offline).
esp-idf-evidence Import ESP-IDF build outputs into deterministic
evidence (offline; no secrets copied).
elf-evidence Read ELF binaries' declared structure — SONAME,
DT_NEEDED, build-id (offline; never executed).
oci-evidence Discover manifests/platforms/referrers in a local
OCI image layout (offline; layers never executed).
syft-scan Optional: discover components via Syft and ingest
its CycloneDX output (never required).
firmware-extract Optional binwalk/unblob run: extracted files are
never executed, and are deleted with
the directory.
mcuboot-evidence Parse an MCUboot image into deterministic firmware
evidence (offline; never executed).
update-manifest-evidence Parse local TUF metadata or an IETF SUIT CBOR
envelope into bounded observations.
rauc-evidence Parse an exact RAUC manifest.raucm artifact
(offline; no CMS verification).
swupdate-evidence Parse an SWUpdate .swu newc/crc cpio or
sw-description artifact.
mender-evidence Inspect a Mender Artifact tar in memory without
extracting or executing it.
uptane-evidence Parse separate Uptane Director/Image repository
metadata observations.
build-applicability-evidence
Sources a build compiled (offline; context).
Integrity, provenance & reproducibility [integrity]
Check signatures, provenance and reproducible bytes.
mcuboot-verify Verify an MCUboot image's integrity + (opt-in)
signature against an operator key.
cosign-verify Optional: verify a blob against a local key +
offline Sigstore bundle via cosign
(never required).
provenance-check Check an in-toto/SLSA provenance statement against
expectations (offline; no SLSA level claimed).
verify-package-artifacts Verify lockfile-recorded digests against local
package cache directories.
reproducible-compare Compare two independent build-output trees by
artifact digest (offline).
diffoscope-compare Optional: explain differences between two
artifacts via diffoscope (never required).
prov-map Map a traceability.json to a documented W3C
PROV-DM subset (model guidance; offline).
Runtime & test evidence custody [runtime-evidence]
Keep traces, dumps and test results by their identity.
custody Keep, verify and review runtime and test artifacts
in a standalone custody set.
ingest-preserved-artifact Preserve a LOCAL analysis artifact by identity and
associate it with a release.
twister-evidence Import Zephyr Twister results (twister.json) into
deterministic test evidence (offline).
Compare releases & keep history [history]
Compare releases, keep an index, render dashboards.
compare-releases Compare two SBOMFlow output directories and
write release-drift.json.
store Local, file-based evidence store: accumulate
releases and query across them.
index Build/validate/query the derived SQLite evidence
index (JSON stays canonical).
index-releases Build release-index.json, the file `dashboard`
reads, from SBOMFlow output directories.
dashboard Render a static release dashboard from
release-index.json or output directories.
portfolio Aggregate the releases a portfolio config lists
into one index and dashboard.
release-chain Verify a hash-linked chain of release records
across output directories.
backfill Register past releases in the store as DECLARED
records, never as observed runs.
migrate-in Import another tool's estate as origin-labelled
CLAIMS (offline; never decisions).
sbom-set Work with SBOM documents you were
handed (offline).
Share & hand off [sharing]
Hand a finished pack to a reviewer, auditor or customer.
bundle Create or refresh reviewer evidence-bundle
artifacts for an output dir.
sign-bundle Sign evidence-bundle.json with a local PEM private
key (optional sbomflow[sign] extra).
verify-bundle Verify an evidence bundle's integrity (stdlib
tamper check) and, with --key, its signature.
auditor-pack Build auditor-pack.zip, a read-only package an
auditor opens in a browser.
passport Issue or verify a product-security assurance
passport (offline).
supplier-package Emit the package a customer's supplier intake
reads (offline).
export-cle Write the declared support history as a
lifecycle-event document (offline).
export-reqif Write one release's requirements, gaps, findings
and evidence as ReqIF (offline).
Trackers & notifications (dry run by default) [trackers]
Plan tracker and notification updates; --apply sends them.
sync-issues Sync evidence-gap issues to GitHub (dry run by
default; --apply to push).
sync-jira Export (or, with --apply, sync) a Jira issue plan
from issues.json.
sync-servicenow Export (or, with --apply, sync) a ServiceNow Table
API plan from issues.json.
sync-dependencytrack Plan or upload cyclonedx-sbom.json to
OWASP Dependency-Track.
notify Plan (and optionally deliver) review-queue/gate
notifications for an output dir.
Requirement regimes (optional; CRA available today) [regimes]
Runs assess CRA unless none is chosen; views are opt-in.
regime-view Read an existing verified pack through a versioned
regime profile (read-only).
regime-profile Author, validate, inspect and carry a LOCAL,
customer-authored regime profile.
emit-user-info Emit an UNSIGNED CRA Annex II user-information
draft from an output directory (offline).
standards-view Group an output's CRA coverage by EN 18031 section
(PROVISIONAL, offline).
validate-graph Validate the packaged or supplied CRA
requirement graph.
validate-techdoc-model Validate the packaged or supplied CRA Annex VII
technical-documentation model.
validate-article14-model Validate the packaged or supplied CRA Article 14
reporting model.
validate-annexii-model Validate the packaged or supplied CRA Annex II
information-to-users model.
Post-market cases (experimental) [post-market]
Track a case and draft its documents; nothing is filed.
case Post-market PSIRT case workflow (experimental):
track a case and draft its documents.
Configure, maintain & look things up [maintenance]
Config, schema migration of old output directories, help.
config Inspect the effective product
configuration (offline).
validate-config Validate a sbomflow.yaml/.json config file.
schema Show the field structure of SBOMFlow's own output
artifacts (offline).
upgrade Inspect/plan/migrate-copy/validate old output dirs
to the current schemas (offline; never in place).
license Read-only, offline entitlement verification; never
enforces licensing.
support-bundle Package sanitized diagnostics for a bug report
(offline, redaction-audited).
commands List every command path with its group, summary
and network class.
help Show the command groups, one group, command, topic
or keyword, or explain a code (offline).
component-support Save component lifecycle snapshots for the offline
run (fetch is opt-in network).
`sbomflow help <command>` explains one command; `sbomflow commands`
also lists every nested subcommand. Docs: https://sbomflow.com/docs
Every argument of every command path, one table per path in path order. Each column is read from the parser's own argument definition — the value it takes, its default (none when it has none), the values it allows, whether it is required, and its help exactly as --help prints it — so a table here cannot disagree with the command. The group pages (cli-<group>.md) carry the same tables beside each command's examples, exit codes and outputs.
Palette for generated HTML surfaces (default: light). Print output is always light.
target
target
none
any
yes
Product source/build directory to scan.
--output
OUTPUT
none
any
yes
Where the evidence outputs are written (directory).
--on-existing-output
{overlay,clean,refuse}
overlay
overlay, clean, refuse
no
What to do when --output already holds a previous run: overlay (default, write over it), clean (first remove SBOMFlow's own artifacts, never your files), or refuse (write nothing, exit 2).
--config
CONFIG
none
any
no
Path to a sbomflow.yaml/.json config file.
--store
DIR
none
any
no
Local evidence store holding prior releases of this product. When given, writes cross-release context (offline, read-only): evidence-aging.json (releases since a human last accepted each requirement), finding-regressions.json (resolved findings that reappeared), and carry-forward.json (prior human decisions on findings seen again here).
Declared product class to record. The engine does not classify the product. One of: default, important-class-i, important-class-ii, critical.
--requirement-regime
{cra,none}
none
cra, none
no
Which requirement regime this run is executed under: cra (default) derives the CRA Annex I requirement graph, gaps and coverage; none declares that no requirement regime applies, so no requirement is assessed and the run records that declaration. Under none the empty evidence gaps mean NOT ASSESSED, never 'no gaps'. Overrides requirement_regime in sbomflow.yaml.
--use-osv
(flag)
false
—
no
Query the real OSV API (osv.dev) over the network. Off by default.
--use-sample-feed
(flag)
false
—
no
Use the bundled SYNTHETIC sample advisory feed (CVE-SAMPLE-*). Illustrative demo/example data only, never intelligence about your product: artifacts mark it synthetic and it never counts as usable intelligence. Without a real source (--use-osv/--osv-snapshot) and without this flag, no advisory matching is performed at all.
--osv-snapshot
OSV_SNAPSHOT
none
any
no
Local OSV-format advisory snapshot (JSON list, {'vulns': [...]}, JSONL, or an OSV per-ecosystem all.zip) matched offline with the range engine instead of the non-real sample feed. Config: osv.snapshot. Never a live lookup.
--vulndb-dir
DIR
none
any
no
Local vulndb store whose active CSAF advisory mirror (vulndb update --source-type csaf-directory) is matched in this run. Offline: that store's index and its active csaf-directory snapshot are read, nothing is fetched, and the store becomes the run's recorded source set. No default is assumed: without it no store is guessed from the working directory or configuration. Refused if it is not a directory, or if another option names a different store.
--offline
(flag)
false
—
no
Force offline mode (never query OSV or resolve west imports), overriding config.
--resolve-west-imports
(flag)
false
—
no
Resolve Zephyr west 'import:' directives over the network (like --use-osv): fetch each imported manifest and add its modules as components. Off by default; dropped under --offline.
--west-import-dir
DIR
none
any
no
Resolve Zephyr west 'import:' directives from a local mirror instead of the network: DIR holds one checkout per project (DIR/<project>/west.yml). Stays OFFLINE and never falls back to the network. Mutually exclusive with --resolve-west-imports.
--west-name-allowlist
WEST_NAME_ALLOWLIST
none
any
no
Comma-separated project names to include from resolved west imports.
--west-name-blocklist
WEST_NAME_BLOCKLIST
none
any
no
Comma-separated project names to exclude from resolved west imports.
--osv-timeout
OSV_TIMEOUT
none
any
no
OSV request timeout in seconds.
--osv-base-url
OSV_BASE_URL
none
any
no
Override the OSV API base URL.
--osv-cache-dir
OSV_CACHE_DIR
none
any
no
Directory to cache OSV records (keyed by id, invalidated by modified time).
--scan-cache-dir
SCAN_CACHE_DIR
none
any
no
Directory for an optional content-addressed scan cache that speeds repeat scans of unchanged files. The cache only speeds up scanning; output is byte-identical with or without it.
--scan-jobs
N
1
any
no
Hash files with N parallel workers for large trees (default 1). Output is byte-identical to a single-threaded scan; ignored when --scan-cache-dir is set.
--use-nvd
(flag)
false
—
no
Enrich CVE findings from the live NIST NVD API (network). Off by default.
--nvd-file
NVD_FILE
none
any
no
Local NVD CVE API 2.0 snapshot to enrich offline (no network): a .json file, a .json.gz file, or a .zip holding one .json document.
Apply a shipped, versioned policy preset by name (cra-critical, cra-default, cra-important, strict-ci). Overridden by --policy; CLI --fail-on-* flags are additive.
--use-kev
(flag)
false
—
no
Enrich findings against the live CISA KEV catalog (network). Off by default.
--kev-file
KEV_FILE
none
any
no
Local CISA KEV catalog JSON snapshot to enrich offline (no network).
--use-epss
(flag)
false
—
no
Enrich findings with live FIRST EPSS scores (network). Off by default.
--epss-file
EPSS_FILE
none
any
no
Local FIRST EPSS snapshot (.csv or .json) to enrich offline (no network).
--reviews
REVIEWS
none
any
no
Evidence reviewer-decisions file to apply; without it (or reviews: in sbomflow.yaml) no decision is applied.
--vulnerability-reviews
VULNERABILITY_REVIEWS
none
any
no
Path to a vulnerability VEX-triage decisions file (for --emit-vex).
--reachability-evidence
REACHABILITY_EVIDENCE
none
any
no
Path to manufacturer-supplied reachability evidence inputs.
--ai-manifest
AI_MANIFEST
none
any
no
Read a local declared AI manifest (models, datasets, prompts, services, agents) and record it beside what the scan observed, in ai-evidence.json. Offline: one local file, no lookup. A declaration is what somebody SAID; where it disagrees with an observation both are kept and the disagreement is surfaced for a human, never resolved.
--debian-tracker-snapshot
DEBIAN_TRACKER_SNAPSHOT
none
any
no
Read a pinned local Debian security-tracker JSON snapshot and annotate findings with the distro's patched-status (no network).
--alpine-secdb-snapshot
ALPINE_SECDB_SNAPSHOTS
none
any
no
Read a pinned local Alpine secdb branch file and annotate findings with the distro's patched-status (no network). Repeatable.
--tree-sitter-reachability
(flag)
false
—
no
Opt in to bounded Tree-sitter C/C++ call-context observations. Requires sbomflow[reachability]; regex scanning remains the baseline.
--ssvc-context
SSVC_CONTEXT
none
any
no
Path to manufacturer SSVC context (Automatable / Mission & Well-being defaults and optional per-finding overrides) for --emit-ssvc.
--incident-awareness-at
INCIDENT_AWARENESS_AT
none
any
no
Instant the manufacturer recorded becoming aware. Starts the CRA Article 14 24-hour and 72-hour windows shown in --emit-incident-report. Recorded by you; never inferred, and never a decision that anything is reportable.
--incident-measure-available-at
INSTANT
none
any
no
Instant a corrective or mitigating measure became available. Starts the Article 14(2)(c) 14-day final-report window (actively exploited vulnerability track) — which does NOT run from awareness.
--incident-notification-submitted-at
INSTANT
none
any
no
Instant the manufacturer recorded submitting the Article 14(4)(b) incident notification, elsewhere. Starts the Article 14(4)(c) one-month final-report window (severe-incident track). Recording it here is a note to yourself; SBOMFlow never submits anything.
--import-sbom
IMPORT_SBOMS
none
any
no
Import a local supplier CycloneDX/SPDX JSON SBOM as observed component evidence. Repeatable; offline and local-file-only.
--import-custom-manifest
IMPORT_CUSTOM_MANIFESTS
none
any
no
Import a local SBOMFlow custom manifest (sbomflow-custom-manifest v1): explicit component + dependency evidence a manufacturer declares directly. Repeatable; offline and local-file-only. See docs/CUSTOM_MANIFEST.md.
--supplier-vex
SUPPLIER_VEX
none
any
no
Import a local supplier OpenVEX/CSAF/CycloneDX JSON VEX document as context for matching findings. Repeatable; never suppresses gates by itself.
--test-results
TEST_RESULTS
none
any
no
Attach a local JUnit XML, TAP or Robot Framework output.xml test-result file as observed security-test evidence for human review. Repeatable; offline only.
--assessment-findings
PATH
none
any
no
A local sbomflow-assessment-findings-v1 file restating the findings an assessment report listed (penetration test, lab evaluation, audit, bug bounty). Writes assessment-findings-ledger.json: each finding stays open until a named reviewer records a decision under assessment:<source>:<id> in the reviews input. Observations only; never a gate input. Offline.
--as-of
AS_OF
none
any
no
ISO timestamp to use as 'now' (for reproducible/freshness-pinned runs).
--release-id
RELEASE_ID
none
any
no
Manufacturer/CI-declared release id.
--release-channel
RELEASE_CHANNEL
none
any
no
Release channel, e.g. stable/beta.
--release-variant
RELEASE_VARIANT
none
any
no
Hardware/software release variant.
--build-id
BUILD_ID
none
any
no
CI/build-system identifier for this release.
--source-repository
SOURCE_REPOSITORY
none
any
no
Source repository URL or local identifier.
--source-revision
SOURCE_REVISION
none
any
no
Source revision used for this release.
--build-started-at
BUILD_STARTED_AT
none
any
no
Build start timestamp from CI metadata.
--build-finished-at
BUILD_FINISHED_AT
none
any
no
Build completion timestamp from CI metadata.
--support-period-ends-at
SUPPORT_PERIOD_ENDS_AT
none
any
no
Manufacturer-declared support-period end.
--support-promise
KIND=DATE
none
any
no
What this release promises until DATE, one kind per use: KIND is security_updates, software_maintenance or hardware_availability. Repeatable; replaces release.support_promises for that kind. Each kind is read on its own (a hardware date never answers a security-update question).
--support-policy
SUPPORT_POLICY
none
any
no
Local support-policy artifact to hash into the release record.
--previous-output
PREVIOUS_OUTPUT
none
any
no
Previous SBOMFlow output directory used to emit release-drift.json.
--build-provenance
BUILD_PROVENANCE
none
any
no
Local in-toto/SLSA-shaped statement or DSSE envelope to record.
--build-provenance-public-key
PEM_FILE
none
any
no
Local PEM public key for optional DSSE build-provenance signature verification. Requires sbomflow[attest].
--gate-dry-run
(flag)
false
—
no
Rehearse the gate: evaluate and report fully, mark release-gate.json dry_run, and always exit 0 (never blocks). For CI adoption before enforcing.
--fail-on-gaps
(flag)
false
—
no
Exit non-zero if missing-evidence gaps meet the severity threshold.
--fail-on-unreviewed
(flag)
false
—
no
Exit non-zero if observed evidence has not been human-reviewed.
--fail-on-vulnerabilities
(flag)
false
—
no
Exit non-zero if advisory findings meet the severity threshold.
--fail-on-kev
(flag)
false
—
no
Exit non-zero if any finding is in the CISA KEV catalog (known exploited).
--fail-on-denied-license
(flag)
false
—
no
Exit non-zero if a component declares a license on your policy's license_policy.deny list (engineering context against your own list, never legal advice; only for single valid SPDX expressions).
--fail-on-reachable-vulnerabilities
(flag)
false
—
no
Exit non-zero for source-referenced advisory findings that meet the severity threshold or enabled KEV/EPSS policy context.
--fail-on-new-vulnerabilities
(flag)
false
—
no
Exit non-zero when release drift contains new advisory findings.
--fail-on-new-kev
(flag)
false
—
no
Exit non-zero when release drift contains newly known-exploited findings.
--fail-on-new-reachable-vulnerabilities
(flag)
false
—
no
Exit non-zero when release drift contains newly source-referenced findings.
--fail-on-new-critical-or-high
(flag)
false
—
no
Exit non-zero when release drift contains new or escalated critical/high findings.
--fail-on-evidence-regression
(flag)
false
—
no
Exit non-zero when release drift contains new gaps, status regressions, or re-review needs.
--fail-on-support-period-missing
(flag)
false
—
no
Exit non-zero when current release metadata lacks support_period_ends_at.
--fail-on-missing-approvals
(flag)
false
—
no
Exit non-zero when required release-approval roles are unmet (or a separation-of-duties violation exists) and no active override is recorded.
--require-role
ROLE
none
any
no
Required release-approval role (repeatable); additive over a policy profile.
--approvals
APPROVALS
none
any
no
Release-approval ledger (approvals.json) consulted by the gate.
--waivers
WAIVERS
none
any
no
Reviewer-owned waivers file (waivers.json) consulted by the gate. An unexpired waiver moves its exact gap/finding to 'waived' (still listed); it never accepts evidence, sets VEX, or claims conformity.
--epss-threshold
EPSS_THRESHOLD
none
any
no
Exit non-zero if any finding's FIRST EPSS score is >= this value (0..1).
--severity-threshold
{none,low,medium,high,critical}
none
none, low, medium, high, critical
no
Severity floor for --fail-on-gaps / --fail-on-vulnerabilities (default: low).
--emit-vex
(flag)
false
—
no
Also write vex.json (OpenVEX; all statements default to under_investigation).
--emit-vdr
(flag)
false
—
no
Also write cyclonedx-vdr.json (CycloneDX Vulnerability Disclosure Report: every known finding, including untriaged ones, which carry no analysis).
--emit-techdoc
(flag)
false
—
no
Also write the CRA Annex VII technical-documentation pack index and UNSIGNED DRAFT EU declaration workspace.
--emit-incident-report
(flag)
false
—
no
Also write the CRA Article 14 UNSIGNED DRAFT incident/vulnerability notification pack (early warning / notification / final report). SBOMFlow never files, transmits, or submits any report.
--emit-ssvc
(flag)
false
—
no
Also write ssvc.json: a suggested CISA SSVC action priority (Track / Track* / Attend / Act) per finding for human review. Not a remediation mandate and not a conformity claim.
--emit-sarif
(flag)
false
—
no
Also write findings.sarif (SARIF 2.1.0) for observed gaps and vulnerability findings. SARIF level is severity, not a release decision.
--emit-spdx3
(flag)
false
—
no
Also write spdx3-sbom.json (SPDX 3.0.1 JSON-LD). SPDX 2.3 remains the default SBOM for broad interoperability.
--emit-mlbom
(flag)
false
—
no
Also write cyclonedx-mlbom.json: a CycloneDX 1.6 ML-BOM over the AI evidence graph. Links to the software SBOM by BOM-Link; never copies its components. An inventory, not a safety or conformity claim.
--emit-aibom
(flag)
false
—
no
Also write spdx3-aibom.json: an SPDX 3.0.1 AI + Dataset profile document over the same AI evidence graph. Add --emit-spdx3 to have it import that document's product element instead of restating it.
--drift-html
(flag)
false
—
no
When release drift is produced (with --previous-output), also write release-drift.html, a human-readable release-diff report.
--emit-traceability
(flag)
false
—
no
Also write traceability.json: a cross-entity node/edge index linking product, release, components, vulnerabilities, requirements, evidence, gaps, issues, and scanned source bytes. A derived view that adds no claims.
--emit-issues-csv
(flag)
false
—
no
Also write issues.csv, a spreadsheet-friendly projection of issues.json. This is a data export only, not a release or legal decision.
--emit-pdf
(flag)
false
—
no
Also write evidence-summary.pdf, a deterministic text summary for auditor handoff. HTML/JSON stay canonical; the PDF adds no claims.
--emit-bundle
(flag)
false
—
no
Also write evidence-bundle.json/html for reviewer handoff.
--share-profile
{importer,distributor,customer}
none
importer, distributor, customer
no
Also write a redacted evidence-sharing pack for the chosen profile (sharing-pack.json/html/zip): a documented SBOM subset plus coverage summary, declaration-draft status, and support period. Internal reviewer notes are redacted; it adds no authority and no conformity claim.
--emit-metrics
(flag)
false
—
no
Also write local metrics.json with aggregate counts, gate state, phase durations, tool metadata, and declared release metadata (no source content, credentials, or contact details; inspect release metadata before sharing).
--break-stale-lock
(flag)
false
—
no
Remove a provably-stale .sbomflow.lock (crashed run) from the output directory before running. Never automatic; confirm no other run is active first.
--strict
[STRICT_WARNINGS]
none
any
no
Treat scan warnings as errors after artifacts are written. Use --strict for any warning except the disclosure-only scan_directory_excluded_by_marker, or --strict=code1,code2 to scope by warning code (naming that code counts it) (distinct exit code 5).
Approval ledger to read/update (default: <output>/approvals.json).
--require-role
ROLE
none
any
no
Required role(s) for the status display (repeatable). Also the set the separation-of-duties rule reads: 'two required roles' means two of these, so without --require-role or --policy no role is required and an approver covering a second role is neither refused nor reported.
--policy
POLICY
none
any
no
Policy profile supplying required_approval_roles for the status display.
--role
ROLE
none
any
no
Role to approve, or to revoke with --revoke.
--revoke
(flag)
false
—
no
Revoke the active approval for --role.
--override
(flag)
false
—
no
Record an emergency override of missing approvals (requires --reason).
--reviewer
REVIEWER
none
any
no
Reviewer identity recorded with the action. MANDATORY when approving a role and when recording --override: an unattributed approval satisfies no role, and an unattributed override suppresses nothing. Optional only for --revoke, which withdraws authority and so fails closed.
--author
AUTHOR
none
any
no
Declared release author (separation of duties: an approver may not be the author).
--delegate-of
REVIEWER
none
any
no
Record this approval as a delegate standing in for REVIEWER (e.g. a release manager on leave). Requires --expires-at (delegation is always time-boxed); delegating for someone who is themselves currently delegating is refused (one hop only).
--expires-at
EXPIRES_AT
none
any
no
ISO expiry. Optional for an approval; MANDATORY for --override and with --delegate-of.
--reason
REASON
none
any
no
Reason for a revocation, or the mandatory override reason.
--note
NOTE
none
any
no
Optional note recorded with an approval.
--idempotency-key
KEY
none
any
no
Optional stable key so a retried approval or revocation converges to ONE operation instead of recording a second. Same key + same action returns the existing operation; same key + a different action is refused. 1-128 chars [A-Za-z0-9._-]. SCOPE: convergence is per OUTPUT DIRECTORY — the same key used against a different output dir is a separate operation, not a retry.
--as-of
AS_OF
none
any
no
Pinned timestamp for the status / audit event.
--json
(flag)
false
—
no
Emit the approval status as JSON.
--export-audit
DIR
none
any
no
Export the approvals ledger for an auditor to DIR/approvals-audit-export.* instead of showing or recording status (refuses on a tampered audit chain).
--format
{csv,json}
csv
csv, json
no
Format for --export-audit (default: csv).
--share-profile
{importer,distributor,customer}
none
importer, distributor, customer
no
Redaction profile for --export-audit (redacts reviewer identity and reason text).
Palette for generated HTML surfaces (default: light). Print output is always light.
target
target
none
any
yes
Product source/build directory to scan.
--output
OUTPUT
none
any
yes
Where the evidence outputs are written (directory).
--on-existing-output
{overlay,clean,refuse}
overlay
overlay, clean, refuse
no
What to do when --output already holds a previous run: overlay (default, write over it), clean (first remove SBOMFlow's own artifacts, never your files), or refuse (write nothing, exit 2).
--config
CONFIG
none
any
no
Path to a sbomflow.yaml/.json config file.
--store
DIR
none
any
no
Local evidence store holding prior releases of this product. When given, writes cross-release context (offline, read-only): evidence-aging.json (releases since a human last accepted each requirement), finding-regressions.json (resolved findings that reappeared), and carry-forward.json (prior human decisions on findings seen again here).
Declared product class to record. The engine does not classify the product. One of: default, important-class-i, important-class-ii, critical.
--requirement-regime
{cra,none}
none
cra, none
no
Which requirement regime this run is executed under: cra (default) derives the CRA Annex I requirement graph, gaps and coverage; none declares that no requirement regime applies, so no requirement is assessed and the run records that declaration. Under none the empty evidence gaps mean NOT ASSESSED, never 'no gaps'. Overrides requirement_regime in sbomflow.yaml.
--as-of
AS_OF
none
any
no
ISO timestamp to use as 'now' (for reproducible/freshness-pinned runs).
--import-sbom
IMPORT_SBOMS
none
any
no
Import a local supplier CycloneDX/SPDX JSON SBOM as observed evidence. Repeatable.
--import-custom-manifest
IMPORT_CUSTOM_MANIFESTS
none
any
no
Import a local SBOMFlow custom manifest (explicit component + dependency evidence). Repeatable; offline.
--supplier-vex
SUPPLIER_VEX
none
any
no
Import a local supplier OpenVEX/CSAF/CycloneDX VEX document as context only. Repeatable.
--test-results
TEST_RESULTS
none
any
no
Attach a local JUnit XML, TAP or Robot Framework output.xml result file as observed test evidence. Repeatable.
--assessment-findings
PATH
none
any
no
A local sbomflow-assessment-findings-v1 file restating the findings an assessment report listed (penetration test, lab evaluation, audit, bug bounty). Writes assessment-findings-ledger.json: each finding stays open until a named reviewer records a decision under assessment:<source>:<id> in the reviews input. Observations only; never a gate input. Offline.
--ai-manifest
AI_MANIFEST
none
any
no
Read a local declared AI manifest (models, datasets, prompts, services, agents) and record it beside what the scan observed, in ai-evidence.json. Offline: one local file, no lookup. A declaration is what somebody SAID; where it disagrees with an observation both are kept and the disagreement is surfaced for a human, never resolved.
--debian-tracker-snapshot
DEBIAN_TRACKER_SNAPSHOT
none
any
no
Read a pinned local Debian security-tracker JSON snapshot and annotate findings with the distro's patched-status (no network).
--alpine-secdb-snapshot
ALPINE_SECDB_SNAPSHOTS
none
any
no
Read a pinned local Alpine secdb branch file and annotate findings with the distro's patched-status (no network). Repeatable.
--build-provenance
BUILD_PROVENANCE
none
any
no
Local in-toto/SLSA-shaped statement or DSSE envelope to record.
--build-provenance-public-key
PEM_FILE
none
any
no
Local PEM public key for optional DSSE signature verification (sbomflow[attest]).
--support-policy
SUPPORT_POLICY
none
any
no
Local support-policy artifact to hash into the release record.
--offline
(flag)
false
—
no
Force offline mode, overriding config.
--use-osv
(flag)
false
—
no
Query the real OSV API (osv.dev) over the network. Off by default.
--use-sample-feed
(flag)
false
—
no
Use the bundled SYNTHETIC sample advisory feed (CVE-SAMPLE-*). Illustrative demo/example data only, never intelligence about your product.
--osv-snapshot
OSV_SNAPSHOT
none
any
no
Local OSV-format advisory snapshot (JSON list, {'vulns': [...]}, JSONL, or an OSV per-ecosystem all.zip) matched offline with the range engine instead of the non-real sample feed. Config: osv.snapshot. Never a live lookup.
--vulndb-dir
DIR
none
any
no
Local vulndb store whose active CSAF advisory mirror (vulndb update --source-type csaf-directory) is matched in this run. Offline: that store's index and its active csaf-directory snapshot are read, nothing is fetched, and the store becomes the run's recorded source set. No default is assumed: without it no store is guessed from the working directory or configuration. Refused if it is not a directory, or if another option names a different store.
--osv-timeout
OSV_TIMEOUT
none
any
no
OSV request timeout in seconds.
--osv-base-url
OSV_BASE_URL
none
any
no
Override the OSV API base URL.
--osv-cache-dir
OSV_CACHE_DIR
none
any
no
Directory to cache OSV records (keyed by id, invalidated by modified time).
--use-nvd
(flag)
false
—
no
Enrich CVE findings from the live NIST NVD API (network). Off by default.
--nvd-file
NVD_FILE
none
any
no
Local NVD CVE API 2.0 snapshot to enrich offline (no network): a .json file, a .json.gz file, or a .zip holding one .json document.
--nvd-timeout
NVD_TIMEOUT
none
any
no
NVD request timeout in seconds.
--nvd-base-url
NVD_BASE_URL
none
any
no
Override the NVD CVE API base URL.
--use-kev
(flag)
false
—
no
Enrich findings against the live CISA KEV catalog (network). Off by default.
--kev-file
KEV_FILE
none
any
no
Local CISA KEV catalog JSON snapshot to enrich offline (no network).
--use-epss
(flag)
false
—
no
Enrich findings with live FIRST EPSS scores (network). Off by default.
--epss-file
EPSS_FILE
none
any
no
Local FIRST EPSS snapshot (.csv or .json) to enrich offline (no network).
--resolve-west-imports
(flag)
false
—
no
Resolve Zephyr west 'import:' manifests over the network. Off by default.
--west-name-allowlist
WEST_NAME_ALLOWLIST
none
any
no
Comma-separated project names to include from resolved west imports.
--west-name-blocklist
WEST_NAME_BLOCKLIST
none
any
no
Comma-separated project names to exclude from resolved west imports.
--release-id
RELEASE_ID
none
any
no
Manufacturer/CI-declared release id.
--release-channel
RELEASE_CHANNEL
none
any
no
Release channel, e.g. stable/beta.
--release-variant
RELEASE_VARIANT
none
any
no
Hardware/software release variant.
--build-id
BUILD_ID
none
any
no
CI/build-system identifier for this release.
--source-repository
SOURCE_REPOSITORY
none
any
no
Source repository URL or local identifier.
--source-revision
SOURCE_REVISION
none
any
no
Source revision used for this release.
--build-started-at
BUILD_STARTED_AT
none
any
no
Build start timestamp from CI metadata.
--build-finished-at
BUILD_FINISHED_AT
none
any
no
Build completion timestamp from CI metadata.
--support-period-ends-at
SUPPORT_PERIOD_ENDS_AT
none
any
no
Manufacturer-declared support-period end.
--support-promise
KIND=DATE
none
any
no
What this release promises until DATE, one kind per use: KIND is security_updates, software_maintenance or hardware_availability. Repeatable; replaces release.support_promises for that kind. Each kind is read on its own (a hardware date never answers a security-update question).
Apply a shipped, versioned policy preset by name. Overridden by --policy.
--gate-dry-run
(flag)
false
—
no
Rehearse the gate: evaluate and report fully, mark release-gate.json dry_run, and always exit 0 (never blocks). For CI adoption before enforcing.
--fail-on-gaps
(flag)
false
—
no
Exit non-zero if missing-evidence gaps meet the severity threshold.
--fail-on-unreviewed
(flag)
false
—
no
Exit non-zero if observed evidence has not been human-reviewed.
--fail-on-vulnerabilities
(flag)
false
—
no
Exit non-zero if advisory findings meet the severity threshold.
--fail-on-kev
(flag)
false
—
no
Exit non-zero if any finding is in the CISA KEV catalog (known exploited).
--fail-on-denied-license
(flag)
false
—
no
Exit non-zero if a component declares a license on your policy's license_policy.deny list (engineering context against your own list, never legal advice; only for single valid SPDX expressions).
--fail-on-reachable-vulnerabilities
(flag)
false
—
no
Exit non-zero for source-referenced findings meeting the threshold/policy context.
--fail-on-new-vulnerabilities
(flag)
false
—
no
Exit non-zero when release drift contains new advisory findings.
--fail-on-new-kev
(flag)
false
—
no
Exit non-zero when release drift contains newly known-exploited findings.
--fail-on-new-reachable-vulnerabilities
(flag)
false
—
no
Exit non-zero when release drift contains newly source-referenced findings.
--fail-on-new-critical-or-high
(flag)
false
—
no
Exit non-zero when release drift contains new or escalated critical/high findings.
--fail-on-evidence-regression
(flag)
false
—
no
Exit non-zero when release drift contains new gaps, regressions, or re-review needs.
--fail-on-support-period-missing
(flag)
false
—
no
Exit non-zero when current release metadata lacks support_period_ends_at.
--fail-on-missing-approvals
(flag)
false
—
no
Exit non-zero when required approval roles are unmet and no override is recorded.
--epss-threshold
EPSS_THRESHOLD
none
any
no
Exit non-zero if any finding's FIRST EPSS score is >= this value (0..1).
--severity-threshold
{none,low,medium,high,critical}
none
none, low, medium, high, critical
no
Severity floor for --fail-on-gaps / --fail-on-vulnerabilities (default: low).
--emit-sarif
(flag)
false
—
no
Also write findings.sarif (SARIF 2.1.0) for observed gaps and findings.
--emit-spdx3
(flag)
false
—
no
Also write spdx3-sbom.json (SPDX 3.0.1 JSON-LD).
--emit-mlbom
(flag)
false
—
no
Also write cyclonedx-mlbom.json (CycloneDX 1.6 ML-BOM; BOM-Linked to the SBOM).
--emit-aibom
(flag)
false
—
no
Also write spdx3-aibom.json (SPDX 3.0.1 AI + Dataset profiles).
--emit-traceability
(flag)
false
—
no
Also write traceability.json (cross-entity node/edge index; a derived view).
--share-profile
{importer,distributor,customer}
none
importer, distributor, customer
no
Also write a redacted evidence-sharing pack for the chosen profile (sharing-pack.json/html/zip). Adds no authority and no conformity claim.
--emit-metrics
(flag)
false
—
no
Also write local metrics.json (aggregate counts, gate state, phase durations, tool metadata, and declared release metadata).
--emit-issues-csv
(flag)
false
—
no
Also write issues.csv, a spreadsheet-friendly projection of issues.json.
--emit-pdf
(flag)
false
—
no
Also write evidence-summary.pdf and include it in the bundle.
--zip
(flag)
false
—
no
Write evidence-bundle.zip.
--scan-cache-dir
SCAN_CACHE_DIR
none
any
no
Optional content-addressed scan cache for faster repeat scans of unchanged files.
--scan-jobs
N
1
any
no
Hash files with N parallel workers (default 1); ignored with --scan-cache-dir.
--strict
(flag)
false
—
no
Enforce the manufacturer's strict policy set. This is not a CRA conformity determination.
--break-stale-lock
(flag)
false
—
no
Remove a provably-stale .sbomflow.lock (crashed run) from the output directory before running. Never automatic; confirm no other run is active first.
Redaction profile for the included shared data subset AND for the reviewer console: reviewer identity and free-form reason text are withheld, the same fields 'approve --export-audit --share-profile' withholds (default: importer).
Also map the run's traceability.json to a W3C PROV-DM subset (prov-mapping.json) and include it in the bundle (requires the run to have been produced with --emit-traceability).
Evidence store holding the release the advisory describes.
--release
RELEASE
none
any
yes
Release id the exported DRAFT is about.
--advisories
ADVISORIES
none
any
yes
Local OSV-format advisory snapshot to draw the advisory text from (offline).
--as-of
AS_OF
none
any
no
Timestamp to record (default: now, UTC).
--profile
PROFILE
csaf_vex
csaf_vex, csaf_security_advisory
no
CSAF 2.0 profile of the document: csaf_vex (default; today's draft, byte-identical) or csaf_security_advisory.
--document-status
{draft,interim,final}
draft
draft, interim, final
no
CSAF tracking status. draft (default) is written as case-advisory.DRAFT.json and records nothing; interim or final is written as case-advisory.<status>.json and appends an advisory_status_recorded journal event naming the reviewer, the note and the document's sha256.
--reviewer
REVIEWER
none
any
no
Named human recording an interim or final status (required with them; refused with draft).
--note
NOTE
none
any
no
The reviewer's own note for an interim or final status (required with them; refused with draft).
--tlp
{WHITE,GREEN,AMBER,RED}
none
WHITE, GREEN, AMBER, RED
no
TLP label a person chose for the document (CSAF 2.0 section 3.2.1.5.2); required for interim and final and never defaulted. Only a TLP:WHITE final document can enter case advisory-tree.
Custody set, or a release run's evidence directory (its preserved-artifacts.json), to resolve the case's preserved-artifact evidence references against: present (review status; the original's state), absent, or set_unusable. Read-only; no original is opened or hashed.
Palette for generated HTML surfaces (default: light). Print output is always light.
--previous
PREVIOUS
none
any
yes
Previous output directory.
--current
CURRENT
none
any
yes
Current output directory.
--output
OUTPUT
none
any
yes
Where release-drift.json is written (directory).
--require-both-releases
(flag)
false
—
no
Automation contract: exit 2 when either release directory is unavailable, instead of writing a drift in which nothing was compared. release-drift.json is still written first, so the reason survives the refusal. Without this flag exit codes are unchanged.
--html
(flag)
false
—
no
Also write release-drift.html, a human-readable release-diff report.
--release-notes
FILE
none
any
no
Also write template-locked engineering security release notes (markdown): counts plus the list of fixed advisory ids. No free prose, no severities, and no still-open advisory ids.
--release-notes-format
FORMAT
markdown
markdown, cyclonedx, both
no
Which rendering(s) of the release note to write. 'markdown' (the default) is --release-notes FILE alone. 'cyclonedx' writes only engineering-release-notes.cdx.json - a standalone CycloneDX 1.7 document - into --output. 'both' writes both, and then --release-notes names the markdown destination. Both renderings project one normalized view, so they carry the same facts; the CycloneDX document adds no claim of its own.
An existing sbomflow-preserved-artifact-v1 record to admit (record form).
--original
ORIGINAL
none
any
no
Record form: the artifact the record describes, re-hashed at admission.
--intake-manifest
FILE
none
any
no
Intake form: an sbomflow-custody-intake-v1 manifest naming each file to add. All of its entries are admitted, or none are.
--release-id
RELEASE_ID
none
any
no
Artifact form: the release this artifact belongs to.
--scenario
SCENARIO
none
any
no
Artifact form: the test scenario it was captured in.
--tool-name
TOOL_NAME
none
any
no
Artifact form: the tool that produced it.
--tool-version
TOOL_VERSION
none
any
no
Artifact form: that tool's version.
--notes
NOTES
none
any
no
Artifact form: capture notes.
--operator
OPERATOR
none
any
no
Artifact form: contact-free identifier of who preserved it.
--artifact-kind
KIND
none
any
no
Artifact form: what the evidence IS, as you state it — one of runtime_trace, core_dump, crash_report, device_log, bench_log, network_capture, test_report, test_results, coverage_report, fuzzing_campaign, fuzzing_reproducer, static_analysis_report, penetration_test_report, laboratory_test_report, certification_or_approval_record, conformance_test_report, vulnerability_handling_record, signing_record, provisioning_record, device_state_statement, timestamp_or_transparency_receipt, other. Never inferred from the filename or the bytes; omit it and the record states no kind.
--firmware-image
PATH
none
any
no
Artifact form: the firmware image this capture was taken on. Hashed, never parsed; the record keeps the SHA-256 and the file name only. A symlink, device or FIFO is refused. A statement, never an observation.
--firmware-sha256
HEX
none
any
no
Artifact form: that image's SHA-256 (64 lowercase hex) when you have the digest but not the file. With --firmware-image the two must agree.
--firmware-build-id
HEX
none
any
no
Artifact form: the image's GNU build id as you state it (even-length, 2 to 128 lowercase hex). A build id is not a checksum.
--firmware-version
TEXT
none
any
no
Artifact form: the firmware version the device or build reported, as you state it (at most 128 characters). Never a stand-in for a digest.
--firmware-inner-hash
ALG:HEX
none
any
no
Artifact form: the image hash an MCUboot image carries in its own hash TLV, as a device manager reports it (ALG sha256, sha384 or sha512; lowercase HEX of that length). Not the file's SHA-256.
--capture-session
ID
none
any
no
Artifact form: an id joining several records from one capture, alert or campaign. Contact-free, same rule as --operator.
--performer
ID
none
any
no
Artifact form: who performed the test, as a lab, team or role id and never a personal contact. Same rule as --operator.
--independence
RELATIONSHIP
none
same_team, independent_internal, third_party
no
Artifact form: the tester's relationship to the team that built the thing. Closed set; no certified or accredited value exists. One of: same_team, independent_internal, third_party.
--test-environment
TEXT
none
any
no
Artifact form: the environment or rig tested on, as you state it (at most 256 characters, no control characters).
--configuration-file
PATH
none
any
no
Artifact form: a configuration, dictionary or profile recorded by name and digest. Hashed, never parsed.
--procedure-ref
TEXT
none
any
no
Artifact form: the procedure or test-plan reference followed, as stated (at most 128 characters). Never dereferenced.
--original-location
URI
none
any
no
Artifact form: where the original is kept, as you state it (s3:, gs:, az:, https:, file: or urn:, or an opaque id; at most 512 characters). Never fetched. Refused with a user name, query, fragment, presigned-URL parameter or absolute host path.
--retain-until
DATE
none
any
no
Artifact form: the date you state the original must be kept until, recorded as typed. No retention period is computed.
--valid-until
DATE
none
any
no
Artifact form, with --artifact-kind certification_or_approval_record or conformance_test_report: the date the record states it applies until, recorded as typed and compared only with --as-of. Nothing is decided from it.
--keep-original
(flag)
false
—
no
Keep a local copy under originals/ in this set (streamed and checked; never exported).
--break-stale-lock
(flag)
false
—
no
Artifact form: remove a provably stale set lock left by a crashed command.
--captured-at
TIMESTAMP
none
any
no
Artifact form: when the capture was taken, as you state it (an assertion; recorded as captured_as_of, the fact ingest-preserved-artifact --as-of records). Never defaulted to the clock. --as-of stays tool time.
--json
(flag)
false
—
no
Print the operation result as JSON.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Where the export is written (directory); it must be absent or empty, and is never a symlink.
--zip
(flag)
false
—
no
Also write a byte-reproducible custody-export.zip inside OUT.
--recipient
NAME
none
any
no
Contact-free identifier of who this package was prepared for. Recorded in the manifest; it is not an access control and filters nothing.
--select-key
KEY
none
any
no
Export only this artifact (repeatable; a FULL review key, never a prefix). The export carries only the selected rows' records, decisions and audit events, and states how many were left out, never which.
--capture-session
ID
none
any
no
Export only the rows whose records state this capture session (with --select-key, the rows either selects). A session no row states is refused.
--key
PEM
none
any
no
Private key to sign the export manifest with (requires --key-id and the sign extra).
--key-id
ID
none
any
no
Identifier recorded in the signature for the key used (requires --key).
--dry-run
(flag)
false
—
no
Print what would be exported and the preflight verdict; write nothing.
--json
(flag)
false
—
no
Print the export manifest as JSON.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Empty or absent directory for the set (its parent must exist).
--set-id
SET_ID
none
any
yes
Contact-free set identifier (lowercase letters, digits, . _ -).
--product
PRODUCT
none
any
no
Product the set is for, as you state it.
--release-id
RELEASE_ID
none
any
no
Release the set is for; artifacts stating another release are refused.
--issued-by
NAME
none
any
no
Contact-free identifier of the organisation that ISSUED the evidence (a test house, a laboratory, a vendor) — not the tool that produced it. Stated, never verified.
--retention-note
RETENTION_NOTE
none
any
no
How long you state the originals must be kept, in your own words (recorded verbatim, never interpreted, compared or checked).
--json
(flag)
false
—
no
Print the operation result as JSON.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Show only the rows whose records state this capture session. The output says how many rows were examined and how many matched, so a filtered listing is never mistaken for a whole set.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Record needs_more_evidence for this full review key.
--reviewer
NAME
none
any
no
Who decided (required).
--note
TEXT
none
any
no
The conclusion and its limits (required, non-empty).
--reviewed-at
T
none
any
no
When the reviewer decided (default: --as-of, else now).
--idempotency-key
K
none
any
no
Optional stable key so a retried decision converges to ONE operation. Same key and same decision returns the existing operation; the same key for a different decision is refused. 1-128 chars [A-Za-z0-9._-], scoped to this set.
--json
(flag)
false
—
no
Print the decision result as JSON.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Directory to look for originals in, by content (size, then sha256), never by name.
--expected-seal
SEAL
none
any
no
The 64-hex seal recorded earlier; a different seal is an integrity problem.
--public-key
PEM
none
any
no
Public key for an export's optional signature. Without it, and without the sign extra, a signature present is reported present_unverified, never verified.
--strict
(flag)
false
—
no
Also require every original verified and no orphan files.
--json
(flag)
false
—
no
Print the verification report as JSON.
--as-of
AS_OF
none
any
no
Tool time: pins generated_at and audit event timestamps, so output is byte-identical across runs (default: now, UTC). It is never a capture time.
Also run the design-partner pilot preflight: smoke analysis, pinned determinism double-run, disk space, and target writability. Checks the environment only, never product or evidence readiness.
--fix
(flag)
false
—
no
Print a plan of safe, reversible remediations. Print-first: plans nothing to disk by itself.
--apply
(flag)
false
—
no
With --fix, execute the plan's still-valid actions (skips any with a drifted precondition).
--release-manifest
RELEASE_MANIFEST
none
any
no
Signed release-manifest.json to compare the installed version and local vulndb snapshot against, fully offline (never fetched, never auto-updated).
--public-key
PUBLIC_KEYS
none
any
no
PEM public key to trust for --release-manifest verification (repeatable).
--vulndb-dir
VULNDB_DIR
.sbomflow-vulndb
any
no
Local vulndb snapshot directory for --release-manifest freshness comparison (default: .sbomflow-vulndb, matching sbomflow vulndb --dir).
--analysis-control
PATH
none
any
no
Run the offline runtime control receipt against the packaged reserved diagnostic corpus and write it to PATH. Reads no customer project, writes nothing else, and reaches no verdict about any product.
--observed-at
TIMESTAMP
none
any
no
Observation time to record on the --analysis-control receipt (RFC 3339). Omitted, no time is recorded rather than invented.
Directory produced by 'analyze' (not needed for --explain-terms).
--gap
GAP_ID
none
any
no
Explain this evidence gap id.
--finding
VULN_ID
none
any
no
Explain this advisory finding id/alias.
--gate
(flag)
false
—
no
Explain release-gate.json.
--ai-entity
ENTITY_ID
none
any
no
Explain one AI evidence entity end to end: what was observed, what was declared, where each fact came from, and what is being asked of a reviewer. A unique id prefix is accepted.
--preserved-artifact
KEY
none
any
no
Explain one preserved artifact in this run: its declared record, the original, the identity the record states, the run's checks, the review decision and the files that name it. A full review key or a unique digest prefix of at least 12 hex characters.
--explain-terms
[TERM]
none
any
no
Plain-language definitions of the core vocabulary (SBOM, VEX, CVSS, purl, gate, KEV, EPSS, SSVC, ...). Omit TERM for all of them; needs no output directory.
--warning
[CODE]
none
any
no
Explain a scan-warning code and this run's occurrences (omit CODE to list the codes seen in this run).
An output directory from sbomflow analyze or audit.
--output
FILE
none
any
yes
Write the ReqIF document here (file): a path outside the input, replaced if present; one export per directory.
--as-of
AS_OF
none
any
no
Pinned CREATION-TIME and LAST-CHANGE (default: the evidence pack's own generated_at).
--exploitation-delta
FILE
none
any
no
A delta store exploitation-delta wrote (sbomflow-exploitation-delta-v1). Each finding it names for this release carries sbomflow.exploitation_delta. Read offline and bounded; a file of another schema is refused. Without it no delta is read (none is guessed) and the receipt says not_available.
Which extractor to run on the image. SBOMFlow launches it as a subprocess with no shell, a sanitized environment, a timeout and bounded output, into a controlled temporary directory. It is not an OS or network sandbox: run a hostile image's extractor inside one you manage.
--executable
EXECUTABLE
none
any
no
Extractor executable (defaults to adapter name).
--expected-executable-sha256
SHA256
none
any
no
Optional pinned extractor SHA-256.
--timeout
SECONDS
120
any
no
Seconds the extractor subprocess may run before it is terminated and the extraction abandoned (default: 120). It does not bound the inventory walk that follows, which is bounded by --max-files/--max-expanded-bytes.
--max-file-bytes
MAX_FILE_BYTES
268435456
any
no
Largest single extracted file to inventory, in bytes (default: 256 MiB).
--max-expanded-bytes
MAX_EXPANDED_BYTES
8589934592
any
no
Total extracted bytes to inventory before stopping, a decompression-bomb bound (default: 8 GiB).
--max-files
MAX_FILES
5000000
any
no
Largest number of extracted files to inventory (default: 5000000).
--max-ratio
MAX_RATIO
200.0
any
no
Largest expanded-to-image size ratio treated as plausible (default: 200.0).
--max-depth
MAX_DEPTH
32
any
no
Deepest nesting level the inventory walk descends (default: 32).
--output
OUTPUT
none
any
no
Write firmware-extraction.json here (file; default stdout).
A command (help audit), a command group (help reviewing), a topic word (help topics lists them all) or a keyword (help vex); or error/exit/warning [CODE] for an offline code explanation.
--json
(flag)
false
—
no
Emit the machine-readable per-command network-behavior registry.
The file to preserve (read-only; never modified). Its bytes are digested; only the header fields a registered reader names are read, and only to show them.
--release-id
RELEASE_ID
none
any
no
The release this belongs to. Recorded as an ASSERTION a human made, never as a fact read out of the artifact.
--scenario
SCENARIO
none
any
no
The test scenario or session this artifact came from (an assertion).
--tool-name
TOOL_NAME
none
any
no
The tool that produced it, as stated by the operator (an assertion).
--tool-version
TOOL_VERSION
none
any
no
That tool's version, as stated by the operator (an assertion).
--notes
NOTES
none
any
no
Capture conditions worth recording for whoever reviews this.
--artifact-kind
KIND
none
any
no
What the evidence IS, as stated by the operator (an assertion), from a closed vocabulary: runtime_trace, core_dump, crash_report, device_log, bench_log, network_capture, test_report, test_results, coverage_report, fuzzing_campaign, fuzzing_reproducer, static_analysis_report, penetration_test_report, laboratory_test_report, certification_or_approval_record, conformance_test_report, vulnerability_handling_record, signing_record, provisioning_record, device_state_statement, timestamp_or_transparency_receipt, other. Never inferred from the filename, the extension or the bytes: omit it and the record states no kind rather than guessing one. A value outside the vocabulary is refused.
--valid-until
DATE
none
any
no
With --artifact-kind certification_or_approval_record or conformance_test_report: the date the record states it applies until, checked by the --as-of validator and recorded as typed. A run compares it with --as-of and decides nothing from it; refused on any other kind.
--firmware-image
PATH
none
any
no
The firmware image this capture was taken on. Its bytes are hashed (never parsed) and the record keeps the SHA-256 and the file NAME only — never the host path. A symlink, a device or a FIFO is refused. This records that you state the capture ran on that image; SBOMFlow does not observe it.
--firmware-sha256
HEX
none
any
no
That image's SHA-256, when you have the digest but not the file: 64 lowercase hex characters. Given together with --firmware-image the two must agree, or both values are named and nothing is written.
--firmware-build-id
HEX
none
any
no
The image's GNU build id, as stated by the operator: an even-length run of 2 to 128 lowercase hex characters. A leading 0x is refused rather than stripped. A build id is not a checksum — it survives stripping.
--firmware-version
TEXT
none
any
no
The firmware version the device or the build reported, as stated by the operator (at most 128 characters, no control characters). A version string is never a stand-in for a digest.
--firmware-inner-hash
ALG:HEX
none
any
no
The image hash an MCUboot image carries in its own hash TLV, as a device manager reports it: ALG is sha256, sha384 or sha512 and HEX is lowercase hex of that algorithm's length. Not the file's SHA-256, and never a version string. A run compares it with the hash the declared image states.
--capture-session
ID
none
any
no
An id joining several records from one capture, alert, campaign or engagement, as the operator states it. Contact-free, same rule as --operator. Nothing groups files on its own.
--performer
ID
none
any
no
Who performed the test, as a lab, team or role identifier — never a personal contact. Same identifier rule as --operator, for the same reason: this value may leave the company inside a record.
--independence
RELATIONSHIP
none
same_team, independent_internal, third_party
no
The relationship between the tester and the team that built the thing. The set is closed and has no certified or accredited value: SBOMFlow verifies no qualification and will not record a claim it cannot support. One of: same_team, independent_internal, third_party.
--test-environment
TEXT
none
any
no
The environment or rig tested on, as stated by the operator (at most 256 characters, no control characters).
--configuration-file
PATH
none
any
no
A rig configuration, dictionary or profile to record by NAME AND DIGEST. The file is hashed and never parsed, so what it contains stays yours while a reviewer can still tell it is the file that was used.
--procedure-ref
TEXT
none
any
no
The procedure or test-plan reference followed, as stated (at most 128 characters). SBOMFlow never dereferences it.
--original-location
URI
none
any
no
Where the original is kept, as you state it: an s3:, gs:, az:, https:, file: or urn: location, or an opaque id (at most 512 characters). Never fetched, resolved or opened. Refused when it carries a user name, a query string or fragment, a presigned-URL parameter, or an absolute path on this host.
--retain-until
DATE
none
any
no
The date you state the original must be kept until, checked by the --as-of validator and recorded as typed. SBOMFlow computes no retention period and keeps no original.
--root
ROOT
none
any
no
Containment root: refuse an artifact path that resolves outside it, rather than reading something from elsewhere on the host.
--as-of
AS_OF
none
any
no
When the capture was taken, as you state it (an assertion); never defaulted to the clock, which only says when this command ran.
--operator
OPERATOR
none
any
no
Who preserved it, as you state it (an assertion); never defaulted to the OS user, who only ran the shell.
--output
OUTPUT
none
any
no
Write preserved-artifact.json here (file). Defaults to the output directory when one is given, so the record lands beside the rest of the run's evidence rather than beside the operator's input file. Give each artifact its own path, for example preserved/<scenario>.preserved-artifact.json: a destination that already holds a different record (a regular file, or a symlink to one) is refused (E019) and never overwritten. Re-running with identical inputs succeeds and changes nothing.
--output-dir, --evidence-dir
EVIDENCE_DIR
none
any
no
The run's evidence directory (also spelled --evidence-dir). The record is written into it as preserved-artifact.json unless --output names a path, so a second artifact for the same directory needs its own --output.
Initial declared product.class value. SBOMFlow does not classify the product. One of: default, important-class-i, important-class-ii, critical.
--requirement-regime
{cra,none}
cra
cra, none
no
Initial requirement_regime value (default: cra). none scaffolds a config with no product.class, technical_documentation, annex_i_evidence or due_diligence keys, so a following run is a none run that trips no requirement-regime preflight refusal.
Path to the delivered entitlement JSON file, or '-' to read it from stdin.
--public-key
PUBLIC_KEYS
none
any
no
PEM public key to trust (repeatable). Adds to any bundled keys.
--as-of
AS_OF
none
any
no
Pinned ISO-8601 time for deterministic verification.
--revocations
REVOCATIONS
none
any
no
Signed revocation list to check against, offline. A missing or unverifiable list degrades to a warning, never a hard failure.
--replace
(flag)
false
—
no
Instruct the swap when the candidate is not a clean renewal of what is installed (downgrade, different organisation, reduced scope, expired, or a current file that could not be read). Required in non-interactive use.
passport.zip, or a directory holding only a passport's own members. To check the analysed output directory passport issue wrote into, verify the passport.zip there.
--public-key
PUBLIC_KEY
none
any
no
PEM public key to verify the signature (needs the 'sign' extra).
Project directory to scan (default: the current directory).
--output
OUTPUT
none
any
no
Where the evidence pack is written (directory). Default: <target>/sbomflow-evidence.
--product-name
PRODUCT_NAME
none
any
no
Override the auto-detected product name.
--product-version
PRODUCT_VERSION
none
any
no
Override the auto-detected product version.
--requirement-regime
{cra,none}
none
cra, none
no
Which requirement regime this run is executed under: cra (default) derives the CRA Annex I requirement graph, gaps and coverage; none declares that no requirement regime applies, so no requirement is assessed and the run records that declaration. Under none the empty evidence gaps mean NOT ASSESSED, never 'no gaps'. Overrides requirement_regime in sbomflow.yaml.
--no-init
(flag)
false
—
no
Do not scaffold sbomflow.yaml (audit with detected defaults only).
--zip
(flag)
false
—
no
Also write the deterministic bundle zip.
--tour
(flag)
false
—
no
After the summary, print a numbered, copy-paste guided tour through the release workflow, filled with this run's real paths. Pure print, CI-safe.
--as-of
AS_OF
none
any
no
Pinned timestamp for a reproducible first run.
--ci
{github}
none
github
no
Instead of auditing, emit a ready-to-commit CI workflow (offline audit + gate + PR annotations + evidence upload). Currently: github.
--force
(flag)
false
—
no
With --ci, overwrite an existing workflow file (default: refuse).
--yes
(flag)
false
—
no
Accept the disclosed scope without being asked. Only a run with no target given is ever asked; the disclosure itself is always printed.
--json
(flag)
false
—
no
Emit the pre-write disclosure as deterministic JSON and exit without writing anything or auditing. Same facts as the text form, including the labelled bounded-count state and the output-directory state.
Newer local OSV-format advisory snapshot (JSON list, {'vulns': [...]}, JSONL, or an OSV per-ecosystem all.zip).
--nvd-file
NVD_FILE
none
any
no
Local NVD snapshot for CVSS/CPE context.
--kev-file
KEV_FILE
none
any
no
Local CISA KEV snapshot.
--epss-file
EPSS_FILE
none
any
no
Local FIRST EPSS snapshot.
--store
STORE
none
any
no
Release store, to attach prior decisions as context.
--output
OUTPUT
none
any
no
Where the report is written (directory). Default: EVIDENCE_DIR/recheck.
--as-of
AS_OF
none
any
no
Pinned timestamp for a reproducible recheck.
--vulndb-dir
DIR
none
any
no
Local vulndb store holding the advisory snapshot the release recorded. Offline: that store's index and the one archive named by the release's recorded digest are read, nothing is fetched, and no other snapshot is read in its place. Each row then says whether its advisory was present_in_release_snapshot or absent_from_release_snapshot. Without it every row reads release_snapshot_unavailable — which is the honest answer, since no store was examined; a store guessed from the working directory would make the answer depend on where the command was run. Changes no status, no summary count and no exit code.
init: write an empty profile (no legal asks). validate: report every structural problem. inspect: explain each selector. export: copy the profile plus a manifest to a clean directory (never evidence).
profile
profile
none
any
yes
Profile file to write (init) or read (validate/inspect/export).
--profile-id
PROFILE_ID
none
any
no
init only: the local profile id. May not shadow a packaged profile.
--organisation
ORGANISATION
none
any
no
init only: the organisation authoring this profile. Required.
--title
TITLE
none
any
no
init only: a human-readable title for the profile.
--destination
DESTINATION
none
any
no
export only: an empty directory to write the profile and manifest into.
--output
OUTPUT
none
any
no
validate only: write regime-profile-validation.json here (file).
--json
(flag)
false
—
no
Print JSON to stdout instead of the text report; validate also writes an --output named beside it, with the same document.
An analyze/audit output directory (read-only; never modified).
--regime
REGIME
none
any
no
Packaged profile id to apply: a regime profile id, not the requirement regime of the run. An unknown id is refused, never defaulted. Supply this or --regime-file.
--output
OUTPUT
none
any
no
Write regime-view.json here (file). Default: EVIDENCE_DIR/regime-view.json.
--json
(flag)
false
—
no
Print the view as JSON to stdout instead of writing the default file; an --output named beside it is written too, with the same document.
--as-of
AS_OF
none
any
no
Pinned timestamp recorded in the view.
--regime-file
REGIME_FILE
none
any
no
Apply a LOCAL, customer-authored profile file instead of a packaged profile id. Mutually exclusive with --regime.
Print a starting justification scaffold for the given CISA category and exit (you edit it into a real explanation; it is never submitted). One of: component_not_present, vulnerable_code_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_cannot_be_controlled_by_adversary, inline_mitigations_already_exist.
--reviews
REVIEWS
none
any
no
Evidence reviews file to read/update (default: <output>/reviews.json).
--vulnerability-reviews
VULNERABILITY_REVIEWS
none
any
no
Vulnerability VEX-triage file to read/update (default: <output>/vulnerability_reviews.json).
--accept
KEY
none
any
no
Accept the evidence item with this key, or the preserved artifact whose review key (preserved-artifact:sha256:<hex>, listed in preserved-artifacts.json) this is; a preserved-artifact decision requires --reviewer and --note.
--reject
KEY
none
any
no
Reject the evidence item or preserved artifact KEY.
--needs-more-evidence
KEY
none
any
no
Mark the evidence item or preserved artifact with this key as needing more evidence.
--triage
VULN_ID
none
any
no
Record a VEX triage decision for this vulnerability id (with --status).
VEX status for --triage. One of: affected, fixed, not_affected, under_investigation.
--justification
JUSTIFICATION
none
any
no
CISA justification (required when --status not_affected).
--evidence-ref
EVIDENCE_REF
none
any
no
Optional evidence reference for a VEX triage.
--waive-gap
GAP_ID
none
any
no
Record a time-boxed waiver for this gap id (requires --reason and --expires-at).
--waive-finding
VULN_ID
none
any
no
Record a time-boxed waiver for this finding id (requires --reason and --expires-at).
--renew-waiver-gap
GAP_ID
none
any
no
Renew the existing waiver for this gap id with a fresh --reason and a later --expires-at (the reason must differ from the one it renews).
--renew-waiver-finding
VULN_ID
none
any
no
Renew the existing waiver for this finding id with a fresh --reason and a later --expires-at (the reason must differ from the one it renews).
--revoke-waiver-gap
GAP_ID
none
any
no
Revoke the existing waiver for this gap id (requires --reason and --reviewer). The record stays in waivers.json marked revoked — history preserved — and immediately stops applying; a revoked waiver cannot be renewed (record a fresh waiver instead).
--revoke-waiver-finding
VULN_ID
none
any
no
Revoke the existing waiver for this finding id (requires --reason and --reviewer). The record stays in waivers.json marked revoked — history preserved — and immediately stops applying; a revoked waiver cannot be renewed (record a fresh waiver instead).
--dispute-match
FINDING_KEY
none
any
no
Dispute the advisory match itself for this finding_key (requires --reason and --reviewer: a dispute suppresses a blocking finding, so it must name the human who asserted the match is wrong). Distinct from VEX: excludes the finding from vex.json/cyclonedx-vex.json/csaf-vex.json entirely, labels it (never excludes it) in cyclonedx-vdr.json, and suppresses it from the gate under its own disputed_matches list; reappears automatically if the match evidence (aliases/range/purl) changes on a later run.
--reason
REASON
none
any
no
Mandatory reason recorded with a waiver, a waiver revocation, or a match dispute.
--expires-at
EXPIRES_AT
none
any
no
Mandatory ISO expiry recorded with a waiver.
--start
KEY
none
any
no
Claim an evidence key, vulnerability id, or gap id: moves it to 'in_review' so two reviewers don't silently duplicate work (requires --as ROLE). A claim carries no evidence authority — it never accepts evidence or sets a status.
--as
ROLE
none
any
no
Reviewer role claiming the item with --start.
--force
(flag)
false
—
no
With --start: reclaim an item already claimed by someone else (the prior claim stays in the audit log).
--bulk
FILE
none
any
no
Record many VEX triage decisions from a pre-reviewed .csv or .json worksheet (columns/keys: finding_key, status, justification, reviewer, note, evidence_ref — finding_key is the vulnerability id, same as --triage). Each row is validated and recorded independently with its own audit event; invalid rows are listed and skipped, valid rows still apply. There is no 'accept all' — every row states its own status and justification.
--reviewer
REVIEWER
none
any
no
Reviewer identity recorded with the decision.
--note
NOTE
none
any
no
Reviewer note recorded with the decision (required, with --reviewer, for a preserved-artifact key: the conclusion and its limits).
--reviewed-at
REVIEWED_AT
none
any
no
ISO timestamp for the decision (default: now/--as-of).
--idempotency-key
KEY
none
any
no
Optional stable key so a retried vulnerability triage converges to ONE operation instead of recording a second one. Same key + same decision returns the existing operation; same key + a different decision is refused. 1-128 chars [A-Za-z0-9._-]. SCOPE: convergence is per OUTPUT DIRECTORY — the same key used against a different output dir is a separate operation, not a retry.
--assign
ROLE
none
any
no
Annotate the queue with an assigned reviewer role.
--as-of
AS_OF
none
any
no
Pinned timestamp for the queue / audit event.
--filter
EXPR|@name
none
any
no
Narrow the queue view with comma-joined FIELD OP VALUE terms (severity/epss/kev/status/ssvc/kind/assigned/component), e.g. 'severity>=high,kev=true'; or @name for a filter saved under review.filters in sbomflow.yaml. A filter narrows what you look at — it never changes a decision, a status, or the gate.
--store
DIR
none
any
no
Local evidence store to read prior reviewer decisions from (offline). Surfaces this product's earlier per-finding decisions as review context; it never suppresses a finding or changes VEX status.
--json
(flag)
false
—
no
Emit the review queue as JSON.
--digest
(flag)
false
—
no
Print a session digest of decisions recorded in this audit log (accepted/rejected/needs-more-evidence, findings triaged, waivers, approvals), grouped with event-hash references, and write session-digest.md. Read-only; records nothing.
--since
SINCE
none
any
no
With --digest: only include decisions recorded at or after this ISO-8601 timestamp.
Use this as the editable declared-class default; SBOMFlow does not classify the product. One of: default, important-class-i, important-class-ii, critical.
--output
OUTPUT
none
any
no
Use this as the editable output-directory default (directory).
--style
{system,dark,light,high-contrast,ansi,none}
none
system, dark, light, high-contrast, ansi, none
no
Use this terminal output style without prompting for a style.
Optional key identifier recorded in the signature.
--as-of
AS_OF
none
any
no
Pinned signed_at timestamp.
--format
{sbomflow,in-toto}
sbomflow
sbomflow, in-toto
no
'sbomflow' writes evidence-bundle.sig.json (default); 'in-toto' writes a DSSE envelope evidence-bundle.intoto.jsonl for standard in-toto verifiers. Same key, same guarantee — integrity/authenticity only.
Local vulndb store holding the two KEV snapshots (the directory vulndb update --dir wrote). Offline: its index and the two archives named by id are read, their bytes re-hashed against the recorded digests, and nothing is fetched. Required in effect: no default is assumed, because a store guessed from the working directory would make the delta depend on where the command was run; without it the command refuses.
--from
KEV_SNAPSHOT_ID
none
any
yes
The older KEV snapshot id (as vulndb inspect lists it).
--to
KEV_SNAPSHOT_ID
none
any
yes
The newer KEV snapshot id; its dateReleased must not precede --from's.
--output
FILE
none
any
yes
Where the delta document is written (file). Never inside the store.
Machine-transfer/DR check: a by-reference release whose external directory cannot be read here FAILS instead of reporting 'by_reference' (exit 4). Use after moving or restoring a store.
--reference-root
REFERENCE_ROOT
none
any
no
Where by-reference release directories live on THIS machine, for a store that moved. Changes only where --strict looks; no recorded path is rewritten.
--expected-seal
EXPECTED_SEAL
none
any
no
A whole-store seal recorded earlier (the 'seal' block of a previous --json run). A release lost in transfer fails here even though every surviving release still hashes correctly.
The gate policy whose recorded outcomes you are verifying: a shipped preset name or a policy file path (.json/.yaml), resolved exactly as sbomflow gate simulate and sbomflow policy show resolve it. Optional: when omitted, each release resolves its own policy from what it recorded — a packaged --policy-profile binding, else the full policy body it stored. A release that recorded neither, or whose stored body does not reproduce its recorded hash, is reported unverifiable, never guessed.
--vulndb-dir
DIR
none
any
no
Local vulndb store to resolve each release's recorded source set against, for the replayability column only. Reads that store's index; no network on any path. Without it, a release that recorded a set reports unknown — source_store_not_examined, which states what this run looked at rather than anything about the release: replayable and the byte-level findings behind it (source_bytes_unavailable, source_bytes_unverifiable_by_content, source_store_unreadable) are only ever produced when this is supplied. No default is assumed — a store guessed from the working directory would make the column depend on where the command was run. Changes no gate verdict, no summary counter and no exit code.
--product
PRODUCT
none
any
no
Scope to one product id or name substring.
--as-of
AS_OF
none
any
no
Pin the report timestamp (ISO-8601 UTC) for reproducible output.
One release id or content hash. Omitted, every release in the store (optionally narrowed by --product) is replayed.
--vulndb-dir
DIR
none
any
no
Local vulndb store holding the retained snapshots. Offline: the index and archives are read, nothing is fetched. Without it every release reports source_bytes_unavailable — which is the honest answer, since no store was examined; a store guessed from the working directory would make the verdict depend on where the command was run.
--product
PRODUCT
none
any
no
Scope to one product id or name substring.
--output
DIR
none
any
no
Where vulnerability-replay-verification.json is written (directory); it must be ISOLATED. Never inside the store: a report deposited in the stored release would change the bytes a later replay hashes.
--as-of
AS_OF
none
any
no
Pin the report timestamp (ISO-8601 UTC) for reproducible output.
Zip to write (default: <output-dir>/support-bundle.zip).
--config
CONFIG
none
any
no
Config file whose SHAPE (keys and types) is recorded.
--as-of
AS_OF
none
any
no
Pinned timestamp for a reproducible bundle.
--dry-run
(flag)
false
—
no
Print a per-section byte-size preview and write nothing (ignores --yes).
--max-size
BYTES
26214400
any
no
Size budget in bytes (default: 26214400). Over budget, optional sections are dropped largest-value-last and listed; 0 always refuses rather than dropping anything, since mandatory content can never reach zero bytes.
--yes
(flag)
false
—
no
Write the bundle. Without it nothing is written and the manifest is printed.
Directory produced by 'analyze' (has issues.json).
--repo
REPO
none
any
yes
Target repository as 'owner/name'.
--apply
(flag)
false
—
no
Make real GitHub API calls (requires GITHUB_TOKEN). Off = dry run, no network.
--labels
LABELS
none
any
no
Comma-separated issue labels. Default: sbomflow,cra-evidence for a cra run, sbomflow,release-evidence for a run recorded under requirement_regime none (read from its evidence-pack.json).
Directory produced by 'analyze' (has issues.json).
--project-key
PROJECT_KEY
none
any
yes
Target Jira project key.
--issue-type
ISSUE_TYPE
Task
any
no
Jira issue type name.
--labels
LABELS
none
any
no
Comma-separated labels. Default: sbomflow,cra-evidence for a cra run, sbomflow,release-evidence for a run recorded under requirement_regime none (read from its evidence-pack.json).
--apply
(flag)
false
—
no
Create/update Jira issues by marker (network). Requires --base-url, JIRA_EMAIL/--jira-email, and JIRA_API_TOKEN. Off = dry run, no network.
--base-url
BASE_URL
none
any
no
Jira Cloud base URL, e.g. https://acme.atlassian.net.
--jira-email
JIRA_EMAIL
none
any
no
Jira account email for Basic auth (or env JIRA_EMAIL).
Directory (or a .zip) with a signed evidence bundle.
--key
KEY
none
any
no
PEM public key path for signature verification.
--json
(flag)
false
—
no
Emit the verification detail as one JSON document (per-layer under --layered), parity with passport verify --json.
--layered
(flag)
false
—
no
Full four-layer verification (content/envelope/semantics/authority) instead of the manifest-only signature check. Accepts a directory or a .zip; a tampered listed member fails even when the signature is intact.
--authorized-key-sha256
SHA256
none
any
no
Operator trust policy: sha256 of a public-key PEM authorised to sign (repeatable). With --layered, a valid signature from a key not listed is reported valid_but_unauthorized and is not trusted.
--require-layers
LAYERS
none
any
no
Automation contract for --layered: comma-separated layer names (content,envelope,semantics,authority) that MUST verify. Exit 7 when a well-formed report does not meet them; the full layer report is still printed. Unknown names and use without --layered are refused (exit 2) before verification. Without this flag exit codes are unchanged.
--refuse-extras
(flag)
false
—
no
With --layered: a member the bundle manifest does not list fails the content layer's expectation (exit 7), instead of verifying with extras_present. For automation that must not accept anything added to a bundle; the default audit -> bundle -> auditor-pack flow writes such members by design. Use without --layered is refused (exit 2).
A source-set document recorded EARLIER (vulndb sources --set, or the source_set block a run recorded in source-health.json). Its retained snapshots are read from --dir; the active set is never substituted for it.
--new-set
PATH
none
any
yes
The source-set document to compare it against, same shape and rules.
--store
STORE
none
any
yes
Evidence store whose stored releases are evaluated against both sides. Required: the per-release candidate section is part of this artifact's shape, and a store with no releases reports that honestly rather than producing a differently-shaped document.
--output
OUTPUT
none
any
no
Where source-change-impact.json is written (directory). Default: the current directory.
--as-of
AS_OF
none
any
no
Pin the comparison timestamp (ISO-8601; default: now).
--json
(flag)
false
—
no
Print the document on stdout; nothing is written unless --output is also named, in which case the same document is written there too.
Machine-readable inventory on stdout (schema_version sbomflow-vulndb-source-inventory-v1).
--set
(flag)
false
—
no
Emit the content-addressed ACTIVE source set on stdout (schema_version sbomflow-vulndb-source-set-v1); record it to replay a run.
--coverage
(flag)
false
—
no
Report, per source, whether an operator can REACH it from this build (schema_version sbomflow-vuln-source-coverage-v1). Reads no store and says nothing about whether data is current or complete.
--verify-set
PATH
none
any
no
Replay a recorded source set against this store and report per-source match/missing/differs/added. Observes only: nothing is activated or fetched.
Official archive URL (OSV dump / CVE List V5 release / NVD CVE feed). Omit when --source names a managed feed.
--source
{csaf-provider,epss,kev}
none
csaf-provider, epss, kev
no
Pin a managed exploitation feed by its official URL (CISA KEV / FIRST EPSS) instead of --url/--source-type; or csaf-provider with --url <provider-metadata.json> to fetch a CSAF 2.0 provider's TLP:WHITE advisories into a local csaf-directory mirror.
--source-type
TYPE
other
csaf-directory, cve-v5, epss, kev, nvd, osv, other
no
Which registered dataset family the snapshot holds, so it is parsed by the right reader (default: other). One of: csaf-directory, cve-v5, epss, kev, nvd, osv, other.
--path
PATH
none
any
no
Local directory of CSAF 2.0 documents (as a CSAF downloader writes it) to register as a pinned snapshot, offline. Valid only with --source-type csaf-directory; refused together with --url.
--release-identity
RELEASE_IDENTITY
none
any
no
Release tag/identity to record.
--modification-window
MODIFICATION_WINDOW
none
any
no
Covered modification window to record.
--as-of
AS_OF
none
any
no
Pinned retrieval timestamp (testing/determinism).
--allow-shrink
(flag)
false
—
no
Allow a >30% record-count drop to become eligible for implicit activation; requires --shrink-reason and still emits a warning.
--shrink-reason
SHRINK_REASON
none
any
no
Auditable reason for --allow-shrink (for example, confirmed mass withdrawal).