Scan Command Reference

The scan command walks your project directory, parses package manifests locally, and queries the Vulnetix VDB API to identify vulnerable dependencies. No file contents are ever uploaded to any server. Results are saved to .vulnetix/ and printed to your terminal.

Credentials are optional. When no credentials are configured the community fallback is used automatically.

Usage

vulnetix scan [flags]
vulnetix scan status <scan-id> [flags]

Flags

FlagTypeDefaultDescription
--pathstring.Directory to scan
--depthint3Maximum recursion depth for file discovery
--excludestringArray-Exclude paths matching glob pattern (repeatable)
-o, --outputstringArray-Output target (repeatable): json-cyclonedx or json-sarif for stdout; file path (.cdx.json, .cdx, .bom.json, .sbom.json) for CycloneDX to file; file path (.sarif, .sarif.json) for SARIF to file. Multiple flags combine file outputs with pretty display.
-f, --formatstring-Deprecated — maps to --output json-cyclonedx. Use --output instead.
--concurrencyint5Max concurrent VDB queries
--no-progressboolfalseSuppress progress indicators
--pathsboolfalseShow full transitive dependency paths (npm, Python, Rust, Ruby, PHP, Go). Edges are built from locally installed packages (node_modules/, venv, vendor/, cargo metadata).
--no-exploitsboolfalseSuppress the detailed exploit intelligence section
--no-remediationboolfalseSuppress the detailed remediation section
--no-licensesboolfalseSkip license analysis during scan (license analysis runs by default)
--severitystring-Exit with code 1 if any vulnerability meets or exceeds this level: low, medium, high, critical. Severity is coerced from all available scoring sources (CVSS, EPSS, Coalition ESS, SSVC). Also gates on SAST findings.
--block-malwareboolfalseExit with code 1 when any dependency is a known malicious package.
--block-eolboolfalseExit with code 1 when a runtime or package dependency is end-of-life. Runtimes: Go, Node.js, Python, Ruby. Package-level checks activate when VDB has EOL data (404s are silently skipped).
--block-unpinnedboolfalseExit with code 1 when any direct dependency uses a version range (^, ~, >=) instead of an exact pin.
--exploitsstring-Exit with code 1 when exploit maturity reaches the threshold: poc (any public exploit), active (CISA/EU KEV / actively exploited), weaponized (in-the-wild only).
--results-onlyboolfalseOnly output when findings exist; completely silent when the scan is clean. Also suppresses exploit and remediation detail sections.
--version-lagint0Exit with code 1 when any dependency is within the N most recently published versions of that package (0 = disabled).
--cooldownint0Exit with code 1 when any dependency version was published within the last N days (0 = disabled, best-effort).
--sca-autofixboolfalseApply validated SCA fixes with the project package manager, then rescan to confirm. See SCA Autofix.
--sca-autofix-strategystringstableTarget strategy for --sca-autofix: stable, safest, or latest.
--sca-autofix-manifeststring-Restrict autofix edits to one manifest file; implies non-interactive manifest selection.
--sca-autofix-max-major-bumpint0Refuse autofix targets crossing more than N major versions.
--yesboolfalseNon-interactive autofix mode: auto-pick safe defaults and never prompt.
--evaluate-sastboolfalseEnable SAST analysis (exclusive mode — disables all other features not explicitly enabled)
--no-sastboolfalseSkip SAST (sast-kind) rules
--evaluate-scaboolfalseEnable SCA — package manifest analysis (exclusive mode)
--no-scaboolfalseSkip SCA — skip ordinary package manifests
--evaluate-licensesboolfalseEnable license analysis (exclusive mode)
--no-licensesboolfalseSkip license analysis
--evaluate-secretsboolfalseEnable secret detection rules (exclusive mode)
--no-secretsboolfalseSkip secret-detection SAST rules
--enable-containersboolfalseEnable container file analysis (exclusive mode)
--no-containersboolfalseSkip Dockerfile/OCI manifests and container SAST rules
--evaluate-iacboolfalseEnable IaC analysis (exclusive mode)
--no-iacboolfalseSkip HCL/Nix manifests and IaC SAST rules
--disable-default-rulesboolfalseSkip built-in default SAST rules (external --rule repos still loaded)
--list-default-rulesboolfalsePrint built-in SAST rules and exit
-R, --rulestringArray-External SAST rule repo in org/repo format (repeatable); fetched from GitHub or --rule-registry — see Custom Rule Repositories
--rule-registrystringhttps://github.comOverride default registry URL for all --rule repos
--dry-runboolfalseDetect files and parse packages locally, check memory, then exit — zero API calls
--from-memoryboolfalseReconstruct scan pretty output from .vulnetix/sbom.cdx.json without API calls
--fresh-exploitsboolfalseWith --from-memory: fetch latest exploit intel from API
--fresh-advisoriesboolfalseWith --from-memory: fetch latest remediation plans from API
--fresh-vulnsboolfalseWith --from-memory: re-fetch affected version checks and latest scoring from API
--reachabilitystringbothTree-sitter reachability mode: direct, transitive, both, or off. Per-finding source-level reachability analysis runs against every produced CVE. Disable globally with off for large monorepos. See the Reachability Analysis section.

Output Files

After every scan the following files are written under your project root:

PathDescription
.vulnetix/sbom.cdx.jsonCycloneDX 1.7 SBOM for all scanned packages
.vulnetix/sast.sarifSARIF 2.1.0 report from SAST analysis (written when any SAST sub-category runs)
.vulnetix/memory.yamlScan state record (timestamp, counts, git context)

Scan Status

Check the status of a previously submitted (legacy) remote scan.

vulnetix scan status <scan-id> [flags]
FlagTypeDefaultDescription
--pollboolfalsePoll until scan completes
--poll-intervalint5Polling interval in seconds
-o, --outputstringprettyOutput format: json, pretty

Package Scope Support

Vulnerabilities and packages are organised by dependency scope where the package manager provides that information:

Package ManagerScopes
npmproduction, development, peer, optional
Python (Pipfile)production, development
Python (requirements.txt)production
Goproduction (no scope distinction in go.mod / go.sum)
Rustproduction (no scope distinction in Cargo.lock)
Rubyproduction (group info requires Gemfile)
Maven / Gradleproduction, test, provided, runtime, system
Composerproduction, development
Yarn / pnpmproduction (scope requires correlation with package.json)
NuGetproduction
Swiftproduction
Pub (Dart)production, development
Hex (Elixir)production
sbt (Scala)production
CocoaPodsproduction
Conan (C/C++)production
vcpkg (C/C++)production

Supported Manifest Files

The scanner recognizes these package manager manifest and lock files:

JavaScript / TypeScript

FilenameEcosystemLock file?
package.jsonnpmNo
package-lock.jsonnpmYes
yarn.locknpmYes
pnpm-lock.yamlnpmYes

Python

FilenameEcosystemLock file?
pyproject.tomlPyPINo
requirements.txtPyPINo
requirements.inPyPINo
PipfilePyPINo
Pipfile.lockPyPIYes
poetry.lockPyPIYes
uv.lockPyPIYes

Go

FilenameEcosystemLock file?
go.modGoNo
go.sumGoYes

Rust

FilenameEcosystemLock file?
Cargo.tomlCargoNo
Cargo.lockCargoYes

Deno

FilenameEcosystemLock file?
deno.jsonDenoNo
deno.lockDenoYes

Ruby

FilenameEcosystemLock file?
GemfileRubyGemsNo
Gemfile.lockRubyGemsYes

Java / Kotlin / Scala

FilenameEcosystemLock file?
pom.xmlMavenNo
build.gradleMavenNo
build.gradle.ktsMavenNo
gradle.lockfileMavenYes
build.sbtMavenNo
build.lockMavenYes

C# / .NET

FilenameEcosystemLock file?
*.csprojNuGetNo
packages.lock.jsonNuGetYes
paket.dependenciesNuGetNo
paket.lockNuGetYes

PHP

FilenameEcosystemLock file?
composer.jsonComposerNo
composer.lockComposerYes

Swift / iOS

FilenameEcosystemLock file?
Package.swiftSwiftNo
Package.resolvedSwiftYes
PodfileCocoaPodsNo
Podfile.lockCocoaPodsYes
CartfileCarthageNo
Cartfile.resolvedCarthageYes

Dart

FilenameEcosystemLock file?
pubspec.yamlPubNo
pubspec.lockPubYes

Elixir

FilenameEcosystemLock file?
mix.exsHexNo
mix.lockHexYes

Erlang

FilenameEcosystemLock file?
rebar.configHexNo
rebar.lockHexYes

C / C++

FilenameEcosystemLock file?
vcpkg.jsonvcpkgNo
conanfile.txtConanNo
conanfile.pyConanNo
conan.lockConanYes
CMakeLists.txtCPMNo
CPM.cmakeCPMNo
meson.buildMesonNo

CMakeLists.txt is only recognized when the file contains CPMAddPackage.

Haskell

FilenameEcosystemLock file?
*.cabalCabalNo
cabal.project.freezeCabalYes
stack.yamlStackNo

OCaml

FilenameEcosystemLock file?
opamopamNo
*.opamopamNo

Nix

FilenameEcosystemLock file?
flake.nixNixNo
flake.lockNixYes

Julia

FilenameEcosystemLock file?
Project.tomlJuliaNo
Manifest.tomlJuliaYes

Crystal

FilenameEcosystemLock file?
shard.ymlCrystalNo
shard.lockCrystalYes

R

FilenameEcosystemLock file?
DESCRIPTIONCRANNo
renv.lockCRANYes

Zig

FilenameEcosystemLock file?
build.zig.zonZigNo

Bazel / Buck

FilenameEcosystemLock file?
MODULE.bazelBazelNo
WORKSPACEBazelNo
WORKSPACE.bazelBazelNo
BUCKBuckNo
BUCK2BuckNo

Containers

FilenameEcosystemLock file?
DockerfileDockerNo
ContainerfileDockerNo
*.dockerfileDockerNo
*.containerfileDockerNo

Infrastructure as Code

FilenameEcosystemLock file?
*.tfTerraformNo

CI/CD

FilenameEcosystemLock file?
.github/workflows/*.ymlGitHub ActionsNo
.github/workflows/*.yamlGitHub ActionsNo

Existing SBOMs

The scanner also detects and ingests existing SBOM documents:

  • SPDX JSON documents (identified by spdxVersion and SPDXID fields)
  • CycloneDX JSON documents (identified by bomFormat: "CycloneDX" and specVersion)

License Analysis

By default, vulnetix scan also runs license analysis on all discovered packages. License findings appear in the pretty output after the vulnerability summary and are stored in the CycloneDX BOM with source vulnetix-license-analyzer.

License resolution uses a multi-source pipeline (manifests, filesystem, container metadata, deps.dev, GitHub). See the License Command Reference for full details on resolution sources, evaluation rules, and conflict detection.

To skip license analysis:

vulnetix scan --no-licenses

Feature Control

By default, vulnetix scan runs all analysis categories: SCA, SAST (including secret detection, container rules, and IaC rules), and license analysis.

Enabling individual features (exclusive mode)

When any --evaluate-X flag is set, only the explicitly enabled categories run — everything else is disabled. This makes it easy to scope a scan to a single concern:

# SCA only (vulnerability analysis on package manifests)
vulnetix scan --evaluate-sca

# SAST only (general static analysis rules)
vulnetix scan --evaluate-sast

# Secret detection only
vulnetix scan --evaluate-secrets

# Container analysis only (Dockerfile/OCI rules)
vulnetix scan --enable-containers

# IaC analysis only (Terraform, Nix)
vulnetix scan --evaluate-iac

# License analysis only
vulnetix scan --evaluate-licenses

Disabling individual features

--no-X flags disable a specific category while leaving all others enabled:

# Run everything except license analysis
vulnetix scan --no-licenses

# Run everything except secret-detection rules
vulnetix scan --no-secrets

# Skip IaC files and rules
vulnetix scan --no-iac

# Skip containers
vulnetix scan --no-containers

# Skip all SAST-kind rules (but still run secrets/containers/IaC rules)
vulnetix scan --no-sast

Specialized scan commands

For convenience, dedicated top-level commands wrap common single-category scans:

CommandEquivalent
vulnetix scavulnetix scan --evaluate-sca --no-sast --no-secrets --no-containers --no-iac --no-licenses
vulnetix sastvulnetix scan --evaluate-sast --no-sca --no-secrets --no-containers --no-iac --no-licenses
vulnetix secretsvulnetix scan --evaluate-secrets --no-sast --no-sca --no-containers --no-iac --no-licenses
vulnetix containersvulnetix scan --enable-containers --no-sast --no-sca --no-secrets --no-iac --no-licenses
vulnetix iacvulnetix scan --evaluate-iac --no-sast --no-sca --no-secrets --no-containers --no-licenses

SAST (Static Application Security Testing)

By default, vulnetix scan also runs SAST analysis alongside SCA. SAST evaluates Rego-based rules against your source files to detect code-level security issues — weak cryptography, hardcoded credentials, missing lock files, insecure deserialization, and more.

SAST findings appear in the pretty output after the SCA summary and are written to .vulnetix/sast.sarif in SARIF 2.1.0 format. Each finding includes CWE, CAPEC, and MITRE ATT&CK technique mappings, plus stable fingerprints for tracking results across runs.

SAST rules are organized into four sub-categories that can be toggled independently:

Sub-categoryFlag to disableRule kindApplies to
Static analysis--no-sastsastGeneral code security rules
Secret detection--no-secretssecretsHardcoded credentials, API keys, tokens
Container rules--no-containersociDockerfile / Containerfile analysis
IaC rules--no-iaciacTerraform HCL, Nix files

Disabling SAST

# Skip all SAST-kind rules (secrets/containers/IaC still run)
vulnetix scan --no-sast

# Skip secret-detection rules specifically
vulnetix scan --no-secrets

# Skip all SAST entirely (all four sub-categories)
vulnetix scan --no-sast --no-secrets --no-containers --no-iac

# Skip built-in rules only (external rule repos still loaded)
vulnetix scan --disable-default-rules --rule myorg/my-rules

Listing Built-in Rules

Prints all all built-in rules with their IDs, names, severities, and language targets, then exit:

vulnetix scan --list-default-rules

External Rule Repos

Load additional Rego rules from Git repositories. See the Custom Rule Repositories guide for a full walkthrough including repository setup, rule authoring, and all flag combinations. Rules are fetched from GitHub by default or from a custom registry.

# Load rules from a GitHub repo
vulnetix scan --rule myorg/custom-rules

# Load multiple external rule repos
vulnetix scan --rule myorg/rules-a --rule myorg/rules-b

# Use a custom registry (e.g. GitLab or self-hosted Gitea)
vulnetix scan --rule myorg/rules --rule-registry https://gitlab.example.com

SAST Severity Gating

SAST findings participate in --severity gating alongside SCA vulnerabilities. When any SAST finding meets or exceeds the threshold, the scan exits with code 1:

# Exit 1 on high or critical SAST findings (or SCA vulnerabilities)
vulnetix scan --severity high

Built-in Rules

27 rules ship with the CLI. Run vulnetix scan --list-default-rules for full descriptions and CWE/CAPEC/ATT&CK mappings.

Cryptography

Rule IDSeverityNameLanguages
VNX-CRYPTO-001mediumMD5 usage detectedPython, Node, Go, Java, Ruby, PHP
VNX-CRYPTO-002mediumSHA-1 usage detectedPython, Node, Go, Java, Ruby, PHP

Container Security

Rule IDSeverityNameApplies to
VNX-DOCKER-001mediumDockerfile missing USER directiveDockerfile, Containerfile
VNX-DOCKER-002mediumDockerfile FROM :latest tagDockerfile, Containerfile

Go

Rule IDSeverityName
VNX-GO-001highMissing go.sum
VNX-GO-002highCommand injection via exec.Command

Java

Rule IDSeverityName
VNX-JAVA-001highCommand injection via Runtime.exec()
VNX-JAVA-002mediumSpring actuator endpoints exposed

Node.js

Rule IDSeverityName
VNX-NODE-001highMissing npm lock file
VNX-NODE-002higheval() or new Function() in JavaScript
VNX-NODE-003highCommand injection via child_process
VNX-NODE-004mediumExpress app without helmet
VNX-NODE-005mediuminnerHTML or dangerouslySetInnerHTML usage

PHP

Rule IDSeverityName
VNX-PHP-001highMissing composer.lock
VNX-PHP-002highDangerous function in PHP

Python

Rule IDSeverityName
VNX-PY-001highMissing Python lock file
VNX-PY-002higheval()/exec() usage in Python
VNX-PY-003highInsecure deserialization with pickle
VNX-PY-004highyaml.load() without SafeLoader
VNX-PY-005mediumWeak PRNG for security operations
VNX-PY-006mediumDjango DEBUG=True

Ruby

Rule IDSeverityName
VNX-RUBY-001highMissing Gemfile.lock
VNX-RUBY-002higheval() or system() in Ruby

Rust

Rule IDSeverityName
VNX-RUST-001highMissing Cargo.lock

Secrets & Credentials

Rule IDSeverityName
VNX-SEC-001criticalAWS access key ID
VNX-SEC-002criticalPrivate key committed
VNX-SEC-004criticalGitHub or GitLab token

SARIF Output

SAST results are always written to .vulnetix/sast.sarif. To write a combined SARIF report (SCA + SAST) to a custom path, use --output:

# Write combined SARIF to a file; pretty summary still goes to stdout
vulnetix scan --output results.sarif

# Write both CycloneDX and SARIF files alongside pretty output
vulnetix scan --output sbom.cdx.json --output results.sarif

The auto-written .vulnetix/sast.sarif contains SAST-only findings. The --output *.sarif file contains all scan findings (SCA + SAST) in SARIF format.

Auto-Discovery

The scanner walks the directory tree starting from --path up to --depth levels deep. It automatically skips common non-project directories:

  • node_modules, .git, .hg
  • __pycache__, .tox, .venv
  • vendor, .cargo

Use --exclude to skip additional paths by glob pattern.

Dependency graph from installed packages

After parsing manifests, the scanner also reads locally installed package directories to build a complete transitive dependency graph. This improves SBOM dependencies section accuracy and powers --paths output — no extra flags required.

EcosystemInstall directory
npmnode_modules/ (follows symlinks for pnpm)
Pythonvenv site-packages/*.dist-info/METADATA
Rustcargo metadata subprocess
Rubyvendor/bundle/ or GEM_HOME gemspec files
PHPvendor/*/composer.json
Gogo mod graph subprocess

If the install directory is not present, the scanner falls back to lock-file edge parsing where available.

Examples

Auto-discover and scan the current directory

vulnetix scan

Scan a specific project directory

vulnetix scan --path /path/to/project --depth 5

Exclude test fixtures and vendor directories

vulnetix scan --exclude "test/**" --exclude "vendor/**"

Emit CycloneDX JSON to stdout

vulnetix scan --output json-cyclonedx

Emit SARIF JSON to stdout

vulnetix scan --output json-sarif

Write CycloneDX to a file (pretty output still goes to stdout)

vulnetix scan --output /tmp/sbom.cdx.json

Write SARIF to a file (pretty output still goes to stdout)

vulnetix scan --output /tmp/results.sarif

Write both CycloneDX and SARIF files alongside pretty output

vulnetix scan --output /tmp/sbom.cdx.json --output /tmp/results.sarif

Raw CycloneDX JSON for scripting

vulnetix scan -o json-cyclonedx | jq '.components'

Suppress progress indicators (useful in CI without a TTY)

vulnetix scan --no-progress

Break the build on high or critical vulnerabilities

# Exit 1 if any high or critical vulnerability is found
vulnetix scan --severity high

# Exit 1 on any scored severity and emit a CycloneDX BOM
vulnetix scan --severity low -f cdx17

Gate on EOL runtimes and packages

# Exit 1 when a runtime or package dependency is end-of-life
vulnetix scan --block-eol

# Combine with severity gating
vulnetix scan --block-eol --severity high

Gate on version lag (supply chain freshness)

# Exit 1 if using the very latest published version of any dependency
vulnetix scan --version-lag 1

# Exit 1 if any dependency is within the 3 most recent releases
vulnetix scan --version-lag 3

Gate on recently published dependencies (cooldown period)

# Exit 1 if any dependency was published in the last 3 days
vulnetix scan --cooldown 3

# Combine multiple supply chain gates
vulnetix scan --block-malware --block-unpinned --version-lag 1 --cooldown 3 --severity high

Suppress output when clean (results-only mode)

# No output when scan is clean; table appears only when findings exist
vulnetix scan --results-only

SAST — list, disable, and load custom rules

# List all built-in SAST rules and exit
vulnetix scan --list-default-rules

# Skip all SAST-kind rules (general static analysis)
vulnetix scan --no-sast

# Skip secret detection
vulnetix scan --no-secrets

# Skip all SAST entirely (all four sub-categories)
vulnetix scan --no-sast --no-secrets --no-containers --no-iac

# Skip built-in rules but load a custom rule repo from GitHub
vulnetix scan --disable-default-rules --rule myorg/custom-rules

# Load additional rules on top of the built-in set
vulnetix scan --rule myorg/extra-rules

# Use a self-hosted registry for custom rules
vulnetix scan --rule myorg/rules --rule-registry https://git.example.com

Suppress extra sections

# Skip exploit intelligence and remediation details
vulnetix scan --no-exploits --no-remediation

Skip license analysis

vulnetix scan --no-licenses

Dry run (detect files, no API calls)

vulnetix scan --dry-run

Reconstruct results from previous scan

# From memory — no API calls
vulnetix scan --from-memory

# From memory with fresh exploit intel
vulnetix scan --from-memory --fresh-exploits

# From memory with fresh remediation plans
vulnetix scan --from-memory --fresh-advisories

Check scan status (legacy remote scan)

# One-shot check
vulnetix scan status abc123def

# Poll until complete
vulnetix scan status abc123def --poll --poll-interval 10

Org Quality Gate Policy

When you run a scan while authenticated and your organization has configured a Quality Gate, its settings are pulled in before the gate is evaluated and override the matching scan flag defaults — org policy always wins, even over a flag you pass explicitly. The override applies to --severity, --block-eol, --block-malware, --block-unpinned, --exploits, --version-lag, --cooldown, --sca-autofix-strategy, and --sca-autofix-max-major-bump. Settings the org left unset fall back to your flag or the builtin default.

Run with --verbose to see which settings were applied or superseded. Inspect the active policy with:

vulnetix config get quality-gate

Non-authenticated scans (no credentials, or the community fallback) have no organization to read from and use only the CLI flags you pass.

Exit Codes

CodeMeaning
0Scan completed successfully (no threshold breach)
1A gate was breached (--severity, --block-eol, --block-malware, --block-unpinned, --exploits, --version-lag, --cooldown), or a fatal error occurred