Python API¶
vexcalibur.api is the supported Python interface. Import application and
extension code from this module rather than from implementation modules such as
vexcalibur.generate or vexcalibur.sources.osv.
The compatibility guarantee begins with Vexcalibur 1.0. Before 1.0, pin an exact Vexcalibur release. For a 1.x release, the contract covers exported names, call signatures and defaults, documented return types and behavior, documented exceptions, public dataclass fields, protocol methods, and enum names and values. Modules and names outside this facade may change in any release.
A minor release may add an export, add an optional keyword argument with a
default to a caller-facing function or constructor, or add a more specific
exception beneath a documented base class. Protocol method signatures remain
fixed throughout 1.x. Vexcalibur may extend a protocol behind an adapter only
when existing implementations still receive the original call. Deprecations
are identified in the API reference and release notes, emit
DeprecationWarning when practical, and remain available until the next
major release. A security fix may reject input that was previously accepted as
unsafe; release notes call out that change.
The compatibility policy also covers CLI behavior, generated documents, execution reports, and integration versioning.
The installation metadata accepts Python 3.10 or later within Python 3. CI currently tests Python 3.10 through 3.14. Other Python 3 versions are unverified. Dropping a tested Python version changes the installation contract and is announced in release notes.
Runnable example¶
The Python API how-to runs against committed fixtures, handles documented failures, writes a real CycloneDX VEX document, and verifies the result.
Generation¶
Generation functions without a _result suffix return serialized JSON as
str. CycloneDX 1.6 is the default output. Pass OpenVexJsonRenderer,
Csaf20VexJsonRenderer, or Spdx3JsonRenderer to select another format.
generate_vex_from_source and generate_vex_from_components accept a
custom VulnerabilitySource. A source receives immutable component values
and returns immutable findings. VexRenderer defines the corresponding
output extension contract.
- vexcalibur.api.generate_vex_from_components(*, components, source, timestamp=None, renderer=None)¶
Generate VEX JSON from component identities and a source provider.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components to query and include in the VEX document.source (
VulnerabilitySource) – Provider used to find vulnerabilities for the components.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.
- Return type:
- Returns:
The serialized VEX document.
- Raises:
SbomError – No usable components were supplied or the source rejects their identities.
VulnerabilitySourceError – The source cannot produce findings.
VexRenderError – The findings cannot be rendered within output limits.
- vexcalibur.api.generate_vex_from_source(*, input_file, source, timestamp=None, renderer=None)¶
Generate VEX JSON from a local SBOM and source provider.
- Parameters:
input_file (
Path) – CycloneDX JSON or XML, or SPDX 3 JSON-LD file to read.source (
VulnerabilitySource) – Provider used to find vulnerabilities for the SBOM components.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.
- Return type:
- Returns:
The serialized VEX document.
- Raises:
SbomError – The SBOM is unreadable, invalid, unsupported, or contains no usable components.
VulnerabilitySourceError – The source cannot produce findings.
VexRenderError – The findings cannot be rendered within output limits.
- vexcalibur.api.generate_vex_from_sbom(*, input_file, timestamp=None, osv_base_url='https://api.osv.dev', allow_public_osv=False, osv_source_name=None, osv_source_url=None, osv_headers=None, renderer=None)¶
Generate VEX JSON from a local SBOM using an OSV-compatible source.
- Parameters:
input_file (
Path) – CycloneDX JSON or XML, or SPDX 3 JSON-LD file to read.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.osv_base_url (
str) – OSV-compatible endpoint.allow_public_osv (
bool) – Consent to send package inventory to public OSV.osv_source_name (
str|None) – Provenance name for a private compatible endpoint.osv_source_url (
str|None) – Provenance URL paired withosv_source_name.osv_headers (
Mapping[str,str] |None) – ASCII request headers sent only to the configured OSV endpoint.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.
- Return type:
- Returns:
The serialized VEX document.
- Raises:
SbomError – The SBOM is unreadable, invalid, unsupported, or contains no usable versioned components.
OsvClientError – OSV configuration, transport, or response handling fails.
VexRenderError – The findings cannot be rendered within output limits.
- vexcalibur.api.generate_vex_from_github_sbom(*, repository, timestamp=None, github_api_url='https://api.github.com', github_token_env=None, use_gh_auth=True, osv_base_url='https://api.osv.dev', allow_public_osv=False, osv_source_name=None, osv_source_url=None, osv_headers=None, renderer=None)¶
Generate VEX JSON from a GitHub Dependency Graph SBOM.
Fetching from GitHub does not grant consent to send the resulting package inventory to public OSV. Set
allow_public_osvexplicitly for that separate transfer.- Parameters:
repository (
str) – GitHub repository inOWNER/REPOform.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.github_api_url (
str) – GitHub REST API base URL.github_token_env (
str|None) – Environment variable containing a printable ASCII GitHub token without whitespace. When omitted, standard GitHub token variables are checked.use_gh_auth (
bool) – Fall back togh auth tokenwhen environment variables do not provide a token.osv_base_url (
str) – OSV-compatible endpoint.allow_public_osv (
bool) – Consent to send package inventory to public OSV.osv_source_name (
str|None) – Provenance name for a private compatible endpoint.osv_source_url (
str|None) – Provenance URL paired withosv_source_name.osv_headers (
Mapping[str,str] |None) – ASCII request headers sent only to the configured OSV endpoint.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.
- Return type:
- Returns:
The serialized VEX document.
- Raises:
GithubSbomError – GitHub configuration, transport, or SBOM parsing fails.
SbomError – The fetched SBOM contains no usable versioned components.
OsvClientError – OSV configuration, transport, or response handling fails.
VexRenderError – The findings cannot be rendered within output limits.
- vexcalibur.api.generate_vex_from_local_findings(*, input_file, findings_file, timestamp=None, renderer=None)¶
Generate VEX JSON from a local SBOM and local findings.
- Parameters:
input_file (
Path) – CycloneDX JSON or XML, or SPDX 3 JSON-LD file to read.findings_file (
Path) – Local findings JSON file to read.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.
- Return type:
- Returns:
The serialized VEX document.
- Raises:
SbomError – The SBOM is unreadable, invalid, unsupported, or contains no usable components.
LocalFindingsError – The findings file is unreadable or invalid.
VexRenderError – The findings cannot be rendered within output limits.
Report-aware generation¶
Each supported generation path has a *_result variant. These functions
return GenerationResult instead of str. The result retains the exact
rendered bytes and the normalized values needed to build a versioned execution
report, so callers do not need to parse VEX output to calculate counts or a
digest.
Built-in sources and renderers supply their execution-report categories. When
a result uses a custom source or renderer, pass GenerationExecutionContext
with the corresponding custom category before calling
GenerationResult.execution_report(). Generation can succeed without that
context, but the result cannot produce an execution report and the method
raises ValueError.
EXECUTION_REPORT_SCHEMA_VERSION is the feature-detection constant for this
contract. Require the exact integer value your application supports. A missing,
mistyped, or different value means the installed package does not provide that
report contract.
- vexcalibur.api.generate_vex_from_components_result(*, components, source, timestamp=None, renderer=None, execution_context=None)¶
Generate report-aware VEX from caller-supplied components and source.
Direct component input has the
CUSTOMinventory category. The source owns its network, authentication, and disclosure policy. Pass anexecution_contextthat classifies custom source or renderer boundaries before callingexecution_report()on the result. Without that context, generation succeeds butexecution_report()raisesValueError.- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
SbomError – Component or source input validation fails.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- Parameters:
components (tuple[ComponentIdentity, ...])
source (VulnerabilitySource)
timestamp (datetime | None)
renderer (VexRenderer | None)
execution_context (GenerationExecutionContext | None)
- vexcalibur.api.generate_vex_from_source_result(*, input_file, source, timestamp=None, renderer=None, execution_context=None)¶
Generate report-aware VEX from a local SBOM and custom source.
The source owns its network, authentication, and disclosure policy. Its documented exceptions propagate unchanged unless it raises
VulnerabilitySourceInputError, which becomesSbomError. Pass anexecution_contextthat classifies custom source or renderer boundaries before callingexecution_report()on the result. Without that context, generation succeeds butexecution_report()raisesValueError.- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
SbomError – Inventory or source input validation fails.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- Parameters:
input_file (Path)
source (VulnerabilitySource)
timestamp (datetime | None)
renderer (VexRenderer | None)
execution_context (GenerationExecutionContext | None)
- vexcalibur.api.generate_vex_from_sbom_result(*, input_file, timestamp=None, osv_base_url='https://api.osv.dev', allow_public_osv=False, osv_source_name=None, osv_source_url=None, osv_headers=None, renderer=None, execution_context=None)¶
Generate report-aware VEX from a local SBOM file.
The arguments, consent policy, and provider failures match
generate_vex_from_sbom.execution_contextmay classify a custom renderer but must not contradict Vexcalibur’s inventory or source category.- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
SbomError – The SBOM is invalid or contains no usable components.
OsvClientError – OSV configuration, transport, or response handling fails.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- Parameters:
- vexcalibur.api.generate_vex_from_github_sbom_result(*, repository, timestamp=None, github_api_url='https://api.github.com', github_token_env=None, use_gh_auth=True, osv_base_url='https://api.osv.dev', allow_public_osv=False, osv_source_name=None, osv_source_url=None, osv_headers=None, renderer=None, execution_context=None)¶
Generate report-aware VEX from a GitHub Dependency Graph SBOM.
Fetching from GitHub does not grant consent to send the resulting inventory to public OSV.
execution_contextmay classify a custom renderer but must not contradict Vexcalibur’s inventory or source category.- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
GithubSbomError – GitHub authentication, transport, or SBOM parsing fails.
SbomError – The inventory is invalid or contains no usable components.
OsvClientError – OSV configuration, transport, or response handling fails.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- Parameters:
- vexcalibur.api.generate_vex_from_github_source_result(*, repository, source, timestamp=None, github_api_url='https://api.github.com', github_token_env=None, use_gh_auth=True, renderer=None, execution_context=None)¶
Generate report-aware VEX from GitHub inventory and a custom source.
This function owns the remote-inventory sequence. It runs a
GenerationSourcePreflightonce, selects the renderer, validates the execution context, resolves GitHub credentials, loads the repository inventory, and then queries the source and renders the result. A failed preflight or context check prevents GitHub authentication and inventory loading.The custom source owns its network and disclosure policy.
VulnerabilitySourceInputErrorbecomesSbomError. Other exceptions from the custom source or renderer propagate unchanged. Pass anexecution_contextthat classifies custom source or renderer boundaries before callingexecution_report()on the result. Without that context, generation succeeds butexecution_report()raisesValueError.- Parameters:
repository (
str) – GitHub repository inOWNER/REPOform.source (
VulnerabilitySource) – Finding source queried with the repository’s component inventory. The source may implementGenerationSourcePreflight.timestamp (
datetime|None) – Document timestamp. The renderer uses the current UTC time when this isNone.github_api_url (
str) – GitHub REST API base URL.github_token_env (
str|None) – Environment variable containing a printable ASCII GitHub token without whitespace. When omitted, standard GitHub token variables are checked.use_gh_auth (
bool) – Fall back togh auth tokenwhen environment variables do not provide a token.renderer (
VexRenderer|None) – Output renderer. The default emits CycloneDX 1.6 JSON.execution_context (
GenerationExecutionContext|None) – Report classification for custom source or renderer boundaries. Vexcalibur infers omitted built-in values and rejects contradictory values before GitHub authentication.
- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
GithubSbomError – GitHub authentication, transport, or SBOM parsing fails.
SbomError – Inventory or source preflight validation fails.
VulnerabilitySourceError – The custom source cannot produce findings.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- vexcalibur.api.generate_vex_from_local_findings_result(*, input_file, findings_file, timestamp=None, renderer=None, execution_context=None)¶
Generate report-aware VEX from local SBOM and findings files.
- Return type:
- Returns:
The rendered document and immutable inputs needed to derive its report.
- Raises:
SbomError – The SBOM is invalid or contains no usable components.
LocalFindingsError – The findings file is unreadable or invalid.
VexRenderError – The findings cannot be rendered within output limits.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report.
TypeError – A result or context value has the wrong type.
ValueError – The execution context contradicts inferred generation facts.
- Parameters:
input_file (Path)
findings_file (Path)
timestamp (datetime | None)
renderer (VexRenderer | None)
execution_context (GenerationExecutionContext | None)
- vexcalibur.api.EXECUTION_REPORT_SCHEMA_VERSION = 1¶
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
- class vexcalibur.api.GenerationResult(rendered_document, components, findings, execution_context=None)¶
Rendered VEX and an immutable snapshot of the normalized render inputs.
- Parameters:
rendered_document (
str) – Exact built-in text rendered as VEX.components (
tuple[ComponentIdentity,...]) – Exact tuple of normalized component identities.findings (
tuple[VulnerabilityFinding,...]) – Exact tuple of normalized vulnerability findings.execution_context (
GenerationExecutionContext|None) – Optional source and renderer categories required to construct an execution report.
- Raises:
TypeError – A value has the wrong concrete type.
GenerationReportMetadataError – The loaded package version cannot be identified safely for a report-aware result.
- property components: tuple[ComponentIdentity, ...]¶
Return independent ordinary package objects from the retained snapshot.
- property findings: tuple[VulnerabilityFinding, ...]¶
Return independent ordinary findings from the retained snapshot.
- property rendered_bytes: bytes¶
Return and retain the strict UTF-8 representation of the document.
- Raises:
VexRenderError – The rendered document is not strict UTF-8 text.
- execution_report()¶
Build the public execution report from retained generation facts.
- Raises:
ValueError – The result lacks report context or contains values that schema version 1 cannot represent.
GenerationReportMetadataError – Installed package metadata cannot identify the loaded Vexcalibur code.
VexRenderError – The rendered document is not strict UTF-8 text.
- Return type:
- class vexcalibur.api.GenerationExecutionContext(inventory_source, finding_source, output_format)¶
Source and renderer facts retained by one generation operation.
- Parameters:
inventory_source (
InventorySourceCategory) – Category for the component inventory.finding_source (
FindingSourceCategory) – Category for vulnerability findings.output_format (
ExecutionReportOutputFormat) – Category for the rendered VEX document.
- Raises:
TypeError – Any category is not a member of its declared enum.
- class vexcalibur.api.GenerationSourcePreflight(*args, **kwargs)¶
Source policy checks that must run before loading remote inventory.
- class vexcalibur.api.GenerationExecutionReport(schema_version, command, vexcalibur_version, inventory_source, finding_source, output_format, component_count, finding_count, analysis_state_counts, document)¶
Versioned summary of one successful
generateoperation.Constructor values must satisfy the schema-version-1 enums, limits, analysis-state order, and count relationships.
analysis_state_countscontains unique, positive-count pairs in this order:RESOLVED,EXPLOITABLE,IN_TRIAGE,FALSE_POSITIVE, thenNOT_AFFECTED. Omit states with a zero count. Each count must be no greater than10,000,000, and their sum must equalfinding_count.- Raises:
TypeError – A field or nested value has the wrong type.
ValueError – A value violates the schema-version-1 invariants.
- Parameters:
schema_version (int)
command (Literal['generate'])
vexcalibur_version (str)
inventory_source (InventorySourceCategory)
finding_source (FindingSourceCategory)
output_format (ExecutionReportOutputFormat)
component_count (int)
finding_count (int)
analysis_state_counts (tuple[tuple[VexAnalysisState, int], ...])
document (GeneratedDocumentMetadata)
- classmethod from_result(*, result)¶
Calculate a report from the normalized values used to render VEX.
- Parameters:
result (
GenerationResult) – Report-aware result from a supported*_resultfunction.- Return type:
- Returns:
A validated schema-version-1 report.
- Raises:
TypeError –
resultis not aGenerationResult.ValueError – The result lacks report context or its facts violate schema-version-1 invariants.
GenerationReportMetadataError – Installed package metadata cannot identify the loaded Vexcalibur code.
VexRenderError – The rendered document is not strict UTF-8 text.
- to_dict()¶
Return the complete public report as JSON-compatible values.
- Return type:
- to_json()¶
Serialize a bounded canonical report with one trailing newline.
- Raises:
ValueError – The canonical JSON exceeds the report size limit.
- Return type:
- class vexcalibur.api.GeneratedDocumentMetadata(sha256, bytes)¶
Digest and byte size of the exact rendered VEX document.
- Parameters:
- Raises:
ValueError – The digest or byte count is outside that contract.
- class vexcalibur.api.GeneratedDocumentMetadataDict¶
JSON representation of generated-document metadata.
- class vexcalibur.api.GenerationExecutionReportDict¶
JSON representation of one generation execution report.
The typed dictionaries expose these required fields:
Type |
Field |
Value |
|---|---|---|
|
|
Lowercase SHA-256 digest text for the exact UTF-8 document bytes |
|
|
UTF-8 document byte count as an integer |
|
|
Report schema integer |
|
|
Literal |
|
|
Installed package version text |
|
|
Serialized |
|
|
Serialized |
|
|
Serialized |
|
|
Normalized component count as an integer |
|
|
Normalized finding count as an integer |
|
|
Mapping from serialized analysis-state values to positive integer counts |
|
|
|
- class vexcalibur.api.InventorySourceCategory(*values)¶
Identifier-free categories for the component inventory source.
- class vexcalibur.api.FindingSourceCategory(*values)¶
Identifier-free categories for the vulnerability finding source.
- class vexcalibur.api.ExecutionReportOutputFormat(*values)¶
Identifier-free categories for the generated document format.
- vexcalibur.api.parse_generation_execution_report(serialized)¶
Parse one bounded, canonical execution report into its typed value.
- Parameters:
serialized (
bytes|str) – Exact UTF-8 bytes or text for one report.- Return type:
- Returns:
The validated schema-version-1 report.
- Raises:
TypeError –
serializedis not exact built-in bytes or text.GenerationExecutionReportParseError – The report is oversized, malformed, noncanonical, or incompatible with schema version 1.
The execution-report reference defines the serialized fields, category values, size limit, and security boundary. This checked-in example writes matching VEX and report bytes without replacing existing files:
1#!/usr/bin/env python3
2"""Generate matching VEX and execution-report bytes with the Python API."""
3
4import argparse
5import os
6from pathlib import Path
7
8from vexcalibur.api import (
9 GenerationExecutionReportParseError,
10 GenerationReportMetadataError,
11 LocalFindingsError,
12 SbomError,
13 VexRenderError,
14 generate_vex_from_local_findings_result,
15 parse_generation_execution_report,
16)
17
18
19def _write_new_file_exclusively(path: Path, content: bytes) -> None:
20 flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
21 flags |= getattr(os, "O_BINARY", 0)
22 flags |= getattr(os, "O_CLOEXEC", 0)
23 flags |= getattr(os, "O_NOFOLLOW", 0)
24 descriptor = os.open(path, flags, 0o600)
25 try:
26 if os.name != "nt":
27 os.fchmod(descriptor, 0o600)
28 with os.fdopen(descriptor, "wb", closefd=False) as stream:
29 stream.write(content)
30 stream.flush()
31 os.fsync(stream.fileno())
32 finally:
33 os.close(descriptor)
34
35
36def main(output_directory: Path) -> None:
37 try:
38 result = generate_vex_from_local_findings_result(
39 input_file=Path("tests/fixtures/sbom/cyclonedx-json-simple.json"),
40 findings_file=Path("tests/fixtures/findings/all-analysis-states.json"),
41 )
42 except GenerationReportMetadataError as exc:
43 raise SystemExit(f"package metadata cannot identify the report: {exc}") from exc
44 except (SbomError, LocalFindingsError, VexRenderError) as exc:
45 raise SystemExit(f"generation failed: {exc}") from exc
46
47 try:
48 report = result.execution_report()
49 serialized_report = report.to_json()
50 if parse_generation_execution_report(serialized_report) != report:
51 raise SystemExit("execution report did not round-trip through its parser")
52 except GenerationReportMetadataError as exc:
53 raise SystemExit(f"package metadata cannot identify the report: {exc}") from exc
54 except GenerationExecutionReportParseError as exc:
55 raise SystemExit(f"generated execution report is invalid: {exc}") from exc
56 except ValueError as exc:
57 raise SystemExit(f"generation facts cannot produce a report: {exc}") from exc
58
59 if not output_directory.parent.is_dir():
60 raise SystemExit("output parent directory must already exist")
61 output_directory.mkdir(mode=0o700)
62 if os.name != "nt":
63 output_directory.chmod(0o700)
64 document_path = output_directory / "vex.json"
65 report_path = output_directory / "execution-report.json"
66 _write_new_file_exclusively(document_path, result.rendered_bytes)
67 _write_new_file_exclusively(
68 report_path,
69 serialized_report.encode("utf-8"),
70 )
71 print(f"wrote {document_path} and {report_path}")
72
73
74def _output_directory() -> Path:
75 parser = argparse.ArgumentParser()
76 parser.add_argument("output_directory", type=Path)
77 return parser.parse_args().output_directory
78
79
80if __name__ == "__main__":
81 main(_output_directory())
Run it from Bash or PowerShell at the repository root with a new output directory:
uv run --frozen python docs/examples/generate_execution_report.py vexcalibur-python-api
Success prints both output paths. The two writes are independent and can leave partial files. On Windows, their privacy depends on the ACL of the existing parent directory. Python embeddings do not receive the CLI’s coordinated publication transaction.
SBOM ingest and GitHub¶
load_cyclonedx_sbom reads CycloneDX JSON or XML 1.4, 1.5, or 1.6.
load_spdx3_sbom reads SPDX 3.0.1 JSON-LD. load_sbom selects the parser
from the file’s content: XML is CycloneDX, and a JSON document picks its format
from one top-level marker, bomFormat for CycloneDX or @graph for
SPDX 3. Each loader returns component identities sorted by package URL and
reference. Components without package URLs are omitted.
SPDX input supports package-identity extraction from the compact JSON form,
not full SPDX validation or general JSON-LD processing. It requires the exact
SPDX 3.0.1 context string and a string type on every graph node. It does
not expand contexts or fetch referenced documents. See the
supported SPDX input fields.
Package definitions must be top-level graph entries, and external identifier
references must resolve locally. Duplicate identifier node IDs are rejected.
The sum of canonical package URL bytes across accepted packages is limited
to 10 MiB, counting repeated references once per package.
The loaders open their path once in nonblocking mode and require the opened target to be a regular file. A symbolic link to a regular file works. Each loader reads at most 10 MiB, accepts at most 10,000 components, and rejects duplicate returned references. CycloneDX input also limits component nesting to 50 levels. JSON input rejects duplicate keys, more than 100 nested arrays or objects, and integer literals longer than 1,000 decimal digits. XML input rejects DTD, entity, and external-reference declarations.
generate_vex_from_github_sbom requests a repository’s Dependency Graph
SBOM. Public repositories may work without a token, subject to GitHub’s rate
limits. Token-backed requests need read access to the repository. Set
github_token_env to read a named environment variable. Otherwise,
Vexcalibur checks GH_TOKEN and then GITHUB_TOKEN for GitHub.com before
falling back to gh auth token. Pass use_gh_auth=False to disable that
fallback. GitHub Enterprise requires either github_token_env or credentials
available to gh for the configured host. Token text must be printable ASCII
without whitespace.
generate_vex_from_github_source_result is the supported owner for a custom
finding source and GitHub inventory. It runs the source’s optional
GenerationSourcePreflight once, before GitHub authentication. The
vexcalibur.api.generate_vex_from_github_source_result() reference above
defines the complete order and exception contract.
The CLI uses this same function. Built-in public and private OSV sources use the same internal sequence. A local findings file is different: Vexcalibur loads the GitHub inventory first because the file can refer to component references from that inventory. It does not send those components to a finding service.
- vexcalibur.api.load_cyclonedx_sbom(path)¶
Load supported component identities from a CycloneDX JSON or XML SBOM.
- Parameters:
path (
Path) – Regular file containing a supported CycloneDX document.- Return type:
- Returns:
Immutable component identities sorted by package URL and reference. Components without package URLs are omitted.
- Raises:
SbomError – The file is unreadable, oversized, malformed, unsupported, or contains unsafe or contradictory component data.
- vexcalibur.api.load_sbom(path)¶
Load component identities from a CycloneDX or SPDX 3 SBOM file.
XML content is CycloneDX. JSON content selects its format from one top-level marker:
bomFormatfor CycloneDX or@graphfor SPDX 3 JSON-LD. A document carrying both markers is rejected instead of guessed.- Parameters:
path (
Path) – Regular file containing a supported SBOM document.- Return type:
- Returns:
Immutable component identities sorted by package URL and reference. Components without package URLs are omitted.
- Raises:
SbomError – The file is unreadable, oversized, malformed, unsupported, ambiguous, or contains unsafe or contradictory component data.
- vexcalibur.api.load_spdx3_sbom(path)¶
Load supported component identities from an SPDX 3.0.1 JSON-LD SBOM.
- Parameters:
path (
Path) – Regular file containing an SPDX 3.0.1 JSON-LD document.- Return type:
- Returns:
Immutable component identities sorted by package URL and reference. Packages without package URLs are omitted.
- Raises:
SbomError – The file is unreadable, oversized, malformed, unsupported, or contains unsafe or contradictory package data.
Sources and renderers¶
The local-findings generation helper reads Vexcalibur’s local findings format.
The built-in OSV helpers deny public OSV unless the caller passes
allow_public_osv=True; fetching an SBOM from GitHub does not supply that
consent. Low-level OSV clients remain outside the supported facade so callers
cannot bypass this check through a built-in helper.
A custom VulnerabilitySource is trusted application code. It owns consent,
authentication, redirect handling, resource limits, and disclosure policy for
every service it contacts. The supported facade does not inspect or constrain
that provider’s I/O.
Pass osv_headers when a private mirror needs application authentication.
Vexcalibur sends those headers only to the configured endpoint and does not
follow redirects. Header names use HTTP token characters. Values accept
printable ASCII and horizontal tabs.
One client operation has independent limits for each response and for all responses combined. It also bounds elapsed time, pages, page-token length, queries, vulnerability IDs, vulnerabilities per query, and total vulnerabilities. Requests don’t follow redirects. Generation adds a 25 MiB limit for serialized UTF-8 output; built-in renderers also apply a conservative estimate before they allocate their document structures.
- class vexcalibur.api.ComponentIdentity(ref, name, version, purl, type='library')¶
Minimal component data needed by vulnerability sources and VEX output.
- ref¶
Source document identifier used to associate findings.
- name¶
Human-readable component name.
- version¶
Explicit component version, if supplied separately from its package URL.
- purl¶
Canonical package URL identifying the component.
- type¶
CycloneDX component type used by applicable renderers.
- Raises:
ComponentVersionError –
versioncontradicts the package URL version.- Parameters:
ref (str)
name (str)
version (str | None)
purl (PackageURL)
type (str)
ComponentIdentity.purl uses packageurl.PackageURL. Construct it
with the third-party packageurl package:
from packageurl import PackageURL
purl = PackageURL.from_string("pkg:pypi/example@1.0.0")
- class packageurl.PackageURL(type=None, namespace=None, name=None, version=None, qualifiers=None, subpath=None, normalize_purl=True)¶
A purl is a package URL as defined at https://github.com/package-url/purl-spec
- class vexcalibur.api.VulnerabilityFinding(id, source_name, source_url, component_ref, purl, modified=None, analysis_state=VexAnalysisState.IN_TRIAGE, analysis_detail='Detected by vulnerability source; manual exploitability analysis required.', action_statement=None, impact_statement=None, fixed_version=None, remediation_category=None)¶
Provider-neutral vulnerability finding for one affected component.
- Parameters:
- id¶
Vulnerability identifier.
- source_name¶
Display name for the vulnerability source.
- source_url¶
HTTP or HTTPS provenance URL for the source.
- component_ref¶
Reference of the affected
ComponentIdentity.
- purl¶
Package URL reported by the source.
- modified¶
Source modification timestamp, when known.
- analysis_state¶
Exploitability assessment represented in the VEX.
- analysis_detail¶
Human-readable reason for the assessment.
- action_statement¶
Action that a consumer should take, when applicable.
- impact_statement¶
Reason the product is not affected, when applicable.
- fixed_version¶
First known fixed version, when applicable.
- remediation_category¶
Kind of remediation represented by the action.
- class vexcalibur.api.VexAnalysisState(*values)¶
Vulnerability analysis states supported by the domain model.
- class vexcalibur.api.VexRemediationCategory(*values)¶
Remediation categories that a VEX output format may represent.
- class vexcalibur.api.VulnerabilitySource(*args, **kwargs)¶
Provider-neutral contract for vulnerability finding sources.
- findings_for_components(components)¶
Return VEX-ready vulnerability findings for SBOM components.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Immutable component identities to inspect.- Return type:
- Returns:
Immutable findings whose component references identify members of
components.- Raises:
VulnerabilitySourceError – The source cannot produce findings.
- class vexcalibur.api.VexRenderer(*args, **kwargs)¶
Render provider-neutral components and findings as one VEX format.
- render(*, components, findings, timestamp=None)¶
Return a serialized VEX document.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components available to the document.findings (
tuple[VulnerabilityFinding,...]) – Vulnerability findings associated with those components.timestamp (
datetime|None) – Document timestamp, orNoneto use the current time.
- Return type:
- Returns:
Serialized VEX JSON.
- Raises:
VexRenderError – The values cannot form a valid bounded document.
- class vexcalibur.api.CycloneDxJsonRenderer¶
Render CycloneDX 1.6 VEX JSON.
- render(*, components, findings, timestamp=None)¶
Adapt provider findings and return CycloneDX 1.6 VEX JSON.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components available to the document.findings (
tuple[VulnerabilityFinding,...]) – Findings associated with those components.timestamp (
datetime|None) – Document timestamp, orNoneto use current UTC.
- Return type:
- Returns:
Serialized CycloneDX 1.6 VEX JSON.
- Raises:
VexRenderError – The values cannot form a valid document.
- class vexcalibur.api.OpenVexJsonRenderer(author, role=None)¶
Render OpenVEX 0.2.0 JSON for one document author.
- author¶
Document author identifier. OpenVEX recommends an IRI.
- role¶
Optional human-readable author role.
- Raises:
OpenVexRenderError – Author metadata is invalid.
- Parameters:
- render(*, components, findings, timestamp=None)¶
Adapt provider findings and return OpenVEX 0.2.0 JSON.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components available to the document.findings (
tuple[VulnerabilityFinding,...]) – Findings associated with those components.timestamp (
datetime|None) – Document timestamp, orNoneto use current UTC.
- Return type:
- Returns:
Serialized OpenVEX 0.2.0 JSON.
- Raises:
OpenVexRenderError – The values cannot form a valid document.
- class vexcalibur.api.Csaf20DocumentMetadata(document_id, title, publisher_name, publisher_namespace, publisher_category, status=CsafDocumentStatus.DRAFT)¶
Publisher-controlled metadata required by the CSAF 2.0 VEX profile.
- document_id¶
Publisher-controlled tracking identifier.
- title¶
Human-readable document title.
- publisher_name¶
Human-readable publisher name.
- publisher_namespace¶
Absolute HTTP or HTTPS publisher namespace.
- publisher_category¶
Publisher’s role in the advisory process.
- status¶
Initial CSAF document lifecycle status.
- Raises:
CsafRenderError – Required metadata is empty, malformed, or unsupported.
- Parameters:
document_id (str)
title (str)
publisher_name (str)
publisher_namespace (str)
publisher_category (CsafPublisherCategory)
status (CsafDocumentStatus)
- class vexcalibur.api.Csaf20VexJsonRenderer(metadata, tool_version=<factory>)¶
Render CSAF 2.0 JSON using the standard VEX profile.
- metadata¶
Tracking and publisher metadata for the document.
- tool_version¶
Vexcalibur version recorded in generator metadata.
- Raises:
CsafRenderError –
tool_versionis empty.- Parameters:
metadata (Csaf20DocumentMetadata)
tool_version (str)
- render(*, components, findings, timestamp=None)¶
Adapt provider findings and return CSAF 2.0 VEX JSON.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components available to the document.findings (
tuple[VulnerabilityFinding,...]) – Findings associated with those components.timestamp (
datetime|None) – Document timestamp, orNoneto use current UTC.
- Return type:
- Returns:
Serialized CSAF 2.0 VEX JSON.
- Raises:
CsafRenderError – The values cannot form a valid document.
- class vexcalibur.api.CsafDocumentStatus(*values)¶
Lifecycle statuses supported for an initial CSAF document revision.
- class vexcalibur.api.CsafPublisherCategory(*values)¶
Publisher categories supported for generated CSAF documents.
- class vexcalibur.api.Spdx3JsonRenderer(creator, tool_version=<factory>)¶
Render SPDX 3.0.1 JSON-LD using the security profile’s VEX relationships.
- creator¶
Name recorded as the document’s creating Agent.
- tool_version¶
Vexcalibur version recorded on the creating Tool.
- Raises:
Spdx3RenderError –
creatorortool_versionis empty.- Parameters:
- render(*, components, findings, timestamp=None)¶
Adapt provider findings and return SPDX 3.0.1 JSON-LD.
- Parameters:
components (
tuple[ComponentIdentity,...]) – Components available to the document.findings (
tuple[VulnerabilityFinding,...]) – Findings associated with those components.timestamp (
datetime|None) – Document timestamp, orNoneto use current UTC.
- Return type:
- Returns:
Serialized SPDX 3.0.1 JSON-LD.
- Raises:
Spdx3RenderError – The values cannot form a valid document.
Enumeration values¶
Enum |
Member |
Serialized value |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Exceptions¶
Catch the most specific exception when the recovery action differs. The base classes support broader boundaries:
SbomErrorcovers local and GitHub SBOM input failures.VulnerabilitySourceErrorcovers provider failures.OsvClientErrorandLocalFindingsErroradd provider-specific detail.VexRenderErrorcovers invalid or oversized output. Format-specific renderers raise itsOpenVexRenderError,CsafRenderError, orSpdx3RenderErrorsubclasses.ComponentVersionErrorreports contradictory explicit and package URL versions when an application constructsComponentIdentitydirectly.GenerationReportMetadataErrormeans package metadata cannot prove which Vexcalibur code produced a report.GenerationExecutionReportParseErrorrejects oversized, malformed, noncanonical, or schema-incompatible report bytes.
The API does not wrap unexpected exceptions raised by custom providers or renderers. Their implementations own those failures.
- exception vexcalibur.api.ComponentVersionError¶
Raised when a component carries contradictory version identities.
- exception vexcalibur.api.GenerationReportMetadataError¶
Raised when installed package metadata cannot identify a report.
- exception vexcalibur.api.GenerationExecutionReportParseError¶
Raised when serialized execution-report bytes violate the public contract.
- exception vexcalibur.api.SbomError¶
Raised when an SBOM cannot be parsed into supported component data.
- exception vexcalibur.api.GithubSbomError¶
Base error raised for GitHub SBOM input failures.
- exception vexcalibur.api.GithubSbomConfigurationError¶
Raised when GitHub SBOM input configuration is invalid.
- exception vexcalibur.api.GithubSbomClientError¶
Raised when GitHub’s SBOM API cannot return usable data.
- exception vexcalibur.api.VulnerabilitySourceError¶
Base error raised by provider-neutral vulnerability sources.
- exception vexcalibur.api.VulnerabilitySourceInputError¶
Raised when source-specific findings cannot be produced from the input components.
- exception vexcalibur.api.LocalFindingsError¶
Raised when a local findings document cannot be converted into VEX findings.
- exception vexcalibur.api.OsvClientError¶
Base error raised for OSV client failures.
- exception vexcalibur.api.OsvConfigurationError¶
Raised when OSV source configuration is unsafe or invalid.
- exception vexcalibur.api.OsvResponseError¶
Raised when OSV returns a response that does not match the expected API shape.
- exception vexcalibur.api.VexRenderError¶
Raised when domain values cannot be rendered as a valid VEX document.
- exception vexcalibur.api.OpenVexRenderError¶
Raised when findings cannot form a valid standalone OpenVEX document.
- exception vexcalibur.api.CsafRenderError¶
Raised when findings cannot form a valid CSAF 2.0 VEX document.
- exception vexcalibur.api.Spdx3RenderError¶
Raised when findings cannot form a valid SPDX 3.0.1 VEX document.
Supported names¶
vexcalibur.api.__all__ is the machine-readable public surface. This page is
generated from docstrings beside the implementation. Names omitted from
__all__ are implementation details even when Python can import them.