Skip to content

Search

Search the docs, blog, and marketplace.

Release assurance

Bomly CLI v0.28.1

Verified

Everything we check for this release was verified: 37 claims, all confirmed.

Released
4 October 2026
Release notes and downloads

How to read this

A claim

One specific statement about what this version of Bomly does — for example, that it reads an npm lockfile correctly, or that the files you download are the ones we signed.

Verified

Something ran against this exact release and confirmed the claim. Every result links to the record of it running, so nothing here has to be taken on trust.

What a verified claim does not mean. It covers what is listed on this page and nothing more. Software can still fail in ways nobody has written a check for. Claims that depend on outside services record what those services said on the day, and timing figures are measurements from one test machine rather than promises.

Nothing here is written by hand. The page is generated from the checks themselves and published automatically with each release, including any claim that was not confirmed. How this is produced.

At a glance

What this release was checked for. Each card opens the section behind it.

Scanning real projects

Verified

Running the real command line against pinned example projects and comparing the entire result with a recorded one.

2 claims verified

Dependency graphs

Verified

Working out which packages a project depends on, and how each one got there.

8 claims verified

Policy decisions

Verified

Deciding what counts as a problem: licences, vulnerabilities, baselines, and packages that change where they come from.

4 claims verified

Reachability

Verified

Judging whether a vulnerable package is actually used by the code that depends on it.

4 claims verified

Upgrade guidance

Verified

The fixes Bomly recommends, worked out without changing anything in your project.

1 claim verified

Comparing two scans

Verified

Telling what genuinely changed between two scans, and what only looks new.

1 claim verified

Other scan targets

Verified

Scanning things that are not a local source tree, such as container images.

1 claim verified

SBOM compatibility

Verified

Reading SBOM documents other tools produce, and writing ones they accept.

3 claims verified

Running everywhere

Verified

Behaving the same on Linux, macOS, and Windows, and building for every processor a release supports.

3 claims verified

Handling broken input

Verified

Reading damaged or hostile project, configuration, and SBOM files without crashing.

1 claim verified

Speed and repeatability

Verified

How long a repeated scan takes, and whether it returns the same answer every time.

1 claim verified

What you download

Verified

Whether the published files are complete, unaltered, and signed by this project's release pipeline.

6 claims verified

Installing it

Verified

Whether the documented ways of installing this release actually work.

1 claim verified

This report itself

Verified

The catalog and contracts the report is built from, and the check that keeps them honest.

1 claim verified

Ecosystems covered

The languages and package formats this release was scanned against. Each was exercised by at least one claim above.

.NETVerifiedC and C++VerifiedContainer imagesVerifiedDartVerifiedElixirVerifiedGoVerifiedJavaVerifiedJavaScriptVerifiedPHPVerifiedPluginsVerifiedPythonVerifiedRubyVerifiedRustVerifiedSBOM documentsVerifiedScalaVerifiedSwiftVerified

Scanning real projects

Verified

Running the real command line against pinned example projects and comparing the entire result with a recorded one.

2 claims verified

VerifiedThe released binary scans real projects

Runs scan, diff, and explain with the binary from the published release against pinned example repositories and checks the results against the same golden files the source-tree smoke tests use.

What this shows

  • The binary users actually download produces the same dependency graphs as the source tree it was built from.

What it does not

  • A representative subset of ecosystems runs against the released binary; the full ecosystem matrix runs on the source tree before the release is tagged.

3 instances passed.

packages
3
tests failed
0
tests passed
11
tests skipped
0
tests total
11

Where it ran — 3 of 3 verified

Check it yourself
sh -c BOMLY_SMOKE_BINARY=$PWD/bin/bomly go test -tags smoke ./test/smoke/ -run 'TestScan$/scan-go$'
VerifiedEnd-to-end scans of real projects

Runs scan, diff, and explain against pinned public repositories, one slice per ecosystem, and compares the whole result with checked-in golden files.

What this shows

  • For every supported ecosystem, the command line produces exactly the dependency graph, policy result, and output shape recorded in the golden files.

What it does not

  • Golden files pin one revision of one example project per ecosystem. They do not cover every project layout or every version of a package manager.
  • Cases that reach live advisory services can change when upstream data changes.

22 instances passed.

packages
22
tests failed
0
tests passed
107
tests skipped
0
tests total
107
Check it yourself
make smoke

Dependency graphs

Verified

Working out which packages a project depends on, and how each one got there.

8 claims verified

VerifiedVisible detector fallback

Forces a detector to fall back to a second technique and checks that the result says so instead of hiding it.

What this shows

  • A detector fallback preserves its origin and produces a typed degraded-coverage warning.

What it does not

  • The synthetic detector case proves orchestration behavior, not the fidelity of every concrete fallback.
Check it yourself
go test ./internal/engine -run TestPipeline_RunRecordsFallbackWarning|TestPipeline_Run_TypesFallbackWarningsAsDegradedCoverage -count=1
VerifiedBun lockfile graph

Scans a pinned Bun example project and compares the whole dependency graph with a recorded one.

What this shows

  • The native Bun detector preserves the package inventory and dependency placement represented by the pinned lockfile.

What it does not

  • This is one Bun lockfile shape and does not prove behavior for every historical Bun format.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-bun$
VerifiedGo module graph

Scans a pinned Go example project and compares the whole dependency graph with a recorded one.

What this shows

  • The Go detector resolves a build-tool-backed module graph for the pinned repository.

What it does not

  • The result depends on a compatible Go toolchain and the evidence available from that toolchain.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-go$
VerifiedMaven dependency graph

Scans a pinned Maven example project and compares the whole dependency graph with a recorded one.

What this shows

  • The Maven detector resolves a build-tool-backed dependency graph for the pinned repository.

What it does not

  • Artifact resolution depends on Maven repositories and a compatible Java and Maven installation.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-maven$
Verifiednpm lockfile graph

Scans a pinned npm example project and compares the whole dependency graph with a recorded one.

What this shows

  • The npm detector preserves lockfile package inventory, versions, scopes, and dependency placement.

What it does not

  • This case covers the lockfile versions present in one pinned repository.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-npm$
Verifiedpnpm lockfile graph

Scans a pinned pnpm example project and compares the whole dependency graph with a recorded one.

What this shows

  • The pnpm detector preserves lockfile package inventory and dependency placement.

What it does not

  • This case does not cover every pnpm lockfile generation.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-pnpm$
VerifiedPython requirements graph

Scans a pinned Python example project and compares the whole dependency graph with a recorded one.

What this shows

  • The pip detector reads the pinned requirements lock and preserves the resolved Python package graph.

What it does not

  • Unpinned requirements and environment inspection have different fidelity and are not proven by this case.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-python-pip$
VerifiedYarn lockfile graph

Scans a pinned Yarn example project and compares the whole dependency graph with a recorded one.

What this shows

  • The Yarn detector preserves package inventory and dependency placement represented by the pinned lockfile.

What it does not

  • This case covers one Yarn lockfile family; fallback behavior is documented separately.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-yarn$

Policy decisions

Verified

Deciding what counts as a problem: licences, vulnerabilities, baselines, and packages that change where they come from.

4 claims verified

VerifiedFinding baseline lifecycle

Records a package finding in a project baseline, then scans again and compares the whole result with a recorded one.

What this shows

  • A project baseline can keep a denied package finding visible with suppressed policy status.

What it does not

  • The local matcher fixture is deterministic but does not measure advisory freshness.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestFindingBaselineWorkflow$
VerifiedComplex and invalid SPDX policy

Evaluates licence policy against a matrix of SPDX expressions, including combined, nested, exception, custom, and invalid ones.

What this shows

  • The license auditor evaluates AND, OR, nested, exception, custom-reference, and invalid SPDX expressions under allow and deny policy.

What it does not

  • The tests prove policy evaluation after license data is present; they do not prove the accuracy of every upstream license source.
Check it yourself
go test ./internal/auditors/license -run TestLicenseAuditorComplexSPDX|TestLicenseAuditorInvalidSPDXExpressionMatrix -count=1
VerifiedRegistry-to-Git source-change review

Compares two scans of the same project where one package moved from a registry to a Git source, and checks how that is flagged.

What this shows

  • Diff marks a same-version registry-to-Git move for review and the package auditor can fail it when source-change policy is enabled.

What it does not

  • A source change is a review signal, not proof of malicious intent, and unknown source evidence cannot be classified.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestDependencyDetailRiskPolicy$
VerifiedVulnerability policy constraints

Evaluates vulnerability policy against a matrix of severities, reachability tiers, known exploitation, and advisory allowlists.

What this shows

  • The vulnerability auditor composes severity, reachability, known exploitation, and advisory allowlists with the documented repeated-constraint behavior.

What it does not

  • Policy can only evaluate vulnerability, reachability, and exploitation evidence that is present in the registry.
Check it yourself
go test ./internal/auditors/vulnerability -run TestAuditorSeverityReachabilityExploitabilityAndAllowlistMatrix -count=1

Reachability

Verified

Judging whether a vulnerable package is actually used by the code that depends on it.

4 claims verified

VerifiedGo vulnerability reachability

Analyses a pinned Go project and checks the reachability evidence attached to each matched vulnerability.

What this shows

  • The Go analyzer attaches named analyzer, tier, status, and reason evidence to matched vulnerabilities.

What it does not

  • Advisories come from live services and may change; an unreachable result is not proof that a package is safe.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-go-reachability$
VerifiedJava package reachability

Analyses a pinned Java project and checks the reachability evidence attached to each matched vulnerability.

What this shows

  • The Java analyzer separates package-reachable and package-unreachable vulnerability evidence.

What it does not

  • This is package-tier evidence, not symbol-level proof, and live advisory results may change.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-java-maven-reachability$
VerifiedJavaScript package reachability

Analyses a pinned JavaScript project and checks the reachability evidence attached to each matched vulnerability.

What this shows

  • The JavaScript analyzer separates package-reachable and package-unreachable vulnerability evidence.

What it does not

  • This is package-tier evidence, dynamic loading can reduce confidence, and live advisory results may change.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-npm-reachability$
VerifiedPython package reachability

Analyses a pinned Python project and checks the reachability evidence attached to each matched vulnerability.

What this shows

  • The Python analyzer separates package-reachable and package-unreachable vulnerability evidence.

What it does not

  • This is package-tier evidence, reflective imports can reduce confidence, and live advisory results may change.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-python-pip-reachability$

Upgrade guidance

Verified

The fixes Bomly recommends, worked out without changing anything in your project.

1 claim verified

VerifiedCanonical read-only remediation guidance

Derives upgrade guidance for a set of findings and checks the fix status, versions, and per-occurrence advice it produces.

What this shows

  • One central component derives fix status, recommended versions, occurrence actions, and detector advice without applying changes.

What it does not

  • Suggestions are read-only evidence and are not guaranteed to work in every checkout.
Check it yourself
go test ./internal/remediation -run TestDerivePackageRemediation|TestDeriveBuildsCanonicalOccurrenceSuggestions -count=1

Comparing two scans

Verified

Telling what genuinely changed between two scans, and what only looks new.

1 claim verified

VerifiedRisk that persists across a version change

Compares two scans across a package version change and checks how a finding that survives the change is classified.

What this shows

  • A vulnerability or license finding that remains across a package version change is classified as persisted instead of one resolved and one introduced finding.

What it does not

  • Persistence uses the canonical package-finding identity; a genuinely different advisory or rule remains a distinct finding.

Confirmed for this release by

Check it yourself
go test ./internal/engine/diff -run TestRun_SameVulnerabilityAcrossVersionBumpPersists|TestRun_SameLicenseIssueAcrossVersionBumpPersists -count=1

Other scan targets

Verified

Scanning things that are not a local source tree, such as container images.

1 claim verified

VerifiedContainer package inventory

Scans a public container image and compares the operating-system packages found with a recorded inventory.

What this shows

  • Bomly can inventory the operating-system packages in the checked Alpine image.

What it does not

  • The upstream image tag can move; the checked-in golden is a snapshot, not an immutable image claim.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestContainerScan/container-scan-alpine$

SBOM compatibility

Verified

Reading SBOM documents other tools produce, and writing ones they accept.

3 claims verified

VerifiedOfficial validators accept our SBOMs

Generates SPDX 2.3 and CycloneDX 1.7 documents from the code about to be released — one pair from a single input and one pair merged from two source documents — and validates all four with checksum-pinned official SPDX and CycloneDX tools.

What this shows

  • The SBOM documents this release writes are accepted by the official SPDX and CycloneDX validators, at the exact validator versions recorded in the result.
  • A document merged from two sources states its own identity and links both sources, rather than adopting one of them.

What it does not

  • Validators check that a document is well formed against its specification. They do not check that every receiving tool interprets it the same way.
  • The merge case uses two checked-in fixtures; it does not cover every combination of source formats.
  • The documents are generated by a binary built from the release commit, before it is tagged, not by the published archive. The published files are verified separately.

4 generated SBOM documents passed spdx-tools-java 2.0.7 and cyclonedx-cli 0.32.0, and 1 document check(s) held.

checks
1
documents
4
validators
2
Check it yourself
go run ./internal/assurance/sbominterop -bomly ./bin/bomly
VerifiedCycloneDX 1.6 ingestion

Reads a checked-in CycloneDX document and compares the dependency graph it produces with a recorded one.

What this shows

  • Bomly ingests the checked CycloneDX 1.6 dependency graph.

What it does not

  • The fixture covers one document shape and does not imply lossless conversion from every producer.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-sbom-cyclonedx$
VerifiedSPDX 2.3 ingestion

Reads a checked-in SPDX document and compares the dependency graph it produces with a recorded one.

What this shows

  • Bomly ingests the checked SPDX 2.3 dependency graph.

What it does not

  • The fixture covers one document shape and does not imply lossless conversion from every producer.
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-sbom-spdx$

Running everywhere

Verified

Behaving the same on Linux, macOS, and Windows, and building for every processor a release supports.

3 claims verified

VerifiedRelease binaries build for every target

Cross-compiles the full and lite binaries for every supported operating system and processor from the same source tree.

What this shows

  • The source tree compiles into both binaries for every Linux, macOS, and Windows target a release ships.

What it does not

  • A successful build is not a test: it does not run the binary or check what it produces.

All 12 release binaries built: full and lite for Linux, macOS, and Windows on amd64 and arm64.

builds completed
12
builds planned
12
Check it yourself
gh workflow run assurance-prerequisites.yml -f ref=main
VerifiedUnit tests pass on every platform

Runs the full Go unit test suite twice on Linux, macOS, and Windows, so a pass is never a single lucky run.

What this shows

  • Every unit test passes on all three supported operating systems, twice in a row, so a pass is not a one-off.

What it does not

  • Unit tests run in process against fixtures. They do not download repositories or call external services.

3 instances passed.

completed runs
6
planned runs
6

Where it ran — 3 of 3 verified

Check it yourself
go test ./... -count=1
VerifiedJava detector tests are stable

Runs the Gradle, Maven, and sbt detector test suites ten times, because build-tool-backed detectors are where intermittent failures have actually appeared.

What this shows

  • The build-tool-backed Java detector suites passed ten consecutive times.

What it does not

  • This exercises the detectors against local fixtures with the toolchain installed on the runner.

The Gradle, Maven, and sbt detector suites passed ten times in a row.

completed runs
10
planned runs
10
Check it yourself
go test ./internal/detectors/gradle ./internal/detectors/maven ./internal/detectors/sbt -count=10

Handling broken input

Verified

Reading damaged or hostile project, configuration, and SBOM files without crashing.

1 claim verified

VerifiedParsers survive malformed input

Runs every registered Go fuzz target against the parsers that read untrusted project, configuration, baseline, SBOM, and plugin data.

What this shows

  • Each registered parser handled its seed corpus and newly generated inputs without crashing during the time budget of this run.

What it does not

  • Fuzzing explores a limited time budget. A clean run is evidence of robustness, not proof that no malformed input can cause a failure.
  • Parsers that are command-backed or handled entirely by the standard library are excluded and listed in test/assurance/PARSER_FUZZING.md.

30 fuzz targets ran for 30s each against their seed corpus without finding a crash.

targets
30
targets failed
0
Check it yourself
make fuzz FUZZTIME=60s

Speed and repeatability

Verified

How long a repeated scan takes, and whether it returns the same answer every time.

1 claim verified

VerifiedRepeated scan speed and stability

Runs the same offline scan with the released binary several times with a cold cache and several times with a warm cache, and records timing, memory, and output stability.

What this shows

  • Repeated runs of the same scan produced identical normalized output, and the recorded timings show how long that scan took on this machine.

What it does not

  • Timing and memory are observations from one CI machine, not limits. Comparing them across releases is only meaningful because the case and the machine class stay the same.

canonical-sbom-scan completed 5 samples per cache mode with identical normalized output (cold median 37 ms, warm median 36 ms).

cold ci95 upper (ms)
37 ms
cold mean (ms)
37 ms
cold median (ms)
37 ms
peak memory bytes
41 MiB
samples per mode
5
warm ci95 upper (ms)
37 ms
warm mean (ms)
36 ms
warm median (ms)
36 ms
Check it yourself
make benchmark-samples

What you download

Verified

Whether the published files are complete, unaltered, and signed by this project's release pipeline.

6 claims verified

VerifiedPublished files download and match

Downloads every published file from its public URL, without credentials, verifies the signature on the published checksum list, and checks each file against it.

What this shows

  • Every file a user downloads from the public release page is present, reachable without credentials, and matches a checksum list signed by this repository's release workflow.

What it does not

  • This checks availability and integrity at one moment from one network location.
  • It confirms the published files match the signed list; it does not re-check the provenance attestation, which is verified before publication.
  • Whether each archive contains a working binary is checked separately, against the draft release and by the install scripts.

All 23 published files downloaded from their public URLs without credentials and match the signed checksum list.

files
23
Check it yourself
gh release download <tag> --repo bomly-dev/bomly-cli
VerifiedEvery release file is attached

Compares the files attached to the draft release against the full list a release is required to ship.

What this shows

  • The release carries an archive for every supported platform, both binaries, every Linux package format, the checksum list, its signature, and the provenance file.

What it does not

  • This counts files. Whether each archive contains a working binary is checked separately.

23 of 23 expected release assets are attached.

assets
23
assets missing
0
Check it yourself
go run ./internal/assurance/cmd verify-release --dir assets --version <version>
VerifiedReleased binaries report this version

Extracts the archives built for each operating system and runs the binaries inside them.

What this shows

  • Both the full and lite binaries start on Linux, macOS, and Windows and report the version that is being released.

What it does not

  • Only the architecture of the CI runner is executed for each operating system; other architectures are verified by checksum and build only.

3 instances passed.

Where it ran — 3 of 3 verified

Check it yourself
go run ./internal/assurance/cmd verify-release --dir assets --version <version> --scope native
VerifiedRelease files match their checksums

Hashes every release file each platform downloads and compares it with the published SHA256SUMS list.

What this shows

  • Every file the release ships hashes to exactly the value recorded in the checksum list, and the list covers every file.

What it does not

  • Checksums prove the files were not altered after they were built; the signature and provenance checks prove who built them.

3 instances passed.

Where it ran — 3 of 3 verified

Check it yourself
sha256sum --check SHA256SUMS
VerifiedBuild provenance verifies

Verifies the SLSA build provenance attached to the release with slsa-verifier.

What this shows

  • The release archives were produced by this repository's tagged release workflow, as recorded in signed build provenance.

What it does not

  • Provenance describes how and where the files were built. It does not review what the source code does.

SLSA build provenance verifies the linux/amd64 archives against this repository and tag.

Check it yourself
slsa-verifier verify-artifact <archive> --provenance-path multiple.intoto.jsonl --source-uri github.com/bomly-dev/bomly-cli
VerifiedChecksum list is signed

Verifies the Sigstore signature over the release checksum list with cosign.

What this shows

  • The checksum list carries a valid Sigstore signature issued to this repository's release workflow, so the checksums themselves can be trusted.

What it does not

  • The signature covers the checksum list. Individual files are tied to it through their checksums.

The checksum list carries a valid Sigstore signature issued to this repository's release workflow.

Check it yourself
cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp ^https://github.com/bomly-dev/bomly-cli/

Installing it

Verified

Whether the documented ways of installing this release actually work.

1 claim verified

VerifiedInstall scripts install the release

Runs the published install script on each operating system against this release and asks the installed binary for its version.

What this shows

  • The documented one-line install works on Linux, macOS, and Windows for this exact release, and the installed binary reports this version.

What it does not

  • This installs into a temporary directory on a clean runner. It does not cover every shell, proxy, or locked-down corporate environment.

3 instances passed.

Where it ran — 3 of 3 verified

Check it yourself
sh -c BOMLY_VERSION=<tag> BOMLY_INSTALL_DIR=$PWD/bin sh scripts/install.sh

This report itself

Verified

The catalog and contracts the report is built from, and the check that keeps them honest.

1 claim verified

VerifiedAssurance catalog is valid

Validates this catalog and confirms every fixture and expected-result file it points at exists.

What this shows

  • Every claim in this report points at a real check and at files that are present in this release's source.

What it does not

  • A valid catalog says the paperwork is consistent; the checks themselves decide whether the software works.

The assurance catalog is valid and every fixture and expected-result file it names exists.

checks
16
Check it yourself
make assurance-catalog