Skip to main content

Flags

FlagDefaultDescription
--imageContainer image to inspect; repeatable
--images-fromScan every image named in this list — a file with one reference per line, a hauler manifest, a Kubernetes manifest, a URL, or - for stdin. # comments allowed, repeats scanned once — see Scanning a fleet
--haulScan every image inside a hauler haul without a registry — a .tar.zst, a tar, or an unpacked store directory. Charts and files in the haul are counted and named on stderr, never dropped silently
--rootfsFilesystem tree already on disk to inspect — see --rootfs
--repoGit source repo to analyze: govulncheck source mode for Go, lock file inventory for Python and npm
--sbomCycloneDX JSON bill of materials to scan — a path, or - for stdin. Every finding is undetermined; see --sbom
--rpmRPM package file to scan without installing it — a path, a directory of them, or a URL; repeatable. Reads only the header, so a URL costs kilobytes not megabytes — see --rpm
--rpm-deepfalseWith --rpm, decompress the payload and extract its ELF objects so the elf-dynsym-absent test can run. Needs --mine-advisories --llm; downloads the whole package; never runs the reachability closure — see --rpm-deep
--packagePackage to check: purl, ecosystem:name, or bare name; repeatable
--cvesCVE / GHSA / GO / RHSA / DSA ids; alone, resolved against the whole target
--allfalseCheck everything each ecosystem can enumerate
--ecosystem(all)Restrict to these ecosystems (golang, os, pypi, npm, maven, or a distro family); repeatable
--moduleDeprecated alias for --package golang:MODULE
--cves-fileFile with one id per line (merged with --cves; # comments allowed)
--ref(default branch)Branch, tag, or commit to check out for --repo
--repo-path.Subdirectory within --repo to scan — the Go module, or the directory holding the lock files
--module-version(auto)Override the module version (image mode) instead of reading build info
--version / -VPrint vexscan's version and exit. --version=VERSION is a deprecated spelling of --module-version and warns
--go-version(auto)Pin the Go toolchain for --repo, e.g. 1.24.0 (useful with golang:stdlib)
--osv-ecosystem(auto)Override the OSV ecosystem derived from os-release, from the VENDOR/DISTRIBUTION headers under --rpm, or from the distro= purl qualifier under --sbom, e.g. Debian:12
--rootsExtra entrypoints for the closures — shared libraries and language imports; repeatable. Adds a starting point; it cannot take the image's own away — for that see --entrypoint
--entrypointThe program this image is actually started with, replacing the ENTRYPOINT its config declares. One argv token per use, repeatable and ordered. An override the image does not contain blocks conclusions rather than narrowing them — see Taints and When there is no manifest
--cmdThe arguments this image is actually started with, replacing the CMD its config declares; same form as --entrypoint. --cmd= says it is started with none, which is not the same as saying nothing. Given alone it leaves the declared ENTRYPOINT running, as Kubernetes args: and docker run IMAGE ... do
--vexhubVEX Repository to check findings against, e.g. https://github.com/rancher/vexhub (also a raw base URL or a local directory); repeatable, earliest wins — see VEX hubs
--distro-feedsSUSE onClear OS-package false positives with the distribution's own security feed: a vendor not-affected or an already-shipped fix moves a row to ALREADY VEXED, and like --vexhub never changes a status. SUSE's CSAF-VEX runs by default for SUSE images (it declines every other image and touches no network for one); --distro-feeds additionally consults the opt-in feeds (Debian's tracker today), and --distro-feeds=false consults none. Network — see Distribution security feeds
--vex-outWrite not_affected documents for the findings ruled out into this directory, laid out as a VEX hub; with --vexhub they are merged into what that hub publishes, so it can be a clone of it — see Contributing ruled-out findings back
--vex-authorWith --vex-out, the author to record on the statements — required, and an error without --vex-out
--vex-formatopenvexWith --vex-out, the serialisation to write: openvex or csaf. A hub indexes one document per product, so a product the hub already publishes in the other format is left untouched with a warning: — see Writing CSAF instead
--vex-merge-intoWith --vex-out, also add every statement to this merged "master" document in the hub, e.g. reports/rancher.openvex.json; repeatable, never added to index.json, OpenVEX only. A named aggregate that cannot be written fails the run — see Merged "master" reports
--vex-publisher-namespaceWith --vex-format csaf, the URI identifying the publisher, e.g. https://acme.example — required for CSAF, and an error without it
--vex-publisher-categoryotherWith --vex-format csaf, the CSAF publisher category: coordinator, discoverer, other, translator, user, vendor
--severity(all)Only report findings at these severities: CRITICAL, HIGH, UNKNOWN, MEDIUM, LOW, NONE; comma-separated or repeatable. UNKNOWN must be named to be shown — see Filtering by severity
--fixed-onlyfalseOnly report findings a fix has been published for. Prints how many it hid and how many of those are AFFECTED — see Filtering to what you can fix
--triagefalseOrder findings by exploitation evidence — EPSS scores and CISA's known-exploited catalog. Adds two columns and re-sorts; hides nothing and changes no severity — see Prioritising by exploitation evidence
--dlopen-policytainttaint (block conclusions) or assume-none
--dlopen-assume-noneThe narrow form of the above: assert that one named dlopen caller loads nothing that matters, by path or SONAME. Repeatable, and an error alongside --dlopen-policy=assume-none. A name matching no caller discharges nothing and is reported — see Waving off one caller
--exec-policytaintThe same knob for a Go entrypoint that links a process-spawning call. assume-none asserts that what it runs is accounted for — name those with --roots — see The exec probe
--dynamic-import-policytaintThe same knob for a language import graph's computed imports. These are far more common than dlopen, so assume-none discards much more
--trust-import-absencefalseLet a missing dynamic import conclude not_in_execute_path (weaker than it looks)
--os / --archlinux / amd64Image platform variant to pull (image mode only)
--llmfalseConsult a chat model on genuinely-affected CVEs; needs a provider below
--llm-endpointOpenAI-compatible chat/completions URL — an API provider or a local Ollama
--llm-modelgpt-4oModel id for --llm-endpoint
--llm-commandRun this installed CLI instead of an endpoint, e.g. 'claude -p'
--mine-advisoriesfalseWith --llm, mine advisory prose for symbols and module paths to check
--formattexttext, summary, json, sarif, fixplan, or inventory
--detailsfalseWith --format text, print the full evidence block under each row instead of the table alone
--out(stdout)Write output to a file
--gistfalseAlso upload the output to a public gist and print its URL (token needs gist scope)
--gist-secretfalseWith --gist, create a secret (unlisted) gist
--fail-onExit 3 if a counted finding is at or above this severity, or any. Off by default — see Gating a pipeline
--fail-on-statusaffectedWhat --fail-on weighs: a comma-separated list of affected, undetermined, vexed, cleared, or all
--colorautoauto, always, or never. auto colours only a terminal — never a pipe, a --out file, a --gist, JSON, or a run with NO_COLOR set — see Colour
--no-pagerfalseNever page the output, even when stdout is a terminal — see Reading a long report
--quietfalseSuppress progress logging on stderr

--gist uploads whatever would otherwise be printed, respecting --format, using GITHUB_TOKEN / GH_TOKEN with gist scope. It composes with --out (written to the file and uploaded).

Standard library​

Go standard-library CVEs work in both modes via --package golang:stdlib (the name OSV and govulncheck use; std is an alias):

vexscan --image myorg/app:latest --package golang:stdlib --cves CVE-2025-22870
vexscan --repo github.com/rancher/rancher --package golang:stdlib --go-version 1.24.0

In repo mode the stdlib version analyzed is that of the toolchain running govulncheck. GOTOOLCHAIN=auto only ever upgrades, so without --go-version a repo is scanned with the newest locally-available toolchain. A pinned older toolchain may be too old to build the latest govulncheck; pair it with VEXSCAN_GOVULNCHECK_VERSION (e.g. v1.1.4) if go run complains.

Environment variables​

Its own variables are prefixed VEXSCAN_; the GOMODVEX_ names are still honored as a fallback so existing CI keeps working.

VariableLegacy namePurpose
VEXSCAN_LLM_ENDPOINTOpenAI-compatible chat/completions URL for --llm
VEXSCAN_LLM_MODELModel id for that endpoint (default gpt-4o)
VEXSCAN_LLM_TOKENBearer credential for that endpoint; OPENAI_API_KEY / ANTHROPIC_API_KEY are accepted as fallbacks
VEXSCAN_LLM_COMMANDA local CLI to run for --llm instead of calling an endpoint
VEXSCAN_LLM_MIN_INTERVALGOMODVEX_LLM_MIN_INTERVALMinimum spacing between --llm calls (Go duration; default none)
VEXSCAN_GOVULNCHECK_VERSIONGOMODVEX_GOVULNCHECK_VERSIONPin the govulncheck version used by --repo
VEXSCAN_TRIAGE_CACHEDirectory for the --triage feed cache (default os.UserCacheDir()/vexscan/triage, e.g. ~/Library/Caches or $XDG_CACHE_HOME)
VEXSCAN_PAGERGOMODVEX_PAGERPager for terminal output; $PAGER is the fallback, less the default. Set it empty to never page — unlike the variables above, an empty value here is a decision rather than an absence

GITHUB_TOKEN / GH_TOKEN are for --gist (gist scope), and are unchanged. --vex-out needs no credential: it writes to the filesystem, and reads the hub over the same read-only path --vexhub uses.