VulnScout is designed to analyse and identify vulnerabilities in their software components and dependencies using an SBOM (Software Bill Of Materials).
It pulls known vulnerabilities from public sources like the NVD, EPSS, and Grype to figure out which parts of a codebase might be affected by security issues (CVE).
VulnScout also provides a web interface for visualisation and a command line to generate enriched output files.
-
Analyse SBOMs (SPDX 2/3, CycloneDX, Yocto CVE check, OpenVEX, Grype)
-
Detect and enrich vulnerabilities from NVD, EPSS, and Grype
-
Manage projects and variants for multi-target builds
-
Web interface for visualisation, triage, and assessment
-
Non-interactive / CI mode with configurable match conditions
-
Generate customisable reports (AsciiDoc, HTML, PDF, CSV)
-
Export enriched SBOMs (SPDX 3.0, CycloneDX 1.6, OpenVEX)
-
Custom CVSS scoring per vulnerability
-
Time estimation tracking for remediation effort
VulnScout is designed to run locally in a Docker container.
It only requires docker to be installed and running on your host.
To install VulnScout, you only need to clone the repository:
git clone https://github.com/savoirfairelinux/vulnscout.git
cd vulnscoutThis project contains default examples of VulnScout.
To run VulnScout demo in interactive mode, you can simply run the command:
./vulnscout --serve --add-spdx $(pwd)/example/spdx3/core-image-minimal-qemux86-64.rootfs.spdx.json \
--add-cve-check $(pwd)/example/spdx3/core-image-minimal-qemux86-64.rootfs.jsonThen open your browser to view the results:
http://localhost:7275If you donβt need additional source files, VulnScout can be rerun directly without any additional arguments:
./vulnscout --serveIt is also possible to add sources files on a specific project and variant with the --project and --variant arguments:
./vulnscout --project demo --variant x86 --add-spdx $(pwd)/example/spdx3/core-image-minimal-qemux86-64.rootfs.spdx.json \
--add-cve-check $(pwd)/example/spdx3/core-image-minimal-qemux86-64.rootfs.jsonFull documentation is available in the doc/ directory as a Sphinx project.
Install the required Python packages:
pip install sphinx myst-parser sphinx-rtd-themeThen build the HTML documentation:
make -C doc htmlThe generated pages are in doc/build/html/. Open doc/build/html/index.html in your browser.
The vulnscout script manages the container lifecycle. The container runs in the background and accepts commands via docker exec.
# Start the container (done automatically by most commands)
./vulnscout start
# Stop and remove the container
./vulnscout stop
# Restart the container (useful after changing config)
./vulnscout restartVulnScout organises data into projects and variants. A project typically maps to a product, and variants represent different builds or architectures (e.g. x86_64, aarch64).
Both flags are optional and default to default if not provided.
./vulnscout --project <name> --variant <name> <command>VulnScout accepts multiple input file types. Commands can be chained and will automatically trigger a scan.
# SPDX 2/3 SBOM (JSON, tag-value, or .tar/.tar.gz/.tar.zst archive)
./vulnscout --add-spdx <path>
# Yocto CVE check JSON output
./vulnscout --add-cve-check <path>
# CycloneDX file
./vulnscout --add-cdx <path>
# OpenVEX file
./vulnscout --add-openvex <path>
# Grype file
./vulnscout --add-grype <path>Multiple inputs can be chained in a single command:
./vulnscout --project demo --variant x86 \
--add-spdx /path/to/sbom.spdx.json \
--add-cve-check /path/to/cve-check.json \
--add-openvex /path/to/assessments.openvex.json|
Tip
|
|
We have a dedicated layer for VulnScout integration in Yocto.
You can find the layer here: https://github.com/savoirfairelinux/meta-vulnscout
To be short, a simple inherit vulnscout in your image recipe will be enough to configure vulnscout for your project.
The vulnscout web interface can be started with a bitbake <image-recipe> -c vulnscout command.
The web interface includes a Settings tab that provides:
-
Rename Project β Select a project and give it a new name (must be unique across all projects).
-
Rename Variant β Select a variant within a project and rename it (must be unique within the project).
-
Import SBOM β Upload an SBOM file directly from the browser instead of using CLI flags like
--add-spdxor--add-cve-check. When importing, you must select (or create) the target project and variant. Supported formats are auto-detected or can be specified explicitly: SPDX (2/3), CycloneDX, OpenVEX, Yocto CVE check, and Grype.
If you want to use the non-interactive mode, without the web interface, you can use the command with the --match-condition argument:
./vulnscout --project demo --match-condition "((cvss >= 9.0 or (cvss >= 7.0 and epss >= 30%)) and (pending == true or affected == true))"The command exits with code 2 if any vulnerability matches the condition, enabling use in CI pipelines.
See the match conditions documentation for the full condition syntax and token reference.
You can combine inputs with a match condition in a single invocation:
./vulnscout --project demo \
--add-spdx /path/to/sbom.spdx.json \
--add-cve-check /path/to/cve-check.json \
--match-condition "((cvss >= 9.0) and (pending == true or affected == true)) "VulnScout can run Grype on the current database contents. This exports the current state as a CycloneDX SBOM, runs Grype against it, and merges the results back:
./vulnscout --project demo --variant x86 --perform-grype-scanThis can be chained with other inputs to scan newly added files immediately:
./vulnscout --project demo --add-spdx example/spdx3/core-image-minimal-qemux86-64.rootfs.spdx.json --perform-grype-scanReports are generated from AsciiDoc templates. VulnScout ships with built-in templates and also supports custom ones.
# Generate a report from a built-in template
./vulnscout --project demo --report summary.adoc
# Generate a match-condition report (lists vulnerabilities that triggered the condition)
./vulnscout --project demo --match-condition "cvss >= 9.0" --report match_condition.adoc
# Register a custom template permanently in the container and generate a report from it
./vulnscout --report /path/to/my-custom-report.adoc
# Then generate a report from it by name
./vulnscout --project demo --report my-custom-report.adoc
# Or pass the file path directly β registers and runs it in one step
./vulnscout --project demo --report /path/to/my-custom-report.adocMultiple reports can be generated in one command:
./vulnscout --project demo --report summary.adoc --report all_assessments.adocReports are written to the outputs directory (default: .vulnscout/outputs/).
See the report templates documentation for documentation on writing custom report templates.
VulnScout can export the enriched project data as standard SBOM formats. Exported files are written to the outputs directory (default: .vulnscout/outputs/).
# Export as SPDX 3.0 SBOM
./vulnscout --project demo --export-spdx
# Export as CycloneDX 1.6 SBOM
./vulnscout --project demo --export-cdx
# Export as OpenVEX document (vulnerabilities + assessments)
./vulnscout --project demo --export-openvexExport commands can be chained with inputs and reports in a single invocation:
./vulnscout --project demo \
--add-spdx /path/to/sbom.spdx.json \
--add-cve-check /path/to/cve-check.json \
--export-spdx --export-cdx --export-openvex \
--report summary.adocVulnScout lets you export and re-import the assessments you have manually created through the web interface (review / triage decisions). This is useful for:
-
Backing up your review work before re-importing SBOMs.
-
Sharing assessment decisions across different VulnScout instances.
-
Restoring triage state in CI pipelines after a database reset.
The --export-custom-assessments flag produces a .tar.gz archive containing one OpenVEX JSON file per variant. The archive is written to the outputs directory (default: .vulnscout/outputs/).
./vulnscout --project demo --export-custom-assessmentsThe --import-custom-assessments flag reads a .json or .tar.gz file and replays the assessment statements into the database, matching them to existing vulnerabilities and packages.
# Import from a single OpenVEX JSON file
./vulnscout --project demo --import-custom-assessments /path/to/assessments.json
# Import from a tar.gz archive previously exported
./vulnscout --project demo --import-custom-assessments /path/to/custom_assessments.tar.gzBoth commands can be combined with other flags:
./vulnscout --project demo \
--add-spdx /path/to/sbom.spdx.json \
--import-custom-assessments /path/to/custom_assessments.tar.gz \
--export-spdx --report summary.adocPersistent configuration is stored in .vulnscout/cache/config.env and is automatically loaded on each run.
# Set a config value
./vulnscout config <key> <value>
# List current configuration (sensitive values masked)
./vulnscout config-list
# Remove a config key
./vulnscout config-clear <key>Example β set an NVD API key for higher rate limits:
./vulnscout config NVD_API_KEY abc123The following environment variables can be set via vulnscout config or exported before running:
| Variable | Description | Default |
|---|---|---|
|
Name of the Docker container |
|
|
Docker image to use |
|
|
Root build directory on the host (parent of |
|
|
Directory for output files on the host |
|
|
Cache directory on the host (holds the SQLite database and config) |
|
|
Port the web UI listens on |
|
|
Host address for the web UI |
|
|
Backend API URL used by the dev frontend |
|
|
UID used to write output files (avoids permission issues) |
current user |
|
GID used to write output files |
current group |
| Variable | Description | Default |
|---|---|---|
|
NVD API key for higher rate limits (https://nvd.nist.gov/developers/request-an-api-key) |
(none) |
|
Continue scanning even if input files contain errors |
|
|
Enable verbose logging in the container |
|
| Variable | Description | Default |
|---|---|---|
|
Product name embedded in generated reports and SBOMs |
(none) |
|
Product version embedded in generated reports |
(none) |
|
Author/company name embedded in reports |
(none) |
|
Customer/client company name embedded in reports (optional, may be empty) |
(none) |
|
Contact email embedded in reports |
(none) |
|
URL embedded in exported SBOM documents |
(none) |
If you want to run VulnScout with an HTTP proxy, set variables in the config:
./vulnscout config HTTP_PROXY http://proxy.example.com:8080
./vulnscout config HTTPS_PROXY http://proxy.example.com:8080
./vulnscout config NO_PROXY localhost,127.0.0.1Or pass them directly as environment variables when calling vulnscout.
If you were previously running VulnScout with a docker-compose.yml file per variant,
use migration.sh to import all your existing data into the new SQLite database.
# Migrate specifying the directory explicitly
./migration.sh /path/to/.vulnscout --project myproject
# Remove legacy YAML files and output dirs without prompting
./migration.sh /path/to/.vulnscout --project myproject --remove-old
# Keep legacy files (skip cleanup prompt)
./migration.sh /path/to/.vulnscout --project myproject --keep-oldThe script will:
-
Scan the build directory for sub-directories containing
docker-compose.ymlfiles. -
Use each sub-directory name as the
--variantfor that import batch. -
Extract host-side input paths from the compose volume mounts and import them.
-
Re-import legacy assessments from any
output/openvex.jsonfound alongside the compose file. -
After all imports succeed, prompt whether to delete the old YAML files and output directories (overridden by
--keep-old/--remove-old).
Once migration is complete, start VulnScout normally:
./vulnscout serve-
SPDX 2.3 (Packages) - JSON and tag-value formats
-
SPDX 3.0 (Packages + vulnerabilities)
-
Cyclone DX 1.4, 1.5, 1.6 (Packages + vulnerabilities)
-
Grype native JSON format (Packages + vulnerabilities)
-
Yocto JSON output of
cve-checkmodule (Packages + vulnerabilities)
-
SPDX 2.3 (Packages)
-
SPDX 3.0 (Packages + vulnerabilities)
-
Cyclone DX 1.4, 1.5, 1.6 (Packages + vulnerabilities)
-
openVex (vulnerabilities + assessments)
-
All reports: Asciidoc, HTML, PDF
-
Summary: Asciidoc, HTML, PDF
-
Time estimates: csv
-
Vulnerabilities: csv, txt
-
NVD (National Vulnerability Database)
-
All data sources supported by Grype
-
EPSS (Exploit Prediction Scoring System)
-
Information embedded in input files


