Go-based CLI vulnerability scanner powered by Vulners, using go-vulners as the intelligence backend.
Designed for Security Engineers, CI/CD pipelines, and AI agents needing deterministic JSON output.
brew install kidoz/vulners/vulners-cligo install github.com/kidoz/vulners-cli/cmd/vulners@latestDownload binaries from GitHub Releases.
docker build -t vulners .
docker run --rm -e VULNERS_API_KEY vulners scan repo /src
# Or mount a local project:
docker run --rm -e VULNERS_API_KEY -v "$(pwd):/src" vulners scan repo /srcSet your Vulners API key as an environment variable:
export VULNERS_API_KEY=your-api-key-hereSee .env.example for a template. Get an API key at vulners.com.
Documentation is organized with the Diátaxis framework:
- Tutorials — learn by doing
- How-to guides — complete a specific task, such as GitHub Actions or GitLab CI
- Reference — commands, flags, formats, and exit codes
- Explanation — how scanning works and why
Start at docs/README.md.
# Search the Vulners database
vulners search "apache log4j"
vulners search "type:exploit AND apache" --limit 20
vulners search "log4j" --exploits # search exploits only
# Look up a specific CVE
vulners cve CVE-2021-44228
vulners cve CVE-2021-44228 --references # include external references
vulners cve CVE-2021-44228 --history # include change history
# Search by CPE
vulners cpe chrome --vendor google
vulners cpe nginx --limit 20 # vendor defaults to product name
# Export STIX bundle
vulners stix CVE-2021-44228 # auto-detects CVE prefix
vulners stix RHSA-2021:5137 # by bulletin ID
vulners stix CVE-2021-44228 --by-cve # explicit CVE lookup
# Autocomplete and suggestions
vulners autocomplete "apache log" # search query autocomplete
vulners suggest type # field value suggestions# Audit Linux packages
vulners audit linux --distro ubuntu --version 22.04 --pkg openssl=3.0.2 --pkg curl=7.81.0
# Audit libraries by Package URL (PURL)
vulners audit library pkg:npm/lodash@4.17.20 pkg:golang/golang.org/x/crypto@0.5.0
# Audit Windows KB updates
vulners audit windows --kb KB5034441 --kb KB5034439
# Host audit (v4 API -- packages in "name version" format)
vulners audit host --os ubuntu --version 22.04 --packages "openssl 3.0.2" --packages "curl 7.81.0"
# Resolve free-form software descriptions and audit the matched products
vulners audit smart --software "Adobe Reader 5.3" --software "OpenSSL 1.0.1" --catalog official
# The official catalog is used by default; pass --catalog extended to include the extended catalog
# Full Windows audit (KBs + software)
vulners audit winaudit --os "Windows 10" --version "19045" --kb KB5034441 --software "Firefox 121.0"# Scan a local or remote host (agentless via SSH or WinRM)
vulners scan host local
vulners scan host ssh://user@192.168.1.10 --ask-pass
vulners scan host ssh://user@192.168.1.10 --identity-file ~/.ssh/id_rsa
vulners scan host winrms://Administrator@192.168.1.20 --password-env WIN_PASS
# Scan a Go repository (reachability-aware via govulncheck)
vulners scan repo .
vulners scan repo /path/to/project
# Scan a directory for package manifests
vulners scan dir .
# Scan a CycloneDX SBOM
vulners scan sbom sbom.json --format cyclonedx
# Scan an SPDX SBOM
vulners scan sbom sbom.spdx.json --format spdx
# Scan a container image
vulners scan image alpine:3.18
vulners scan image ubuntu:22.04 --distro ubuntu/22.04 # override distro detectionImage scanning automatically detects the OS distribution and uses specialized APIs for accurate matching:
- OS packages (apk/deb/rpm) are matched via the
LinuxAuditAPI with distro-aware version comparison - Application packages are matched via the
SBOMAuditAPI with CVSS, EPSS, AIScore, and exploit enrichment - Output includes
imageMetawith distro info, package breakdown, and audit mode
# Webhooks — get notified when new bulletins match a query
vulners webhook list
vulners webhook add "type:exploit AND apache"
vulners webhook read <webhook-id>
vulners webhook enable <webhook-id>
vulners webhook disable <webhook-id>
vulners webhook delete <webhook-id>
# Subscriptions — managed alert rules
vulners subscription list
vulners subscription create --name "Log4j alerts" --type email --query "log4j"
vulners subscription get <subscription-id>
vulners subscription enable <subscription-id>
vulners subscription disable <subscription-id>
vulners subscription delete <subscription-id># Account-level vulnerability reports
vulners report summary # aggregated vulnerability summary
vulners report vulns --limit 50 # list known vulnerabilities
vulners report hosts # host vulnerability status
vulners report scans # scan history
vulners report ips # IP-level summaryRun vulners-cli as a Model Context Protocol server for AI agent integration:
vulners mcpExposes tools for search, CVE lookup, CPE search, Go repo scanning, SBOM audit, smart software audit, and health checks to MCP-compatible clients (Claude Desktop, Cursor, etc.).
# Sync vulnerability data for offline use
vulners offline sync --collections cve,debian
# Allow more time for large collection downloads (still buffered in memory)
VULNERS_HTTP_TIMEOUT=10m vulners offline sync --collections debian
# Check offline database status
vulners offline status
# Purge offline database
vulners offline purge
# Use offline data with any supported command
vulners scan repo . --offline
vulners scan dir . --offline
vulners cve CVE-2021-44228 --offline
vulners search "log4j" --offlineNote: Large collections (
cve,ubuntu,debian) are served as CDN-cached downloads that can exceed the default 50 MiB response limit. To sync them, raise the limit viaVULNERS_MAX_RESPONSE_SIZE(bytes):# 512 MiB is enough for the full cve collection (~370k bulletins) export VULNERS_MAX_RESPONSE_SIZE=536870912 vulners offline sync --collections cve
# Print version, commit, build date, and Go version
vulners version
# Check environment health
vulners doctorversion reports the binary's build metadata (version, commit, build date, Go version). Use --output json for machine-readable results.
doctor verifies API key, network connectivity, offline cache, and Go installation. Use --output json for machine-readable results.
# JSON (default)
vulners scan repo . --output json
# Human-readable table
vulners scan repo . --output table
# SARIF (for GitHub Code Scanning, IDE integration)
vulners scan repo . --output sarif
# HTML report
vulners scan repo . --output html
# CycloneDX VEX
vulners scan repo . --output cyclonedx
# Markdown (human-readable, portable)
vulners scan repo . --output markdown
# Write to file instead of stdout
vulners scan repo . --output sarif --output-file results.sarifNote:
sarif,html, andcyclonedxformats are only available for scan commands. Intel, audit, STIX, and offline commands supportjson,table, andmarkdown.
# Machine-friendly mode: JSON, quiet, deterministic ordering, no color
vulners scan repo . --agent
# Select specific JSON fields
vulners scan repo . --fields findings.vulnID,findings.severity,summary
# Summary + top 5 findings only (smaller payloads for LLM context)
vulners scan repo . --summary-only
# Limit findings count (preserves total count in output)
vulners scan repo . --max-findings 20
# Dry-run: show what a scan would do
vulners scan repo . --plan
# Command specification for tool integration
vulners spec
vulners spec --schema scan# Fail if findings at or above severity
vulners scan repo . --fail-on high
vulners scan repo . --fail-on critical
# Ignore specific CVEs
vulners scan repo . --ignore CVE-2021-44228 --ignore CVE-2023-0001
# Suppress findings using an OpenVEX document
vulners scan repo . --vex vex.jsonOpenVEX statements must include products. Suppression applies only when a product matches the scanned component's PURL, CPE, or name@version reference. Go, Python, SBOM, npm lockfile, and VEX inputs are limited to 64 MiB per file. Manifest inventories are capped at 10,000 components, and online component matching is capped at 1,000 API search requests per scan. Host and web scans use the same policy and scan report structure; their --plan modes do not execute scans.
| Exit code | Meaning |
|---|---|
| 0 | No findings above threshold |
| 1 | Findings above threshold |
| 2 | Usage or configuration error |
| 3 | Runtime error |
--fail-on, --ignore, and --vex apply to scan commands only. Audit commands return API results without scan policy filtering.
| Flag | Description |
|---|---|
--output |
Output format: json, table, sarif, html, cyclonedx, markdown (default: json) |
--output-file |
Write output to file instead of stdout |
--quiet / -q |
Suppress non-error output |
--verbose / -v |
Enable debug output |
--offline |
Use offline database only |
--agent |
Machine-friendly mode: JSON output, quiet, deterministic sort, no color |
--no-color |
Disable colored log output |
--fail-on |
Fail with exit code 1 at severity: low, medium, high, critical |
--ignore |
CVE IDs to ignore (repeatable) |
--vex |
Path to an OpenVEX document for finding suppression |
--fields |
Select JSON fields to include in output (repeatable, JSON only) |
--summary-only |
Output summary and top findings only |
--max-findings |
Maximum findings in output; 0 = unlimited (default: 0) |
--plan |
Show what a scan would do without executing it |
vulners-cli can be configured via a YAML file at ~/.vulners/config.yaml. On Unix systems, this file must use mode 0600; group- or world-readable config files are rejected because they may contain an API key.
api_key: your-api-key-here
verbose: false
quiet: false
offline: false
# http_timeout: 10m # per-request timeout; default 120s
# max_response_size: 536870912 # bytes; raise to sync large offline collectionsConfiguration precedence (highest wins): CLI flags > environment variables > config file > defaults.
Environment variables use the VULNERS_ prefix (e.g. VULNERS_API_KEY, VULNERS_VERBOSE). Recognized env vars:
| Variable | Type | Notes |
|---|---|---|
VULNERS_API_KEY |
string | Required for most commands |
VULNERS_DB_PATH |
string | Offline cache database path |
VULNERS_VERBOSE / VULNERS_QUIET |
bool (true/false/1/0) |
Log verbosity |
VULNERS_OFFLINE |
bool | Force offline mode |
VULNERS_ENABLE_AI_SCORE |
bool | Fetch AI enrichment scores |
VULNERS_HTTP_TIMEOUT |
duration (e.g. 10m) |
Per-request Vulners API timeout, including offline downloads. Zero / unset keeps 120s; negative values are rejected. |
VULNERS_MAX_RESPONSE_SIZE |
int (bytes) | Raise the HTTP response-body limit (default 50 MiB). Needed to sync large offline collections (cve, ubuntu, debian). Non-positive / unset keeps the default. |
VULNERS_CONFIG |
string | Override the config file path |
# Build
just build
# Run tests (with race detector)
just test
# Run live SBOM/web API tests (requires VULNERS_API_KEY; sends test fixtures)
just test-integration
# Run linter
just lint
# Format code
just fmt
# Remove build artifacts
just clean- Go >= 1.26
- just task runner
- golangci-lint v2
- gofumpt
cmd/vulners/main.go Fx wiring, Kong parse, logger init
internal/cmd/ Kong command structs
internal/config/ Koanf v2 config loader
internal/intel/ go-vulners wrapper + govulncheck
internal/cache/ SQLite offline cache (modernc.org/sqlite)
internal/inventory/ go.mod, npm, pip, CycloneDX/SPDX, syft parsers
internal/matcher/ Component normalization + vuln matching + enrichment
internal/policy/ --fail-on / --ignore / VEX filtering + exit codes
internal/report/ JSON, table, SARIF, HTML, CycloneDX output
internal/model/ Component, Finding, ExitCode, SeverityLevel
See SECURITY.md for the vulnerability disclosure policy.
MIT -- see LICENSE for details.