Skip to main content
CleanStart

Knowledge Hub

VEX Documents: Vulnerability Exploitability Exchange in CleanStart

Related Fundamentals: VEX documents address vulnerabilities across all container layers; see Vulnerability Across All Layers and understand the supply chain context in Library CVE Maintainer Dependency.

The following diagram illustrates the VEX document lifecycle from vulnerability detection through justification:

graph TD    A["Vulnerability<br/>Database"] -->|Scan| B["Container<br/>Image"]     B -->|Find| C["CVE-2024-5678<br/>OpenSSL"]     C -->|Analyze| D{Is Vulnerable<br/>Code<br/>Executed?}     D -->|No:<br/>Code Not<br/>Present| E["Status:<br/>not_affected"]    E -->|Justification| E1["vulnerable_code<br/>_not_present"]    E1 -->|Evidence| E2["Static Analysis<br/>Binary Search<br/>Confidence: 98%"]     D -->|No:<br/>Code Present<br/>But Not Called| F["Status:<br/>not_affected"]    F -->|Justification| F1["vulnerable_code<br/>_not_in_execute_path"]    F1 -->|Evidence| F2["Data Flow<br/>Analysis"]     D -->|No:<br/>Configuration<br/>Mitigates| G["Status:<br/>not_affected"]    G -->|Justification| G1["vulnerable_code<br/>_cannot_be_controlled<br/>_by_adversary"]    G1 -->|Evidence| G2["Config Review<br/>Privilege Check"]     D -->|Yes:<br/>Vulnerable| H["Status:<br/>affected"]    H -->|Action| H1["Upgrade to<br/>Fixed Version"]    H1 -->|Timeline| H2["Patch by<br/>Date X"]     D -->|Maybe| I["Status:<br/>unknown"]    I -->|Investigate| I1["Manual<br/>Review"]     E -->|Create| J["VEX<br/>Document<br/>OpenVEX Format"]    F -->|Create| J    G -->|Create| J    H -->|Create| J    I -->|Create| J     J -->|Filter| K["427 CVEs<br/>Detected"]     K -->|After VEX<br/>Filtering| L["23 CVEs<br/>Actually Relevant"]     L -->|Risk Based<br/>Triage| M["Focus on<br/>High Risk<br/>Vulnerabilities"]     style E fill:#ccffcc    style F fill:#ccffcc    style G fill:#ccffcc    style H fill:#ffcccc    style J fill:#99ccff    style M fill:#ffff99

Creating VEX Documents to Suppress False-Positive CVEs

VEX (Vulnerability Exploitability Exchange) documents provide critical context for vulnerability assessment. Rather than treating all known vulnerabilities equally, VEX lets organizations communicate whether a vulnerability actually impacts their product based on component usage, configuration, and deployment environment.

CleanStart generates context-aware VEX documents automatically during image scanning and build verification, eliminating manual triage work and enabling faster security decisions.

Why VEX Matters

A container image scanning report listing 427 vulnerabilities is overwhelming. Of those, 387 may not affect your deployed application at all. Traditional vulnerability management treats them equally; VEX eliminates false positives through provable context.

Scenario: Your image contains OpenSSL with CVE-2024-5678 (critical in server contexts). Your container runs a stateless image processor that never opens network sockets. VEX status: not_affected (affected component not executed). You can skip remediation and focus on actual risks.

CleanStart VEX Generation

Automatic VEX Creation

CleanStart generates VEX documents for every scanning operation. The scanning engine analyzes the component inventory for every package in every layer, resolves transitive dependencies that are actually used, performs code flow analysis to determine whether vulnerable code paths are executed, reviews configuration impact to identify runtime settings that mitigate exploitability, and considers environment context including network exposure, privilege levels, and resource access.

VEX Document Structure

CleanStart VEX documents follow OpenVEX format:

{  "@context": "https://openvex.dev/ns/v0.2.0",  "tooling": "CleanStart v2.0.0",  "statements": [    {      "vulnerability": {        "name": "CVE-2024-5678",        "aliases": ["GHSA-xxxx-yyyy-zzzz"]      },      "timestamp": "2025-10-04T14:32:00Z",      "products": [        {          "identifier": "cleanstart-api:2.0.0",          "identifiers": {            "sbom": "sha256:abc123..."          }        }      ],      "status": "not_affected",      "justification": "vulnerable_code_not_present",      "impact_statement": "OpenSSL library included but vulnerable function __parse_cert_extensions() not called in binary.",      "evidence": {        "source": "static_analysis",        "confidence": 0.98      }    },    {      "vulnerability": {        "name": "CVE-2024-9999"      },      "status": "affected",      "products": [        {          "identifier": "cleanstart-api:2.0.0"        }      ],      "affected_range": "< 1.2.3",      "fixed_range": ">= 1.2.3",      "action_statement": "Upgrade PostgreSQL from 1.2.1 to 1.2.3"    }  ]}

VEX Status Values

Status

Meaning

When to Use

not_affected

Vulnerability does not impact product

Vulnerable package present but code path unreachable

affected

Vulnerability impacts product

Code is executed and exploitable

fixed

Vulnerability fixed in newer version

Upgrade available and recommended

under_investigation

Status being determined

Pending deep code analysis results

Justifications for "not_affected"

CleanStart VEX includes detailed justifications explaining why a vulnerability doesn't impact your build:

vulnerable_code_not_present  → The vulnerable function is not called vulnerable_code_not_in_execute_path  → Code exists but runtime conditions prevent execution vulnerable_code_in_deactivated_functionality  → Feature containing vulnerability is disabled vulnerable_code_in_compile_time_feature_not_enabled  → Optional feature not compiled in vulnerable_code_cannot_be_controlled_by_adversary  → Input validation prevents exploit vulnerable_code_cannot_be_reached_by_user_supplied_input  → Vulnerable code uses only internal data component_not_present  → Dependency not actually included in image product_as_used_by_consumer_not_vulnerable  → Consumer's usage pattern blocks exploit

Image-Specific VEX Consumption

Vulnerability Triage with VEX

# Get VEX for scanned imagecleanimg-init --image myapp:1.0.0 --vex-output triage.vex # Filter to only "affected" statusjq '.statements[] | select(.status == "affected")' triage.vex # Display impact statementsjq '.statements[] | select(.status == "affected") |  {cve: .vulnerability.name, action: .action_statement}' triage.vex

Output shows actionable items only—in this example, three CVEs requiring attention out of 427 total.

Integration with Scanning Tools

CleanStart VEX integrates with standard vulnerability scanners:

# Syft generates SBOM; CleanStart adds VEXsyft myapp:1.0.0 --output json > sbom.jsoncleanimg-init --sbom sbom.json --output-vex enriched.vex # Grype consumes VEX for enhanced reportinggrype myapp:1.0.0 --add-cpes-if-missingcat enriched.vex | grype --template json > final_report.json

Building for VEX Compliance

Code Path Analysis

CleanStart uses static analysis and dynamic tracing to identify which vulnerable code is actually executed:

FROM alpine:3.19RUN apk add --no-cache openssl=3.1.4-r5COPY app /appCMD ["/app/process-files"]

Analysis result: OpenSSL CVE-2024-5678 (certificate parsing) → not_affected (no TLS in process-files). OpenSSL CVE-2024-9012 (encryption) → affected (AES-256 used in file processing).

Minimal Base Images Reduce VEX Burden

Using distroless or minimal images automatically improves VEX status:

# Before: Debian baseFROM debian:bookwormRUN apt-get install -y curl wget git openssh-client vimCOPY app /app# VEX: 200+ packages included, many unused → high vulnerability burden # After: Alpine or distrolessFROM gcr.io/distroless/base-debian12COPY --from=builder /app /app# VEX: 12 packages total, all required → cleaner VEX report

VEX for Compliance Reporting

FedRAMP Vulnerability Assessment

VEX documents satisfy FedRAMP requirements by providing evidence of vulnerability assessment and risk acceptance decisions:

{  "vulnerability": {    "name": "CVE-2024-2222"  },  "status": "not_affected",  "justification": "vulnerable_code_cannot_be_controlled_by_adversary",  "impact_statement": "Remote code execution requires administrator privileges; application runs as unprivileged user with no privilege escalation vectors.",  "evidence": {    "source": "runtime_monitoring",    "confidence": 0.95,    "timestamp": "2025-10-04T16:45:00Z"  },  "compliance_note": "Assessed against FedRAMP IA-4 (Access Control) and SI-2 (Flaw Remediation)"}

EU CRA Vulnerability Documentation

CleanStart VEX satisfies EU Cyber Resilience Act requirements to document known vulnerability status:

cleanimg-init --compliance eu-cra --output-vex cra-compliance.vex# Includes:# - Vulnerability severity and CVSS score# - Impact statement for non-technical stakeholders# - Remediation timeline and status# - Evidence of vulnerability assessment

Advanced VEX Features

Transitive Dependency Analysis

VEX doesn't just analyze direct dependencies:

{  "vulnerability": {    "name": "CVE-2024-3333"  },  "products": [    {      "identifier": "myapp:1.0.0",      "dependency_chain": [        "myapp → api-client v2.1.0",        "api-client → http-library v5.0.0",        "http-library → openssl v3.1.4"      ]    }  ],  "status": "not_affected",  "justification": "vulnerable_code_not_in_execute_path",  "impact_statement": "Vulnerable OpenSSL function only called by TLS 1.0 cipher negotiation. Application enforces TLS 1.3 minimum."}

Time-Sensitive VEX

VEX statements include temporal context for change management:

{  "vulnerability": {    "name": "CVE-2024-4444"  },  "status": "affected",  "action_statement": "Upgrade required by 2025-12-15 (90 days from disclosure)",  "deployment_windows": [    {      "environment": "staging",      "deadline": "2025-11-15"    },    {      "environment": "production",      "deadline": "2025-12-15"    }  ]}

VEX Best Practices

Generate VEX for Every Build

Make VEX generation part of your CI/CD pipeline:

scan:  stage: verify  script:    - cleanimg-init --scan --output-vex vex-report.json    - cleanimg-init --vex vex-report.json --validate-compliance fips,feds  artifacts:    paths:      - vex-report.json

Publish VEX Alongside Artifacts

Include VEX with container image metadata:

# Store VEX with imagecosign attach attestation myapp:1.0.0 --attestation vex-report.json --type vex # Retrieve VEX during deploymentcosign verify-attestation myapp:1.0.0 --type vex | jq .

Review VEX for "affected" Status Only

Establish clear processes for remediating VEX "affected" vulnerabilities:

# Extract action itemscat vex-report.json | jq '  .statements[]  | select(.status == "affected")  | {      cve: .vulnerability.name,      severity: .severity,      action: .action_statement,      deadline: .deployment_windows[0].deadline    }' | sort_by(.deadline)

Troubleshooting VEX Generation

Missing Vulnerability Context

If VEX shows "under_investigation" for many vulnerabilities:

# Run with increased analysis depthcleanimg-init --scan --analysis-depth=deep --output-vex report.vex # Enable dynamic tracingcleanimg-init --scan --trace-runtime --output-vex report.vex

Confidence Scores Below Threshold

VEX confidence below 0.85 indicates uncertain analysis:

# Filter low-confidence statementscat report.vex | jq '.statements[] | select(.evidence.confidence < 0.85)' # Manual review required for security decisions

See Also

SBOM Integration: spdx-sbom.md — VEX pairs with SBOM for complete vulnerability context. Image Signing: image-signing-sigstore.md — Sign VEX documents for authenticity. Compliance Reporting: fedramp-high.md — Using VEX for regulatory compliance.