Files and how to run them
The machine-readable artifacts that constitute the example, together with the commands used to reproduce the conformance verdicts.
Artifacts
| File | Description |
|---|---|
| profile-interface-enumeration.rules.json | The entry profile of the interface family: the shallowest set of rules that still produces a usable inventory record. See Maturity |
| profile-interface-disclosure.md | Prose profile specification (product-level and per-interface rules) |
| profile-interface-disclosure.rules.json | Machine-readable rules, including the appliesTo version range |
| profile.schema.json | The shape of a rules file, so a third party can validate a profile without our checker. Not a substitute for C1 to C17: a schema can see that objective has a decision string, not whether the decision is one a consumer could act on |
| claim.schema.json | The shape of a conformance claim, including the two consistency rules a schema can enforce — a refused entry carries no rule results, and an entry claiming conformance may not list a failed MUST |
| claim-example.json | A worked claim over both example profiles at once, bound to cbom-pqc-pass by digest |
| mapping-cyclonedx-spdx.md | Complete requirement-to-format mapping |
| cbom-pass.cyclonedx.json | Conforming example CBOM (CycloneDX 1.7) |
| cbom-fail.cyclonedx.json | Non-conforming example; omits the management interface |
| cbom-disclosure.cyclonedx.json | Non-conforming example exercising all four disclosure outcomes on one interface: a withheld library (permitted), an encryption algorithm declared unknown, an undeclared authentication algorithm, and a key exchange disclosed normally |
| cbom-noadmin.cyclonedx.json | Conforming example with no management interface at all: a library with no configuration surface, satisfying product rule P2 by stating the absence rather than by having one |
| cbom-entry-fail.cyclonedx.json | Roughly what a scanner emits with no profile in mind. Valid CycloneDX, and below even the entry profile: it identifies no subject, states no completeness, classifies no interface and says nothing about where the reading came from |
| profile-pqc-migration.rules.json | The PQC migration profile, derived from the baseline via extends |
| cbom-pqc-pass.cyclonedx.json | Conforming example for the migration profile; three interfaces at different readiness stages |
| cbom-pqc-fail.cyclonedx.json | Non-conforming example exercising both conditional rules and the inherited-rule tightening |
| validate_cbom.py | Version-aware validator with profile composition. Checks a document against a profile |
| check_profile.py | Well-formedness checker. Checks a profile against requirements C1 to C17 of Conformance |
| versioning-and-legacy-cboms.md | Treatment of older CBOM files |
Running the validator
# conforms (CycloneDX 1.7)
python validate_cbom.py cbom-pass.cyclonedx.json profile-interface-disclosure.rules.json
# does not conform; fails product rule P2 (no management interface)
python validate_cbom.py cbom-fail.cyclonedx.json profile-interface-disclosure.rules.json
# the same document at the family's entry depth, which does not require a
# management interface: conforms. See Maturity.
python validate_cbom.py cbom-fail.cyclonedx.json profile-interface-enumeration.rules.json
# JSON output, for integration into a continuous-integration gate
python validate_cbom.py cbom-pass.cyclonedx.json profile-interface-disclosure.rules.json --json
Reproducing the version bands
# four bands need four inputs: 1.7 is the tested version, and these are the rest
python - <<'PY'
import json
b = json.load(open("cbom-pass.cyclonedx.json"))
for v in ("1.8", "1.6", "1.5"):
b["specVersion"] = v
json.dump(b, open(f"cbom-{v}.json", "w"))
PY
python validate_cbom.py cbom-pass.cyclonedx.json profile-interface-disclosure.rules.json # target: exit 0
python validate_cbom.py cbom-1.8.json profile-interface-disclosure.rules.json # newer: accepted, review advised, exit 0
python validate_cbom.py cbom-1.6.json profile-interface-disclosure.rules.json # legacy: accepted with a warning, exit 0
python validate_cbom.py cbom-1.5.json profile-interface-disclosure.rules.json # refused: not assessed, exit 4
The last of these is the one worth running. A refusal is not a failure: the document was never assessed, so it exits 4 rather than 1, and no rule result is reported for it. A pipeline that treats any non-zero exit as a rejection will turn the age of a carrier format into a supplier's problem, which is what the distinct code exists to prevent.
The derived profile
The PQC migration profile extends the baseline, so evaluating against it also evaluates every baseline rule. The validator resolves the base, applies the overrides, and rejects any override that would relax an inherited rule.
# conforms
python validate_cbom.py cbom-pqc-pass.cyclonedx.json profile-pqc-migration.rules.json
# does not conform, for three separate reasons
python validate_cbom.py cbom-pqc-fail.cyclonedx.json profile-pqc-migration.rules.json
The failing document is worth reading alongside its verdict. Two failures come from conditional rules: an interface claiming enablement by software update without naming the version (pqc-migration#I5), and one declaring a capability committed for key establishment without saying what blocks it (pqc-migration#G1.2). Two more come from the group rule: a purpose the profile takes in scope with no entry at all, and a purpose it defers with no entry either — a deferred purpose still owes a status. The last arises from the extension itself. Its interconnect interface withholds implementationPurl, which the baseline permits. Evaluated against the baseline alone that document conforms; it fails here only because the derived profile removed withholdability from that rule.
# the same document against the base profile, which permits the withheld value
python validate_cbom.py cbom-pqc-fail.cyclonedx.json profile-interface-disclosure.rules.json
Checking a profile
A profile is itself checkable, against requirements C1 to C17 of Conformance. C1 to C7 and C11 to C17 are MUST requirements and determine the result; C8 to C10 are reported as warnings unless --strict is given.
# all three example profiles are well-formed
python check_profile.py profile-interface-enumeration.rules.json
python check_profile.py profile-interface-disclosure.rules.json
python check_profile.py profile-pqc-migration.rules.json
# require the SHOULD material as well: exclusions, companion artifacts, changelog
python check_profile.py profile-interface-disclosure.rules.json --strict
# machine-readable findings
python check_profile.py profile-pqc-migration.rules.json --json
The test suite carries one deliberately defective profile per MUST requirement, so that each check is itself tested. See tests/fixtures/ and tests/README.md in the repository.