Subcommand Reference for CI

Every platform page links here rather than restating this. Read it once.

Warning Current as of writing (Vulnetix CLI v3.55.2). Flags and default output paths change between releases. Check vulnetix <command> --help, and open an issue if a page here is stale.

Installing in CI

One command, on every platform that has a shell:

curl -fsSL https://cli.vulnetix.com/install.sh | sh

It installs to /usr/local/bin, falling back to $HOME/.local/bin when that is not writable. Pin a release in CI:

curl -fsSL https://cli.vulnetix.com/install.sh | sh -s -- --version v3.55.2

On minimal images, install the script’s dependencies first — alpine ships without curl, bash, tar, or CA certificates:

apk add --no-cache bash ca-certificates curl tar

Via Go, note the /v3 module suffix; the module cannot be fetched without it:

go install github.com/vulnetix/cli/v3@latest
Note There is no published Vulnetix container image. The repository has a Dockerfile for local builds, but nothing is pushed to a registry. Install the CLI into a standard base image, or bake your own image once and reuse it.

Authenticating in CI

Set two environment variables from your platform’s secret store. That is the whole setup.

VariableValue
VULNETIX_ORG_IDOrganization UUID
VULNETIX_API_KEYApiKey hex digest

Then, as the first step of the job:

vulnetix auth verify

It reads the credential, calls the API, exits non-zero on failure, and writes nothing.

Do not run vulnetix auth login on an ephemeral runner. Environment variables sit at the top of the credential precedence chain, persist nothing, and disappear with the job; a login step writes a plaintext credentials file into the workspace for no benefit.

Do not store an ApiKey in VULNETIX_API_TOKEN. That variable holds a Bearer token, outranks everything else, and an ApiKey sent as a bearer credential is rejected. See Authentication in CI/CD.

What Each Subcommand Writes

Results land under .vulnetix/ in the scanned directory whether or not you ask for a copy elsewhere. Each command uploads its own findings to Vulnetix automatically when authenticated.

CommandDefault result fileFormatExits 1 when
vulnetix sca.vulnetix/sbom.cdx.jsonCycloneDXa gate flag is passed and breached
vulnetix sast.vulnetix/sast.sarifSARIF--severity is met or exceeded
vulnetix secrets.vulnetix/sast.sarifSARIF--severity is met or exceeded
vulnetix containers.vulnetix/containers.sarifSARIF--severity is met or exceeded
vulnetix iac.vulnetix/sast.sarifSARIF--severity is met or exceeded
vulnetix license.vulnetix/sbom.cdx.jsonCycloneDX--severity is met or exceeded
vulnetix cbom.vulnetix/cbom.cdx.jsonCycloneDX (CBOM)--fail-on status is found
vulnetix aibom.vulnetix/ai-bom.cdx.jsonCycloneDX (AIBOM)never
vulnetix malscan.vulnetix/malscan.sarifSARIFany malware finding
vulnetix scan.vulnetix/sbom.cdx.json + .vulnetix/sast.sarifbothany passed gate is breached
Note The SARIF-producing scans write their file only when there are findings. A clean scan deliberately leaves no empty artifact behind, so an artifact-upload step must tolerate a missing file.

Choosing the Output Flag

Three different behaviours. Getting this wrong is the most common mistake in a CI config.

FlagCommandsBehaviour
-o / --outputscan, sca, sast, secrets, containers, iacRepeatable. Takes a path ending .cdx.json or .sarif, or the literals json-cyclonedx / json-sarif for stdout
--output-filecbom, aibom, malscanSingle path. On these commands -o selects the terminal format only (pretty, json, …)
(neither)licenseWrites .vulnetix/sbom.cdx.json. -o json-spdx prints SPDX 2.3 to stdout. Copy the file out to publish it
# Two artifacts from one pass
vulnetix scan -o dist/results.sarif -o dist/sbom.cdx.json

# CBOM and AIBOM take a different flag
vulnetix cbom --output-file dist/cbom.cdx.json

# license takes neither
vulnetix license && cp .vulnetix/sbom.cdx.json dist/licenses.cdx.json

--format / -f on the scan family is deprecated; use --output.

Quality Gates

Gates are opt-in. Without a gate flag the command reports findings and exits 0.

FlagFails the build when
--severity low|medium|high|criticalany finding meets or exceeds the threshold
--block-malwarea dependency is a known malicious package, or malscan finds malware in the installed bytes
--block-eola runtime or package dependency is end-of-life
--block-unpinneda direct dependency uses a version range instead of an exact pin
--exploits poc|active|weaponizedexploit maturity reaches the threshold
--version-lag Na dependency is within the N most recently published versions
--cooldown Na dependency version was published within the last N days
vulnetix scan --severity high --block-malware --block-eol --exploits active

Most CI systems have a way to report a breach without blocking the merge — GitLab’s allow_failure: true, Jenkins’ catchError, GitHub’s continue-on-error. Prefer that to lowering the gate.

Uploading Third-Party Artifacts

The scan subcommands upload themselves. upload exists for reports produced by other tools.

vulnetix upload --file reports/semgrep.sarif --format sarif
vulnetix upload --file reports/syft.spdx.json --format spdx
FlagPurpose
--filePath to one artifact. Optional — without it, .vulnetix/ is auto-discovered
--dirDirectory to scan for artifacts
--formatOverride auto-detection: cyclonedx, spdx, sarif, openvex, csaf_vex
--org-idOrganization UUID, when not using stored or environment credentials
--jsonMachine-readable result, for parsing a pipeline ID out of the output

A format the CLI does not recognise cannot be uploaded. govulncheck -json output, for instance, is not one of the five — emit SARIF instead (govulncheck -format sarif).

Pipeline Context Is Automatic

The CLI detects GitHub Actions and GitLab CI from their environment variables and attributes findings to the right repository, commit, branch, and merge/pull request without any flags. On other platforms it falls back to reading the local git checkout.

You never pass --org-id on a machine where the environment credentials are set.