Skip to main content

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.

Current releases write CycloneDX 1.6, OpenVEX 0.2.0, and CSAF 2.0 JSON. CSAF output uses the csaf_vex profile. This branch also writes SPDX 3.0.1 JSON-LD through the security profile's VEX relationships; no release through v0.6.3 includes it.

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; SPDX 3.0.1 JSON-LD with the security profile
Automation A companion GitHub Action
Migration A narrow vexy command-line compatibility layer
Python 3.10–3.14

Install a release

Open the release page and choose an exact version. The commands prompt for that version so an unresolved placeholder cannot reach pip:

set -euo pipefail

read -r -p "Vexcalibur version from the release page: " VEXCALIBUR_VERSION
if [[ ! "$VEXCALIBUR_VERSION" =~ ^(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})$ ]]; then
  printf 'Enter a MAJOR.MINOR.PATCH release version\n' >&2
  exit 2
fi
VEXCALIBUR_VENV=".venv-vexcalibur-${VEXCALIBUR_VERSION}"
if [[ -e "$VEXCALIBUR_VENV" ]]; then
  printf 'Refusing to reuse %s\n' "$VEXCALIBUR_VENV" >&2
  exit 2
fi
python -m venv "$VEXCALIBUR_VENV"
"$VEXCALIBUR_VENV/bin/python" -m pip install \
  "vexcalibur==${VEXCALIBUR_VERSION}"
INSTALLED_VERSION="$("$VEXCALIBUR_VENV/bin/python" -c \
  'from importlib.metadata import version; print(version("vexcalibur"))')"
test "$INSTALLED_VERSION" = "$VEXCALIBUR_VERSION"
"$VEXCALIBUR_VENV/bin/vexcalibur" --help

In PowerShell 7.3 or newer, use:

$ErrorActionPreference = "Stop"
$PSNativeCommandUseErrorActionPreference = $true
$VEXCALIBUR_VERSION = Read-Host "Vexcalibur version from the release page"
if ($VEXCALIBUR_VERSION -notmatch '^(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})$') {
    throw "Enter a MAJOR.MINOR.PATCH release version"
}
$VEXCALIBUR_VENV = ".venv-vexcalibur-$VEXCALIBUR_VERSION"
if (Test-Path -LiteralPath $VEXCALIBUR_VENV) {
    throw "Refusing to reuse $VEXCALIBUR_VENV"
}
py -m venv $VEXCALIBUR_VENV
$PYTHON = Join-Path $VEXCALIBUR_VENV "Scripts/python.exe"
$VEXCALIBUR = Join-Path $VEXCALIBUR_VENV "Scripts/vexcalibur.exe"
& $PYTHON -m pip install "vexcalibur==$VEXCALIBUR_VERSION"
$INSTALLED_VERSION = & $PYTHON -c `
    'from importlib.metadata import version; print(version("vexcalibur"))'
if ($INSTALLED_VERSION -ne $VEXCALIBUR_VERSION) {
    throw "Installed $INSTALLED_VERSION instead of $VEXCALIBUR_VERSION"
}
& $VEXCALIBUR --help

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

The complete local gate runs on Linux and needs the host tools listed in Reproduce important gates. That guide includes exact portable commands for macOS and Windows. Required pull-request CI runs the Linux-only checks.

On Linux, run the quality gate:

make check

Documentation changes must also build without warnings:

uv sync --extra docs
make docs

Parser, source-client, package-URL, and terminal-safety changes must also run the deterministic fuzz smoke profile:

make fuzz-smoke

See the contribution guide, the security policy, the fuzzing guide, 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.

Release files for vexcalibur 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vexcalibur 0.7.0
File Size Uploaded
vexcalibur-0.7.0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for vexcalibur 0.7.0
File Interpreter ABI Platform
vexcalibur-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / vexcalibur-0.7.0.tar.gz

Download URL vexcalibur-0.7.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
b4404a30227dbfce87510f23bdb67da340c7871ee2772b3345a295673b960054
BLAKE2b-256 checksum
How to use checksums
3fa834efe05a198228fcf74eaf6b72a83cb44ed932b5c9cb72e71b55dff909e3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release files / vexcalibur-0.7.0-py3-none-any.whl

Download URL vexcalibur-0.7.0-py3-none-any.whl
Size 122.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d738b78138ac5e91fb204473d2092c334eba8e7b8b8be7ad295df4555a9cac0d
BLAKE2b-256 checksum
How to use checksums
5e2655989331076480ed4e1e47402fb5d82b09fac8bcc2de614b368366aacb01
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

This release

0.7.0 This release

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page