Skip to main content

The offline vulnerability bundle

Vulkro checks your dependencies against known vulnerabilities on your own machine. The advisory data it uses arrives as one signed file, the CVE bundle, so the same check works on a laptop, in CI, behind a proxy and on a machine with no network at all.

What is in it​

A .vkbundle is a gzipped archive with three parts:

  • manifest.json: the snapshot id, when it was built, the ecosystems it covers, the record counts and a SHA-256 for every data file.
  • manifest.json.sig: an Ed25519 signature over the manifest.
  • data/: one advisory file per ecosystem, plus optional rule packs and compliance frameworks.

The data is collected from OSV, NVD, CISA KEV and EPSS. Current bundles cover npm, PyPI, Maven, Go, crates.io, RubyGems, Packagist and NuGet.

How it is verified​

Before anything is written, Vulkro:

  1. checks the signature on manifest.json against the public keys built into the binary, plus any key you add with --trust-key;
  2. checks the SHA-256 of every file against the manifest;
  3. stages the files and swaps them into place in one step.

A signature that matches no trusted key is refused. There is no trust on first use and no "warn but allow", and because the trust list lives in the binary, whoever controls a mirror or a USB stick cannot name their own key. Any failure stops before the swap, so the data directory is never left half updated.

vulkro update --verify ./cves.vkbundle   # check only, writes nothing
vulkro update --bundle ./cves.vkbundle   # check, then apply

How it stays current​

On a connected machine, vulkro update downloads the current bundle named in the public manifest at dist.vulkro.com/cve/manifest.json, which lists its snapshot date, record count, SHA-256 and signing key. An air-gapped team downloads the same file on the connected side, verifies it, carries it across its approved channel and applies it inside. For a custom build, write to license@vulkro.com.

Every scan states how old its data is: table output prints the bundle date and age, and JSON, SARIF and SBOM output carry a cve_bundle field. To make age a hard rule in CI:

vulkro scan . --max-bundle-age 168 --max-bundle-age-fail   # exit 2 past 7 days, or with no bundle

If a project uses an ecosystem the applied bundle does not cover, the scan says those dependencies were not checked, rather than reporting them clean.

Further reading​

Start a 14-day trial