Skip to main content

csaf-check

CI PyPI Python License: Apache-2.0

Validate CSAF 2.0 advisories from Python, using the same validator Secvisogram runs — and get an honest answer when that validator is not installed.

The problem

If you publish security advisories as CSAF, you want schema validation in your release pipeline, not in a browser tab at the end. The authoritative implementation of the CSAF 2.0 mandatory tests is @secvisogram/csaf-validator-lib, which is JavaScript. Reimplementing the schema in Python means maintaining a second, subtly different opinion about what "valid" means — and yours will be the wrong one.

So this package does not reimplement anything. It bridges to the real validator and handles the part that is annoying to get right: what happens when the validator is not there.

The contract

validate() never raises. Not when Node is missing, not when the library is absent, not when the validator times out or returns something unexpected. Each of those returns a result that says so:

from csaf_check import validate

result = validate(advisory_dict)

result.available   # could the validator run at all?
result.is_valid    # True / False / None when no verdict was reached
result.errors      # one message per failed mandatory test
result.note        # why there is no verdict, when there isn't
result.conclusive  # available and a verdict exists

This matters because the alternative — a validator that throws on a missing optional dependency — turns a quality gate into a hard dependency, and every caller ends up wrapping it in try/except and swallowing real failures along with the boring ones.

Install

pip install csaf-check

That gives you the Python API and CLI. For actual validation you also need Node.js and the validator library:

npm install @secvisogram/csaf-validator-lib

The default is intentionally lenient: without the JavaScript validator, csaf-check prints UNKNOWN - validator unavailable and exits 0, so CI environments without Node or the validator do not break. Strict handling is an explicit opt-in: add --require-validator to make validator unavailability exit 3.

The validator is found either next to the installed package or under node_modules in your current working directory, so running npm install in your own project directory is enough — you do not have to install it into site-packages. NODE_PATH is honoured as well.

CLI

csaf-check examples/advisory-minimal.json                      # human-readable verdict
csaf-check examples/advisory-minimal.json --json               # machine-readable
csaf-check - < examples/advisory-minimal.json                  # stdin
csaf-check examples/advisory-minimal.json --require-validator  # fail if no verdict is possible

Exit codes: 0 valid (or inconclusive without --require-validator) — 1 invalid — 2 unreadable or malformed input — 3 no verdict possible and --require-validator was set.

Python API

import json
from csaf_check import validate, validator_available

if not validator_available():
    print("install Node.js to enable strict validation")

with open("advisory.json", encoding="utf-8") as fh:
    result = validate(json.load(fh))

if result.conclusive and not result.is_valid:
    for message in result.errors:
        print("FAIL", message)

What this does NOT do

  • It does not generate CSAF documents. It only validates ones you already have.
  • It runs the mandatory tests only, not the informative or optional profiles.
  • It does not check that your advisory is correct, only that it is well-formed. A schema-valid document can still describe the wrong product or the wrong affected range.
  • It does not publish anything, sign anything, or talk to any network service.
  • It is not legal advice about the EU Cyber Resilience Act. CRA is format-neutral and does not mandate CSAF. CSAF is a good machine-readable choice for advisories and VEX, not a compliance checkbox.

Examples

examples/advisory-minimal.json is a small synthetic advisory for a fictional vendor using a placeholder CVE identifier. examples/advisory-invalid.json is deliberately missing the mandatory tracking object. Both exist to exercise this wrapper; neither describes a real product or a real vulnerability.

Testing

pip install -e ".[dev]"
pytest -q

The suite runs without Node.js on purpose — the degradation path is the part most likely to rot.

License

Apache-2.0. See LICENSE.

Built and maintained by Gexiro Global Enterprises Ltd.

Third-party attribution: see NOTICE.

Part of the Gexiro open-source toolkit.

Metadata

Release files for csaf-check 0.1.1

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

Source distribution (sdist)

Source distribution for csaf-check 0.1.1
File Size Uploaded
csaf_check-0.1.1.tar.gz 20.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for csaf-check 0.1.1
File Interpreter ABI Platform
csaf_check-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 38.5 kB

Release files / csaf_check-0.1.1.tar.gz

Download URL csaf_check-0.1.1.tar.gz
Size 20.6 kB
Tags Source
SHA-256 checksum
How to use checksums
457d7c7f3607062ea1270d0110c7ac53c5bcc2a9dbcba127d8fcb543f68845f1
BLAKE2b-256 checksum
How to use checksums
6b04ae777205216f8204f173530fe779ab6aa42be2a85209ca5c0141da9a6b60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 10, 2026.

Transparency log

Release files / csaf_check-0.1.1-py3-none-any.whl

Download URL csaf_check-0.1.1-py3-none-any.whl
Size 17.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d0fae8413778aed030cee3b66a4a5f044026938a9347eaa9d2be796066182094
BLAKE2b-256 checksum
How to use checksums
123f2aff291b5c5090bbd21bdc8207abfa0e302706ea0e986842ba8d73ac8154
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

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