Your scanner found 300 CVEs. Which ones actually matter? Vens takes a Trivy or Grype report, combines it with a description of your system (exposure, data sensitivity, compliance, security controls), and scores every CVE based on its real risk to you β not just its generic severity.
The output is a CycloneDX VEX file with OWASP Risk Rating scores.
π Read the full documentation β
New to Vens? Start with the 5-minute quickstart or learn how to prioritize a CVE backlog.
Traditional scanners treat all vulnerabilities the same. Vens analyzes each CVE in your specific context to calculate real risk:
Risk = Likelihood Γ Impact (0-81 scale)
Illustrative example:
| Scenario | CVSS (Generic) | OWASP (Contextual) | Why? |
|---|---|---|---|
| Generic RCE in a library whose vulnerable path is not executed | 8.8 HIGH | 10.0 LOW β¬οΈ | Not reachable in your runtime |
| Info leak in a PII handler running under GDPR | 5.3 MEDIUM | 52.0 HIGH β¬οΈ | PII leak + compliance impact |
Scores above are illustrative β actual scores depend on your config.yaml and the LLM model.
Result: Fix what actually matters in YOUR system.
Standalone:
go install github.com/venslabs/vens/cmd/vens@latesttrivy plugin install github.com/venslabs/vens# 1. Set up LLM (OpenAI shown β Anthropic, Google AI, or local Ollama also supported)
export OPENAI_API_KEY="sk-..."
export OPENAI_MODEL="gpt-4o"
# 2. Scan with Trivy or Grype
trivy image python:3.11-slim --format json --output report.json
# or
grype python:3.11-slim --output json --file report.json
# 3. Pin a stable per-service UUID (reuse across runs, do not regenerate each time)
SBOM_UUID="urn:uuid:$(uuidgen | tr '[:upper:]' '[:lower:]')"
# 4. Generate contextual risk scores
vens generate --config-file config.yaml --sbom-serial-number "$SBOM_UUID" report.json output.vex.json
# 5. Optionally fold the OWASP ratings back into the Trivy report
vens enrich --vex output.vex.json report.jsonOutput is a CycloneDX VEX document; each vulnerability carries an OWASP rating:
{
"vulnerabilities": [{
"id": "CVE-XXXX-YYYY",
"source": { "name": "NVD", "url": "https://nvd.nist.gov/vuln/detail/CVE-XXXX-YYYY" },
"ratings": [{
"method": "OWASP",
"score": 52.0,
"severity": "high",
"vector": "SL:7/M:7/O:7/S:7/ED:6/EE:6/A:6/ID:3/LC:7/LI:7/LAV:7/LAC:7/FD:7/RD:7/NC:7/PV:7"
}]
}]
}The per-CVE reasoning from the LLM is logged to stderr as the command runs, and is captured alongside prompts/responses when you pass --debug-dir <path>. It is intentionally not embedded in the VEX file to keep the document strictly CycloneDX-compliant.
Create config.yaml:
project:
name: "my-api"
description: "Customer-facing REST API"
context:
exposure: "internet" # internal | private | internet
data_sensitivity: "high" # low | medium | high | critical
business_criticality: "high" # low | medium | high | critical
compliance_requirements: ["GDPR", "SOC2"]
controls:
waf: trueLLM Providers:
| Provider | Environment Variable |
|---|---|
| OpenAI (recommended) | OPENAI_API_KEY |
| Anthropic | ANTHROPIC_API_KEY |
| Ollama (local) | OLLAMA_MODEL |
| Google AI | GOOGLE_API_KEY |
Generate VEX with contextual OWASP scores:
vens generate --config-file config.yaml INPUT OUTPUTSupported scanners:
- β Trivy - Auto-detected from JSON report format
- β Grype - Auto-detected from JSON report format
Key flags:
--config-file(required) - Path to config.yaml--input-format- Scanner format:auto|trivy|grype(default:auto)--llm- LLM provider:openai|anthropic|ollama|googleai(default:auto)--llm-batch-size- CVEs per request (default:10)--debug-dir- Save prompts/responses for debugging
Apply VEX scores to your Trivy report:
vens enrich --vex output.vex.json report.json- π Full Documentation β installation, guides, reference
- 5-minute Quickstart β your first VEX
- Prioritize a CVE backlog β the common use case
- CVSS vs OWASP contextual β why the scores move
- Complete Example - 107 real CVEs comparison
- Trivy Plugin Guide - Plugin usage
Contributions are welcome. See CONTRIBUTING.md for the full contributor guide: development setup, coding standards, testing with the mock LLM, commit conventions, and the review process.
Quick start for contributors:
- Good first issue? Look for the
good first issuelabel. - Bug report? Open an issue with the exact command, your
vens --version, and (if possible) redacted--debug-diroutput. - Bigger change? Open an issue first so we can agree on scope before you write the code.
- Security report? See SECURITY.md β please do not open public issues for vulnerabilities.
Apache License 2.0 - See LICENSE
Focus on what matters. Patch smarter, not harder.