Run a release audit
Produce a release-evidence pack from a build and read it. This page documents every command in the auditing group, in the order sbomflow help auditing lists them. Each command's section is generated from the command itself — its summary, description and options from the parser, and its reads, writes, exit codes, examples and see-also from the command catalog — so it says exactly what sbomflow <command> --help says. Every example below is executed offline by the test suite, and every non-zero exit code is either produced by an executed probe or carries a recorded reason why no offline probe can produce it.
See the CLI overview for how the thirteen groups fit together and the command reference for every command's options in one place.
Overview#
sbomflow audit <dir> --output <dir>— full offline evidence pack for a release.sbomflow analyze <dir> --output <dir>— the analysis stage.sbomflow explain <output> --gap <id>— explain an evidence gap.sbomflow explain <output> --finding <id>— explain an advisory finding.sbomflow explain <output> --gate— explain the release-gate decision.sbomflow explain <output> --warning <code>— explain a scan-warning code and the exact inputs that triggered it in this run (omit the code to list the codes seen). See the Warning codes reference.sbomflow validate— validate a generated output directory.sbomflow next-actions— a sourced worklist for the run you just did; every command it prints is one you can paste and run.
On a large device, validate takes minutes, almost all of it spent checking spdx3-sbom.json against the official SPDX 3.0.1 schema. It announces that step and its expected cost on stderr before starting it, so a long run is distinguishable from a hung one — see validate is taking minutes for the measured figures and how to avoid the cost.
validate is also the tamper check, and a value edited to another JSON type (a string into an array, an object into a number) is a changed artifact like any other: it exits 4 and names the artifact. A check that meets a value of a type it does not read fails that artifact alone, names the check, and lets every other check run. Only when every artifact that check read still holds the bytes the run's completion seal recorded does it end in E099, because then the value is SBOMFlow's own and the fault is a bug to report.
sbomflow batch-run <manifest>— runanalyzefor every product declared in one batch manifest, sequentially. Each job gets its own output directory (enforced before anything runs), every job runs even when an earlier one fails, and the exit code is the worst job's — so a batch never looks healthier than its unhealthiest product. A shell loop does the same thing; this adds per-product isolation and partial-failure aggregation. Every row also carrieswarningsandconsole_lines(that job's warning count and the number of lines it was counted out of — a clean job keeps its warnings, not its chatter) andnetwork_posture/network_gates/network_posture_reason. The posture isoffline,network_enabledorunknown, read from the configuration that job DECLARES: it says what the job was permitted to reach, never that a socket was or was not opened, andunknownmeans the declaration could not be read rather than that the job stayed offline. A job that exits hard — an argparse refusal inside the in-process re-invocation raisesSystemExit— is recorded as that job's error and the estate continues; Ctrl-C still stops the whole batch.sbomflow next-actions <output-dir>— the release-scoped ship-readiness line (exit N BECAUSE policy X in mode Y) plus the top few outstanding items, with--jsonfor machine use and--limitto widen the list. Aggregation only: it restates the gate's verdict rather than making one, and always exits 0 — the release gate remains the only machine verdict.
Every action names the pack you actually passed and the real decision key, so the printed command is one you can run rather than a template to fill in. When an input genuinely is not knowable from an output directory, the action says so and names where to get it instead of printing a command that would fail. The JSON carries argv as an array alongside the display string, so a caller never has to re-parse a shell line to run one.
Where an action's examples are things you can open on their own — an AI evidence conflict, an AI item with nothing declared about it — each example also carries its own sbomflow explain … --ai-entity <id> command, in example_commands in the JSON and under per example: in the text. Where they are not (a control name, a drift attribute), the action says why it offers none rather than printing a line that would fail, and the category command above it is still the whole answer.
A preserved artifact's review key is printed under its original's file name in the text (e.g. boot-to-idle.psf with the key on the next line, and For boot-to-idle.psf alone: above that artifact's own command), read from preserved-artifacts.json in the directory you passed. sbomflow review does the same in its queue (- boot-to-idle.psf, then the key, then Original verified). The --json document keeps file names out, as before, because it is meant to be shared.
What has LEFT the worklist is recorded too, in terminal_history: count and three examples as before, and now items — every identifier a decision recorded since the analysis run has covered, per category and in total. The worklist is capped because a person reads it; this record is not, because "the finding I decided yesterday — was it handled, or lost?" is a question about the fourth item as much as the first.
A preserved scheme record — a scheme's certificate or a scheme test tool's report, recorded with its kind — whose stated firmware version is not string-equal to the release version this run declares is listed as a scheme_record_names_other_version item. The JSON records list carries each record's review key with the version it states and the version this release declares, and the text shows both beside each example. It is two statements disagreeing, compared as text: the item decides nothing about whether the record still applies, and it stays listed while the two differ, even after a reviewer records a decision about that file (see runtime-and-test-evidence.md).
An entry of the evidence plan in sbomflow.yaml (preserved_artifact_expectations:) that fewer declared rows match than it names — absent, or not_evaluable when rows that state no kind leave the count undecided — is listed in one preserved_artifact_expectation_unmet item. The JSON records list carries each entry's id, kind, minimum, matching row count and state, and the text shows them beside each example. It offers no command: the fix is in sbomflow.yaml or in the records, followed by a new run. It compares a plan you wrote with the rows declared and says nothing about whether the plan is sufficient (see runtime-and-test-evidence.md).
The list also declares what it rests on, in a freshness block:
- live_decisions — the reviewer decision file beside the pack was re-read for this run, so a decision recorded since the analysis run is already reflected, and findings that were ruled on appear under already decided rather than in the worklist; - snapshot_only — no decision file sits beside the pack, so the list rests on the frozen analysis snapshot and names that fact; - snapshot_unreadable_overlay — a decision file is there but could not be read. The list falls back to the snapshot; treat items as possibly stale. This is deliberately not the same state as an absent file.
Each action carries its own freshness_basis too, so a category with no live overlay is labelled rather than borrowing the freshness of the ones that have one.
Each entry in freshness.decision_sources also carries an input_state, because several different facts fall back to the snapshot and must not read alike: absent (nothing is there), unreadable (something is there and its bytes were never seen — a permission, a directory in the file's place, a dangling symlink, a document past the size budget), malformed (the bytes were read and are not that family's decisions — including a file whose entries are not themselves decisions, such as {"key": "accepted"}), conflicted (the file records more than one answer for one key, so none of them is applied) and valid. A rejection_reason travels beside it. Only valid lets an overlay remove anything from the worklist, and even then the removal rests on the recorded status: an entry with no status, an unknown status, or a not_affected without a valid CISA justification and an attributed reviewer is downgraded and stays on the list.
AI and model evidence#
Every AI surface below is a command or flag you can run. Nothing here runs, loads, evaluates or scores a model, and nothing observes runtime behaviour.
sbomflow analyze <dir>— static discovery of model artifacts, agents, tools, services and MCP servers, from framework and deployment configuration, dependency files, imports and environment-variable names. Secret values are never recorded, and every detector publishes what it cannot see beside what it can.ai-evidence.jsonandai-evidence-map.jsonare written on every run, including the run that found nothing. Both are experimental artifacts.analyze --ai-manifest <file>/audit --ai-manifest <file>— read your own declaration of the AI in the release. The declaration never overwrites the observation, a disagreement is surfaced and never resolved automatically, and a run without the flag records that nothing was compared. The flag being available does not mean anyone supplied a manifest.analyze --emit-mlbom/--emit-aibom(also onaudit) — opt-in AI/ML BOMs: CycloneDX 1.6 ML-BOM and the SPDX 3.0.1 AI profile, linked to the software SBOM rather than copied. The software SBOM itself stays CycloneDX 1.6 and SPDX 2.3.sbomflow explain <output> --ai-entity <id>— explain one AI entity for review. AI-aware release controls are opt-in and off by default; when one is enforced and cannot run, it blocks with its own reason code rather than passing.
Some AI work landed in v0.5.0 as library foundations with no operator path — see Capabilities.
Who this is for: firmware leads, platform teams, estate owners, developers, release managers, QA engineers and programme managers.
sbomflow audit#
Run analyze + full opt-in packs + bundle + validation in one command.
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.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| 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) |
--output names | a directory |
| Network | 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. |
| Exit codes | 0 ok · 1 an enforced gate blocked the release · 2 usage, input, IO or config error · 4 a written artifact failed validation |
| Machine output | has-json — read/status surface; one versioned JSON document on stdout |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
--report-theme | {light,dark} | light | light, dark | no | 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). |
--product-name | PRODUCT_NAME | none | any | no | Override the product name. |
--product-version | PRODUCT_VERSION | none | any | no | Override the product version. |
--product-class | CLASS | none | default, important-class-i, important-class-ii, critical | no | 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). |
--previous-output | PREVIOUS_OUTPUT | none | any | no | Previous SBOMFlow output directory; enables release-drift.json. |
--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 | Vulnerability VEX-triage decisions file to apply. |
--reachability-evidence | REACHABILITY_EVIDENCE | none | any | no | Manufacturer-supplied reachability evidence inputs (context, never a decision). |
--tree-sitter-reachability | (flag) | false | — | no | Opt in to bounded Tree-sitter C/C++ call-context observations (sbomflow[reachability]). |
--approvals | APPROVALS | none | any | no | Release-approval ledger (approvals.json) consulted by the gate. |
--waivers | WAIVERS | none | any | no | Reviewer-owned waivers file; an unexpired waiver marks its item 'waived' (still listed). |
--require-role | ROLE | none | any | no | Required release-approval role (repeatable); additive over a policy profile. |
--policy | POLICY | none | any | no | Standalone named/versioned release-gate policy profile (.json/.yaml). |
--policy-profile | NAME | none | any | no | 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. |
--json | (flag) | false | — | no | Emit one machine-readable summary. |
Examples
Run the full offline evidence pack for one release.
sbomflow audit . --output outAlso write the deterministic evidence-bundle.zip to hand over.
sbomflow audit . --output evidence --zipEnforce the evidence-gap gate; it blocks this demo and exits 1 with every artifact written. Exits 1.
sbomflow audit . --output evidence --fail-on-gapsPrint one machine-readable summary instead of the text report.
sbomflow audit . --output evidence --jsonAudit with no requirement regime assessed.
sbomflow audit . --output evidence --requirement-regime noneWrite one release's full offline evidence pack into evidence, the directory the first steps read.
sbomflow audit . --output evidenceSee also: sbomflow analyze, sbomflow review, sbomflow bundle, sbomflow explain, sbomflow help auditing, sbomflow help goal sign-off.
sbomflow analyze#
Scan a product directory and write its evidence pack (audit adds the bundle).
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.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| 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 |
--output names | a directory |
| Network | 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. |
| Exit codes | 0 ok · 1 an enforced gate blocked the release · 2 usage, input, IO or config error · 5 --strict matched a scan warning |
| 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 |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
--report-theme | {light,dark} | light | light, dark | no | 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). |
--product-name | PRODUCT_NAME | none | any | no | Override the product name. |
--product-version | PRODUCT_VERSION | none | any | no | Override the product version. |
--product-class | CLASS | none | default, important-class-i, important-class-ii, critical | no | 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. |
--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. |
--policy | POLICY | none | any | no | Standalone named/versioned release-gate policy profile (.json/.yaml). |
--policy-profile | NAME | none | any | no | 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). |
Examples
Scan a source tree and write the evidence artifacts.
sbomflow analyze . --output out --product-name Gateway --product-version 2.4.1Refuse to write into a directory that already holds a run. Exits 2.
sbomflow analyze . --output out --on-existing-output refuseEmit a VEX document alongside the pack, for downstream consumers.
sbomflow analyze . --output out --emit-vexWrite the SBOMs with no requirement regime assessed.
sbomflow analyze . --output out --requirement-regime noneCompare with the previous release's pack and write the drift report as HTML too.
sbomflow analyze . --output out --previous-output out-prev --drift-htmlSee also: sbomflow audit, sbomflow review, sbomflow explain, sbomflow compare-releases, sbomflow help auditing, sbomflow help goal sbom.
sbomflow batch-run#
Run analyze across every product declared in one batch manifest.
Run `analyze` for each job in a batch manifest, sequentially, and
aggregate the outcomes. Ergonomics over a shell loop: per-product
isolation and partial-failure aggregation, not new capability. The
exit is 0 only if every job exited 0, else the worst job's code.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | a batch manifest and each job's source tree. |
| Writes | evidence-pack.json (one pack per job, in its own directory); stdout (the summary; --json prints JSON) |
| Network | opt-in-network — Runs analyze per job, so it inherits analyze's class: the default path is offline, but a JOB'S OWN CONFIG can enable egress for that job. The batch adds no network flags itself. Gates: each job's own config: osv/nvd enabled with scan.offline=false, each job's own config: exploitation.use_kev/use_epss=true with scan.offline=false. |
| Exit codes | 0 every job exited 0 · 1 the worst job's enforced gate blocked it · 2 manifest refused, or the worst job exited 2 |
| Machine output | has-json — one versioned batch summary on stdout; each job's own output is captured so the document stays parseable, and every row carries that job's warning count (with the line count it was taken out of) plus its declared network posture |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
manifest | manifest | none | any | yes | Batch manifest declaring the jobs to run. |
--json | (flag) | false | — | no | Emit the batch summary as JSON. |
Examples
Analyze every product the manifest declares, one after another.
sbomflow batch-run estate/estate.yamlPrint the batch summary as JSON, one row per job.
sbomflow batch-run estate/estate.yaml --jsonRefuse a file that is not a batch manifest. Exits 2.
sbomflow batch-run estate/products/sensor/requirements.txtSee also: sbomflow analyze, sbomflow portfolio, sbomflow dashboard.
sbomflow validate#
Validate a generated evidence output directory.
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.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | an existing analyze or audit output directory. |
| Writes | stdout (the report; --json prints JSON) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 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 |
| Machine output | has-json — read/status surface; one versioned JSON document on stdout |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
EVIDENCE_DIR | EVIDENCE_DIR | none | any | yes | Directory produced by 'analyze'. |
--json | (flag) | false | — | no | Machine-readable report on stdout (schema_version sbomflow-validate-report-v1); same exit codes as the human output. |
Examples
Check that an output directory is a complete, well-formed run.
sbomflow validate outPrint the same report as one JSON document, with the same exit.
sbomflow validate out --jsonRefuse a pack whose evidence-pack.json fails its schema. Exits 4.
sbomflow validate broken-evidenceSee also: sbomflow audit, sbomflow verify-bundle, sbomflow store verify, sbomflow help exit.
sbomflow explain#
Explain one gap, finding, gate decision, warning or preserved artifact from existing artifacts.
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).| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | an existing analyze or audit output directory; --explain-terms needs none. |
| Writes | stdout (the explanation; nothing is written) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 unknown id or missing artifact |
| Machine output | human-only-by-design — renders a prose explanation composed from artifacts that are already machine-readable on disk |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
[EVIDENCE_DIR] | [EVIDENCE_DIR] | none | any | no | 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). |
Examples
Explain why the release gate decided what it decided.
sbomflow explain out --gateExplain one scan-warning code, sourced from the catalog.
sbomflow explain out --warning unparseable_manifestExplain one advisory finding: where it matched and what a reviewer decided.
sbomflow explain out --finding CVE-SAMPLE-OPENSSL-001List the warning codes this run actually emitted.
sbomflow explain out --warningDefine a term; no output directory is needed.
sbomflow explain --explain-terms kevExplain 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 c640b5514933See also: sbomflow review, sbomflow next-actions, sbomflow help, sbomflow help warning.
sbomflow next-actions#
Release-scoped ship-readiness line plus the top few outstanding actions.
Answer "is this release ready, and what do I deal with first?" by
aggregating facts already in an output directory. Aggregation only -
it invents nothing, decides nothing, and never says ship/do-not-ship.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | an existing analyze or audit output directory. |
| Writes | stdout (the worklist; --json prints JSON) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok, even with actions outstanding · 2 missing or unusable directory |
| Machine output | has-json — one versioned next-actions document on stdout; aggregation only, never a decision |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
EVIDENCE_DIR | EVIDENCE_DIR | none | any | yes | Directory produced by 'analyze' or 'audit'. |
--json | (flag) | false | — | no | Emit the next-actions document as JSON. |
--limit | LIMIT | none | any | no | How many actions to surface (default 3). |
Examples
Print the ship-readiness line and the three actions to deal with first.
sbomflow next-actions outPrint the next-actions document as JSON.
sbomflow next-actions out --jsonSurface five actions instead of three.
sbomflow next-actions out --limit 5See also: sbomflow explain, sbomflow review, sbomflow report freshness.
sbomflow report#
Derived, read-only planning reports composed from a finished run.
Read-only planning reports composed from a finished run. Each verb reads
artifacts that are already on disk and decides nothing; name a verb, or the
group prints its usage and exits 2.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | nothing itself; its verb reads a finished output directory. |
| Writes | nothing itself; its verb's help names what it writes |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 a verb ran and returned 0 · 2 no verb, or the verb refused |
| Machine output | human-only-by-design — group dispatcher: prints usage/guidance only; the machine surfaces are its nested verbs |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
Examples
Print what lapses next in a finished run, evaluated at a pinned time.
sbomflow report freshness out --as-of 2026-07-01T00:00:00ZThe same horizon as JSON, flagging items that lapse within 30 days.
sbomflow report freshness out --json --as-of 2026-07-01T00:00:00Z --horizon-days 30Name no verb: print the report group's usage and exit 2. Exits 2.
sbomflow reportSee also: sbomflow report freshness, sbomflow next-actions.
sbomflow report freshness#
What goes stale next: one dated horizon composed from a run's artifacts.
Compose one freshness horizon from a finished output directory: accepted
evidence validity windows, advisory-snapshot staleness, waiver expiries,
and the support-period end — all the dated things that lapse, soonest
first.
Read-only and offline. Planning context, not a decision: it changes no
review state and suppresses no gate. Writes freshness-horizon.json into
the directory.| Fact | Value |
|---|---|
| Group | auditing — Run a release audit |
| Stability | stable |
| Regime | any |
| Reads | a finished analyze or audit output directory. |
| Writes | freshness-horizon.json, into the directory; stdout (the horizon; --json prints JSON) |
| Network | offline — This command has no network-capable path. |
| Exit codes | 0 ok · 2 missing or unusable directory |
| Machine output | has-json — read/status surface; one versioned JSON document on stdout |
Options
| Option | Value | Default | Allowed | Required | Help |
|---|---|---|---|---|---|
-h, --help | (flag) | none | — | no | show this help message and exit |
EVIDENCE_DIR | EVIDENCE_DIR | none | any | yes | A finished analyze/audit output directory. |
--as-of | AS_OF | none | any | no | Evaluate the horizon at this ISO-8601 UTC time (default: now). |
--horizon-days | HORIZON_DAYS | 90 | any | no | Flag items lapsing within this many days as expiring_soon (default: 90). |
--json | (flag) | false | — | no | Emit JSON to stdout. |
Examples
Print what lapses next, evaluated at a pinned time.
sbomflow report freshness out --as-of 2026-07-01T00:00:00ZThe same horizon as JSON, flagging items that lapse within 30 days.
sbomflow report freshness out --json --as-of 2026-07-01T00:00:00Z --horizon-days 30Look a year ahead: every dated item lapsing within 365 days is flagged.
sbomflow report freshness out --as-of 2026-07-01T00:00:00Z --horizon-days 365See also: sbomflow next-actions, sbomflow recheck, sbomflow vulndb retention.