Skip to content

Navigation Menu

Sign in
Sign up

Add sample PQC readiness perspective for CBOM - #960

Open
bhess wants to merge 3 commits into
CycloneDX:2.0-dev from
bhess:bhe-pqc-perspective
Open

Add sample PQC readiness perspective for CBOM #960
bhess wants to merge 3 commits into
CycloneDX:2.0-dev from
bhess:bhe-pqc-perspective

Conversation

@bhess

@bhess bhess commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Adds a sample perspective demonstrating how the perspective model can apply in a CBOM context, using PQC readiness as the example. It lives in a new perspectives/ folder, as discussed in the last Cryptography WG meeting.

The mappings also exercise a proposed expectation field (values are present or absent) on perspective mappings that turns a descriptive mapping into a machine-checkable assertion. That field is not yet in the 2.0 schema, so the sample is illustrative pending that discussion.

bhess requested a review from a team as a code owner June 25, 2026 12:29
bhess changed the base branch from master to 2.0-dev June 29, 2026 12:05
Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
bhess force-pushed the bhe-pqc-perspective branch from bca039c to 68d3377 Compare June 29, 2026 12:08

Copy link
Copy Markdown
Contributor

Hi,
I was reading this PR against #947.

Since changeMechanism is now an array, would "includes runtime-config" fit the rationale better than "runtime-config or restart-required"? Multiple values now mean required steps rather than alternatives.

And if #947 lands first, I assume the path should move from cryptoProperties.agility to component.agility — is that right?

The inventory/algorithm/agility split makes sense to me. One thing I wondered: should primitive: "unknown" / "other" be treated like missing primitive for the inventory check? And whether protocol cipher suites or cert->signing-algorithm linkage are in scope for a later revision.

I also couldn't find perspective-expectation-rationale.md in this PR — is it planned elsewhere, or should the reference in the description come out for now?

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
bhess force-pushed the bhe-pqc-perspective branch from 7750dd2 to bebabfd Compare July 16, 2026 11:37

bhess commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the good feedback @Mehrn0ush .

Since changeMechanism is now an array, would "includes runtime-config" fit the rationale better than "runtime-config or restart-required"? Multiple values now mean required steps rather than alternatives.

Changed the wording accordingly.

And if #947 lands first, I assume the path should move from cryptoProperties.agility to component.agility — is that right?

I agree, Changed the path accordingly to component.agility.

The inventory/algorithm/agility split makes sense to me. One thing I wondered: should primitive: "unknown" / "other" be treated like missing primitive for the inventory check? And whether protocol cipher suites or cert->signing-algorithm linkage are in scope for a later revision.

I agree, modified the rule to exclude "unknown". I think cert algorithms could be valuable as well, need to brainstorm a bit how to implement this as a JSON path expression since this needs bom-ref matching.

I also couldn't find perspective-expectation-rationale.md in this PR — is it planned elsewhere, or should the reference in the description come out for now?

Right, the reference is removed now.

Copy link
Copy Markdown

@bhess I'd appreciate if you can take a look at #1067 - if this aligns with your vision here.

@jkowalleck jkowalleck added this to the 2.0 milestone Aug 31, 2026
taleodor-claude pushed a commit to relizaio/cyclonedx-specification that referenced this pull request Sep 3, 2026
...ract in CI
The registry data file is hand-maintained (no generator), so until now
nothing asserted that it actually conforms to its governing schema or that
the hand-kept enum stays in step with the entries. Add a registry test to
the schema-v2 suite (picked up by `npm test` via the `test:*` glob, so the
existing JavaScript CI workflow runs it on every pull request):
- schema/perspectives-defs.json validates against
 schema/perspectives-defs.schema.json (strict ajv, draft-07 meta-schema,
 formats enabled).
- preDefinedPerspectivesEnum and the entries' `predefined` values are the
 same set, with no duplicates on either side; the message names which
 file to fix.
- every entry's `file` points under perspectives/. A missing document only
 warns, so an identity can be reserved ahead of its catalog document
 (pqc-readiness, CycloneDX#960). An existing document must
 be JSON, declare an integer `version` >= 1 (the value a reference's
 `predefinedVersion` selects), define at least one perspective, and define
 it inline (no `predefined`/`predefinedVersion`), since catalog entries are
 the published definitions, not references.
The test is not versioned (`-v`) because the registry lives at the schema
root and is shared across specification versions.
Verified: suite green; each check fails on a tampered input (unknown
identity/missing file in data, enum drift, catalog document in reference
form, catalog document without version).
taleodor pushed a commit to relizaio/cyclonedx-specification that referenced this pull request Sep 4, 2026
...d references, standalone registry
* feat(perspective): namespace pre-defined perspective identities under cdx:perspectives:
Per review on CycloneDX#1067: prefix the pre-defined
perspective enum values with the reserved cdx: namespace and a
cdx:perspectives: path, so 'model-card' becomes
'cdx:perspectives:model-card' and 'pqc-readiness' becomes
'cdx:perspectives:pqc-readiness'. This aligns the identities with the
reserved CycloneDX property taxonomy and keeps them collision-free with
author-chosen names.
Updates the enum, its meta:enum keys, the field description, and the
valid/invalid test fixtures accordingly.
* feat(perspective): version pre-defined perspective references (registry model)
Per Steve's review on CycloneDX#1067: adopt a registry model
for pre-defined perspectives, referenced by identity plus version.
- Add a required sibling 'predefinedVersion' (integer, minimum 1) on the
 reference form. It selects the published revision of the perspective and
 is the 'version' of the catalog document that defines it; like other
 CycloneDX version fields it increments by 1 per revision. Pinning it
 keeps a reference stable as the catalog perspective evolves.
- The reference form now requires both predefined and predefinedVersion
 (and still forbids all inline content but bom-ref); the inline form
 forbids both.
- The 'predefined' enum stays ids-only, hand-maintained inline (the
 registry is this id list plus the versioned catalog files) -- no
 separate data file or generator, unlike the crypto family registry,
 since the set is small and curated and version is not schema-enumerated
 per id (mirroring how crypto validates the family but not the parameter
 set).
Fixtures: valid reference form gains the version; the unknown-id,
annotated and mixed invalid cases gain it so each isolates its intended
violation; new invalid fixture covers a reference missing the required
version.
* feat(perspective): move pre-defined perspective registry into a standalone defs file
Decouples the pre-defined perspective lifecycle from the specification
release cycle, the same way the cryptography algorithm registry is
handled: perspectives can be added or revised, and new catalog document
versions published, by editing the registry alone -- no change to the
versioned specification schemas.
- New schema/perspectives-defs.schema.json: a single registry file
 holding the reserved identity enum (definitions.preDefinedPerspectivesEnum)
 and the identity-to-catalog-document map (definitions.catalog, id ->
 document path under perspectives/). Kept to one file, no separate data
 file or generator (the set is small and curated, unlike the ~100-entry
 crypto family registry that justifies generation).
- cyclonedx-perspective-2.0.schema.json: 'predefined' now the
 external enum (../../perspectives-defs.schema.json#/definitions/
 preDefinedPerspectivesEnum) instead of an inline enum; the inline
 preDefinedPerspective def is removed.
- bundler: perspectives-defs.schema.json added to the external ref
 exceptions so it stays external in the bundle (like cryptography-defs).
- schema-v2 validate + functional harnesses: load and register the new
 external schema so refs resolve.
The registry data is expressed with schema keywords (const-valued map
entries) so the single file remains a valid JSON Schema under the
harness's ajv strict mode. Bundled schemas left to the post-merge
workflow.
* refactor(perspective): split pre-defined registry into data file + governing schema
Follows the crypto registry's file split so the registry data has a real,
checkable contract (the previous single file invented an unvalidated
const-map convention).
- schema/perspectives-defs.json: the registry DATA, hand-edited (no
 generator). Each entry is a proper object: predefined (the reserved
 identity, matching the CycloneDX perspective 'predefined' field),
 file (catalog document path), and description. Declares its governing
 schema via $schema.
- schema/perspectives-defs.schema.json: now a governing meta-schema that
 defines the data file's shape (perspectives[] of {predefined, file,
 description}, predefined constrained to preDefinedPerspectivesEnum) and
 still exposes preDefinedPerspectivesEnum for the specification schema to
 $ref. Identities are entry values, not object keys.
Data edits stay manual, matching how the crypto data file is maintained;
the enum in the governing schema is kept in sync by hand (the set is
small and curated). Verified the data file validates against the
governing schema, and the schema-v2 suite passes.
* test(perspective): enforce the pre-defined perspectives registry contract in CI
The registry data file is hand-maintained (no generator), so until now
nothing asserted that it actually conforms to its governing schema or that
the hand-kept enum stays in step with the entries. Add a registry test to
the schema-v2 suite (picked up by `npm test` via the `test:*` glob, so the
existing JavaScript CI workflow runs it on every pull request):
- schema/perspectives-defs.json validates against
 schema/perspectives-defs.schema.json (strict ajv, draft-07 meta-schema,
 formats enabled).
- preDefinedPerspectivesEnum and the entries' `predefined` values are the
 same set, with no duplicates on either side; the message names which
 file to fix.
- every entry's `file` points under perspectives/. A missing document only
 warns, so an identity can be reserved ahead of its catalog document
 (pqc-readiness, CycloneDX#960). An existing document must
 be JSON, declare an integer `version` >= 1 (the value a reference's
 `predefinedVersion` selects), define at least one perspective, and define
 it inline (no `predefined`/`predefinedVersion`), since catalog entries are
 the published definitions, not references.
The test is not versioned (`-v`) because the registry lives at the schema
root and is shared across specification versions.
Verified: suite green; each check fails on a tampered input (unknown
identity/missing file in data, enum drift, catalog document in reference
form, catalog document without version).
* test(perspective): register the perspectives registry schema in the Java 2.x harness
The Java schema-v2 verification harness resolves external schema URIs
through an explicit classpath mapping and disallows anything else, so the
perspective schema's $ref to perspectives-defs.schema.json failed to load
("Schema from 'https://cyclonedx.org/schema/perspectives-defs.schema.json'
is not allowed to be loaded"), erroring the five perspective fixtures.
Map the http/https URIs of perspectives-defs.schema.json to the classpath
copy (schema/ is already a test resource root), alongside the existing
cryptography-defs and behavior-taxonomy mappings.
Verified: `mvn clean test -Pschema-v2-tests` green locally (229 tests,
0 errors).
* feat(perspective): generate the pre-defined perspectives registry and enforce immutable published versions
The registry data (schema/perspectives-defs.json) is now GENERATED, in the
spirit of the crypto registry's generator, and published perspective
versions become immutable:
- Naming convention replaces any mapping: the catalog document defining
 `cdx:perspectives:<name>` is `perspectives/<name>-perspective.json`.
 Identities are lowercase-kebab-case. The identity enum in the governing
 schema stays hand-maintained (now with meta:enum descriptions, so a
 reserved identity without a document still has one).
- Registry entries are objects {predefined, file, name, description,
 versions[]}; each version record is {version, sha256, commit, date}:
 sha256 of the catalog document's canonical JSON (keys sorted, no
 whitespace, so formatting-only edits do not count as changes), the last
 commit touching the document, and that commit's UTC date. `name` and
 `description` are copied from the document at the latest version.
 lastUpdated is the newest registered date (deterministic).
- tools/src/main/js/perspectives-registry/: shared module (convention,
 canonical hash, structural checks, version-state assessment) used by both
 the generator and the test, plus generate-perspectives-registry.js. The
 generator only appends unregistered versions (a new perspective at
 version 1, or registered latest + 1); it refuses content changed at a
 registered version, regressed or skipped versions, removed registered
 documents, documents not defining exactly one inline perspective, and
 identities violating the convention. Idempotent when nothing changed.
- .github/workflows/generate_perspectives_registry.yml: on push to
 master/main/2.0-dev touching perspectives/**, the governing schema, or
 the generator, runs the generator and commits the registry directly
 (with a skip-ci marker), mirroring bundle_2.0_schemas.yml. A failing generator (change
 without bump merged over a red check) fails the workflow.
- The schema-v2 registry test now shares that logic and checks every
 identity in the enum: reserved, new, unchanged and pending (latest + 1)
 pass; modified, regressed, skipped and removed fail. It also checks
 registered entries follow the convention and list contiguous versions
 from 1, and that every registered identity is in the enum.
- Governing schema rewritten for the generated shape (patterns for file,
 sha256, commit; date-time dates; versions minItems 1).
- Perspective schema: `predefined` description now states the naming
 convention instead of a mapping.
Initial registry generated from this branch: model-card version 1 at
ebb5184 (the commit is fork-side provenance; the hash is the check key).
Verified: JS schema-v2 suite green; Java schema-v2 suite green (229 tests);
bundler unchanged (registry ref stays external); no new lint findings on
the perspective schema. Test and generator both reject each tampered
input: content change at a registered version, skipped/regressed version,
removed document, non-contiguous registry versions, non-convention
identity, document with two perspectives; a version bump registers cleanly
and formatting-only edits are accepted.
* feat: create generate_perspectives_registry.yml to generate perspectives defs PR
Signed-off-by: Pavel Shukhman <taleodor@users.noreply.github.com>
* fix: switch generate_perspectives_registry.yml to perspectives code
Signed-off-by: Pavel Shukhman <taleodor@users.noreply.github.com>
---------
Co-authored-by: Claude Code (ReARM Agent) <rearm-agent-claude@reliza.io>
Co-authored-by: Pavel Shukhman <taleodor@users.noreply.github.com>
Signed-off-by: Pavel Shukhman <taleodor@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

Projects

None yet

Milestone

2.0

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /