cbomctl
One CBOM. Every jurisdiction's verdict. And where they contradict.
Germany and France recommend hybrid post-quantum key exchange. Australia recommends against it. The NSA wants ML-KEM-1024, not the -768 the others accept. If you ship into more than one of those markets, those are not independent checkboxes — and no tool will show you the collision.
cbomctl takes a CBOM from any generator, runs it against several national PQC
policies at once, and reports the matrix and the conflicts.
⚠️ Pre-release. All seven policy packs are read from their primary sources — every rule cites the section or page it came from. The machinery for unverified rules stays in place for the next pack that has not been checked: any verdict derived from one carries a visible banner naming the packs involved. Read the sources yourself before acting on a verdict — they are listed in docs/policy-sources.md. Not compliance advice.
What it looks like
cbomctl verdict app-cbom.json --jurisdictions bsi-de,anssi-fr,asd-au,cnsa-2.0
ASSET PURPOSE bsi-de anssi-fr asd-au cnsa-2.0
───────────────────────────────────────────────────────────────────────
ECDH key-agreement WARN WARN WARN FAIL ⚠ c1
└ bsi-de · disallowed 2031-12-31
└ anssi-fr · complete 2030-12-31
└ asd-au · disallowed 2030-12-31 · complete 2030-12-31
└ cnsa-2.0 · disallowed 2030-12-31 · exclusive_use 2031-12-31
└ src/payments/legacy.go:12
X25519MLKEM768 key-agreement PASS PASS WARN FAIL ⚠ c2,c3
└ asd-au · deprecated 2030-12-31
└ src/payments/tls.go:88
ML-DSA-65 signature WARN WARN WARN FAIL ⚠ c4,c5
└ asd-au · deprecated 2030-12-31
└ src/payments/sign.go:7
RSA-2048 ambiguous INDET INDET INDET INDET
└ unresolved: purpose-ambiguous (primitive:pke)
└ as key transport → critical · as signature → medium
└ Declare the purpose in cbomctl.yaml, or regenerate the CBOM with a generator that records
cryptoFunctions.
└ src/payments/keys.go:41
CONFLICTS (5)
c1 [construction] ECDH
anssi-fr, bsi-de recommend a hybrid construction for key-agreement; asd-au recommend
against it; cnsa-2.0 does not permit one outside named interoperability exceptions.
cnsa-2.0 does not permit a hybrid construction outside named interoperability exceptions,
while anssi-fr, bsi-de recommend one. **No single configuration satisfies all selected
jurisdictions.** You will need different builds, or to drop a jurisdiction from scope.
asd-au would permit a hybrid but recommends against it, so even dropping cnsa-2.0 leaves a
documented cost. This is a business decision, not a technical one.
⚖ This conflict depends on a contested encoding. Under the alternative reading (cnsa-2.0
silent), a hybrid construction would satisfy all selected jurisdictions, at a documented
cost. The argument and the evidence for the encoding used are in the `cnsa-2.0` rule's
interpretation note (`cbomctl policies show cnsa-2.0`).
WARN rather than FAIL for ASD is deliberate: the ISM recommends against
hybrids, it does not prohibit them. Reporting a guideline as a mandate is the
most common error in this space, so every rule carries a binding field —
statute, executive_order, agency_requirement, certification_requirement,
or guideline_recommendation — and the verdict follows from it.
INDET is the tool declining to guess. That CBOM records primitive: pke for
the RSA key, which cannot distinguish key transport from signature — and the
answer moves the finding between critical and medium. Rather than pick, it says
what is missing and what would resolve it.
Related tools
Most of what a PQC readiness tool does, other people already do — several of them well. Use them.
| tool | what it does |
|---|---|
| CBOMkit, cbomscanner, KeyLens, pqc-scanner | generate CBOMs from source |
| open-quantum-secure | scans source + live TLS/SSH, generates CBOM, quantum readiness score, --data-lifetime-years HNDL weighting, and seven compliance frameworks including BSI, ASD ISM and ANSSI |
| sbom-tools | CycloneDX/SPDX ingestion, semantic CBOM diff, quality scoring, CNSA 2.0 and NIST IR 8547 validation, SARIF/OSCAL |
| IBM Quantum Safe Migration Orchestrator, SandboxAQ AQtive Guard, O3 Security | commercial discovery, risk prioritization and migration planning |
cbomctl overlaps all of them, and only two things are actually its own:
- Conflict as a computed output.
open-quantum-secureruns multiple frameworks at once and its README documents cross-framework divergence directly — this is not a gap in the market, and anyone claiming otherwise has not read it. What it emits is one report per framework, concatenated; you find the disagreement by comparing them yourself.cbomctlemits the matrix, a conflict object naming the disagreeing authorities and the reason, and a computed satisfies-all target where one exists. - Evaluating a CBOM you did not generate. The tools above evaluate their
own scan. If your CBOM came from a vendor, a procurement process, or a
different generator,
cbomctlwill read it.
If you want a scanner, use open-quantum-secure. If you want diff and
validation, use sbom-tools. If you have a CBOM and need to know which
jurisdiction's answer to believe, that is this tool.
What it does not do
- It does not scan source code or probe endpoints. Bring a CBOM.
- It does not guess. In CBOMkit's published Keycloak CBOM, 8 of 22 algorithm components carry no usable purpose signal — more than a third. Those are reported as unresolved, with the range they would span if guessed.
- It does not give compliance advice. It reports what a rule set says, with the primary source and verification date attached. Every rule today is unverified.
- It does not treat guidance as law. See
binding, above. - It does not know when a CRQC arrives. 2035 is a planning assumption
matching the NIST/NSM-10 horizon, not a prediction.
--crqc-yearchanges it; whatever you choose is stamped into the output. - It does not diff SBOMs, verify signatures, or scan binaries.
Also included
cbomctl prioritize ranks findings by Mosca's inequality using data lifetimes
you supply, weighting harvest-now-decrypt-later exposure highest.
cbomctl plan emits an ordered migration plan. Both are useful; neither is
novel — see Related tools.
Policy packs
The rule sets live in policy-packs/ as a standalone,
semantically versioned artifact with its own schema and changelog, so another
tool can consume them without cbomctl. Every rule carries a primary-source
URL, a last_verified date, a binding classification, and a hybrid stance.
| pack | state |
|---|---|
| pack | state |
| --- | --- |
| pack | state |
| --- | --- |
bsi-de |
✅ TR-02102-1 v2026-01 §2.1, §5.3.4 |
anssi-fr |
✅ 5/6 — ANSSI 2023 follow-up §1.1, §1.2, §2, §3.2, §4 |
asd-au |
✅ ISM Guidelines for Cryptography, 2026-09-03 |
eu-roadmap |
✅ Coordinated Implementation Roadmap Part 1 v1.1 |
us-eo14412 |
✅ 91 FR 38483 §4(b), §5(c) |
nist-ir8547 |
✅ as a draft — IR 8547 ipd Tables 2 and 4 |
cnsa-2.0 |
✅ CNSA 2.0 FAQ v2.1 (Dec 2024), pp. 2, 6, 8, 19–20 |
Install
pip install cbomctl
Optional: pip install cbomctl[llm] adds a prose migration narrative that
cannot affect any verdict.
Documentation
Design · Policy sources and open questions · Policy packs
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cbomctl-0.1.4.tar.gz.
File metadata
- Download URL: cbomctl-0.1.4.tar.gz
- Upload date:
- Size: 145.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e35a3a7c3ebfc60acdc82d30aa610c97c93fac855749bac6f27bcd2a1f838a7
|
|
| MD5 |
e90a0096922cc0a1293095e9c25e1eb1
|
|
| BLAKE2b-256 |
36b01c7e789b68fd6910410eceebed62a5cd12d5288920336e0d9f7ecc67b934
|
Provenance
The following attestation bundles were made for cbomctl-0.1.4.tar.gz:
Publisher:
release.yml on lvlrSajjad/cbomctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cbomctl-0.1.4.tar.gz -
Subject digest:
2e35a3a7c3ebfc60acdc82d30aa610c97c93fac855749bac6f27bcd2a1f838a7 - Sigstore transparency entry: 2743365572
- Sigstore integration time:
-
Permalink:
lvlrSajjad/cbomctl@4a8909ccedb75f237119b451d5c457089d46ee30 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lvlrSajjad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a8909ccedb75f237119b451d5c457089d46ee30 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cbomctl-0.1.4-py3-none-any.whl.
File metadata
- Download URL: cbomctl-0.1.4-py3-none-any.whl
- Upload date:
- Size: 70.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1a1edc30846f351280001875bc501cd916d950c6e0b3d6721c4e39217581915
|
|
| MD5 |
b1440377b4778a629409158a330ff4f1
|
|
| BLAKE2b-256 |
befa620adc36df9dd242fce8165083ed7e7423d9155c500e06fe61e87c9697ce
|
Provenance
The following attestation bundles were made for cbomctl-0.1.4-py3-none-any.whl:
Publisher:
release.yml on lvlrSajjad/cbomctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cbomctl-0.1.4-py3-none-any.whl -
Subject digest:
d1a1edc30846f351280001875bc501cd916d950c6e0b3d6721c4e39217581915 - Sigstore transparency entry: 2743365589
- Sigstore integration time:
-
Permalink:
lvlrSajjad/cbomctl@4a8909ccedb75f237119b451d5c457089d46ee30 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lvlrSajjad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a8909ccedb75f237119b451d5c457089d46ee30 -
Trigger Event:
push
-
Statement type: