Skip to main content

Generate and transform VEX documents from SBOMs and vulnerability data sources.

Project description

Vexcalibur

Vexcalibur wordmark and sword logo

CI CodeQL OpenSSF Scorecard Dependency Review

Vexcalibur turns software bills of materials and vulnerability findings into VEX documents. It reads CycloneDX SBOMs or a GitHub Dependency Graph SBOM. Findings come from an OSV-compatible service or a local file.

Version 0.3.0 writes CycloneDX 1.6, OpenVEX 0.2.0, and CSAF 2.0 JSON. CSAF output uses the csaf_vex profile.

The project is usable, but still pre-1.0. Pin an exact release because command flags, Python APIs, and detailed output may change.

What works today

Area Support
SBOM input CycloneDX JSON and XML 1.4–1.6; GitHub Dependency Graph SPDX 2.3 JSON
Finding sources Public OSV with explicit consent; private OSV-compatible endpoints; local findings files
VEX output CycloneDX 1.6 JSON; OpenVEX 0.2.0 JSON; CSAF 2.0 JSON with the csaf_vex profile
Automation A companion GitHub Action
Migration A narrow vexy command-line compatibility layer
Python 3.10–3.14

Install a release

Create an environment and pin the package version:

python -m venv .venv
.venv/bin/python -m pip install "vexcalibur==0.3.0"
.venv/bin/vexcalibur --help

On Windows, use .venv\Scripts\python and .venv\Scripts\vexcalibur.

Try local generation

Clone the repository, then install its locked dependencies:

uv sync

Dependency installation may contact the configured package index. The generation command below uses only local inputs and does not contact a vulnerability service.

Generate a VEX document from the committed example files:

uv run --frozen vexcalibur generate \
  tests/fixtures/sbom/cyclonedx-json-simple.json \
  --offline \
  --findings-file tests/fixtures/findings/all-analysis-states.json \
  --timestamp 2026-06-23T00:00:00Z \
  --output /tmp/vexcalibur-vex.json

Check the result:

python - <<'PY'
import json
from pathlib import Path

vex = json.loads(Path("/tmp/vexcalibur-vex.json").read_text())
assert vex["bomFormat"] == "CycloneDX"
assert vex["specVersion"] == "1.6"
assert len(vex["vulnerabilities"]) == 5
print("generated CycloneDX VEX")
PY

See the quickstart for the guided version of this example.

CycloneDX remains the default output. Add --format openvex and identify the document author to create OpenVEX. Add --format csaf and the required document and publisher metadata to create a CSAF 2.0 VEX document. Follow the OpenVEX guide or CSAF guide for a runnable example and the format's evidence rules.

Choose a finding source

Vexcalibur requires one finding source for each generation run.

Inventory and trust boundary Use
Findings already exist locally Use --findings-file findings.json. Add --offline for a local SBOM.
Inventory may go to an internal service --osv-url https://osv.internal.example
Inventory is approved for public OSV --allow-public-osv

Warning: --allow-public-osv sends package URLs and versions to https://api.osv.dev. Do not use it with a private SBOM or sensitive package inventory unless that disclosure is approved.

The default public endpoint fails closed without that flag. Fetching an SBOM from GitHub is a separate network boundary and does not grant permission to send the resulting inventory to public OSV.

Documentation

The complete manual is at vexcalibur-dev.github.io/vexcalibur.

Contributing

Run the local quality gate:

make check

Documentation changes must also build without warnings:

uv sync --extra docs
make docs

See CONTRIBUTING.md, the security policy, and the Python style policy before opening a pull request.

Use the issue forms for questions, bugs, and feature requests. The organization support policy explains which public route to use, and the code of conduct applies to project spaces.

Vexcalibur is licensed under the Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vexcalibur-0.3.1.tar.gz (836.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vexcalibur-0.3.1-py3-none-any.whl (65.3 kB view details)

Uploaded Python 3

File details

Details for the file vexcalibur-0.3.1.tar.gz.

File metadata

  • Download URL: vexcalibur-0.3.1.tar.gz
  • Upload date:
  • Size: 836.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for vexcalibur-0.3.1.tar.gz
Algorithm Hash digest
SHA256 98dc0ad0599eb5627e85744a407402962c0fdad16b715bf4da27ad5d78ec99cf
MD5 5bd8c59cae97bb3f0047fdd2e18d7093
BLAKE2b-256 89436e4ad6348b5e41004e74f77cfff67f7b997e0989f9365c357869a370e9fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for vexcalibur-0.3.1.tar.gz:

Publisher: pypi.yml on vexcalibur-dev/vexcalibur

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vexcalibur-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: vexcalibur-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 65.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for vexcalibur-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 de538f693600b0a7ce390fb6b4e0b368cea92821b62ec3203038f28b7d615219
MD5 977c15d7f117c86c3e33c11b9d55eb5d
BLAKE2b-256 9cf168faf1f9e1cd9c2a202ab1e0b22613f0114a4d3f76e337fa5ef2f6ce684b

See more details on using hashes here.

Provenance

The following attestation bundles were made for vexcalibur-0.3.1-py3-none-any.whl:

Publisher: pypi.yml on vexcalibur-dev/vexcalibur

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page