[2.0] fixes on schema and test resources - #1001
Conversation
a03e560 to
905e58a
Compare
- [x] Java tests - functional - [x] JS tests - functional - WIP - found some false-positives/false-negatives - due to errors in test resources - [x] JS tests - schema validate - includes #996 - includes #992 - JS tests - semantics - [x] #998 - [x] #995 - [x] PHP tests - functional added tests only, no schema/res fixes - they are prepared in - #997 - #1001 --------- Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
There was a problem hiding this comment.
removed the test case, since the name was not required at all ...
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
|
had Fable 5 analyze the state of the schema. my query: report: CycloneDX 2.0 JSON Schema Structure ReviewScope: branch 1. Broken / fragile referencesAll intra-
2.
|
| Location | Issue | Suggested fix |
|---|---|---|
model/cyclonedx-common-2.0.schema.json#/$defs/organizationalEntityOrContact |
Literally {"$comment": "TODO"} — an unfinished stub. |
Implement or delete. |
model/cyclonedx-common-2.0.schema.json#/$defs/timestamp |
Unused, while 48 places across the corpus inline "format": "date-time" without a pattern. In 2020-12, format is annotation-only by default, so those 48 timestamps are effectively unvalidated, and the one def that does validate (format + pattern) is dead. |
Ref common#/$defs/timestamp everywhere (or delete it and accept format-only). |
model/cyclonedx-common-2.0.schema.json#/$defs/base64 |
Unused; common#/$defs/attachment declares encoding: enum ["base64"] but never validates content against this pattern. |
Wire it into attachment (e.g. via if/then on encoding) or delete. |
model/cyclonedx-common-2.0.schema.json#/$defs/baseObject |
The "mixin base object for all CycloneDX entities" (composes extensibleProperties) is dead code — nothing refs it. Consequence: only the document root composes extensibleProperties; every other object is closed with additionalProperties: false, so the ext:<namespace>:<name> extension mechanism is unusable anywhere except the BOM top level. |
Either have entity defs compose baseObject/extensibleProperties + unevaluatedProperties: false, or delete baseObject and document that extensions are root-only. |
4. Circular references & duplicate definitions
- File-level cycle:
cyclonedx-component-2.0.schema.json⇄cyclonedx-ai-modelcard-2.0.schema.json(component →modelCard,graphicsCollection; ai-modelcard →componentData). Fully resolvable for validators — not problematic, but worth knowing for code generators. Self-recursive defs (nestedcomponents,dependencygraph, etc.) are standard and fine. - Duplicate
$defsnames across files (14):dependency,flow,hashAlgorithm,identifier(×3),metadata,postalAddress,rating,requirement,requirements,risk,signatures,step,timestamp,trigger.- True concept duplicate:
postalAddressincommonvsparty— thepartyversion is a superset (addsisoCode,coordinates). Two competing address models. Fix: keep one (party's) and ref it; delete/alias the other. - Intentional but collision-prone:
hashAlgorithmandtimestampincyclonedx-jss_X590_2023_10deliberately differ fromcommon(IANA names / X.590 clause 6.1 millisecond rule). Fine semantically, but same-named defs across files will clash in naive bundlers/codegen. Fix: prefix jss defs (e.g.jssTimestamp) or namespace during bundling. - The rest (
dependencyin dependency vs requirement,flow,metadata,identifier,rating,risk,step,trigger, …) are genuinely different domain concepts sharing generic names — acceptable, same bundling caveat.
- True concept duplicate:
5. Draft 2020-12 correctness
- Metaschema validation: 0 violations in all 36 files. ✅
- Regex patterns: all
pattern/patternPropertiescompile. ✅ - Root composition (
unevaluatedProperties: false+allOf: [$ref → common#/$defs/extensibleProperties]): works as intended. In 2020-12,unevaluatedPropertiessees annotations frompatternPropertiesinside schemas reached throughallOf/$ref, soext:…properties are correctly allowed at the root while unknown properties are rejected. ✅ additionalProperties: false+allOfcombinations (e.g.component#/$defs/component,behavior#/$defs/behaviorGraph|behaviorNode,vulnerability#/$defs/presenceEvidence,threatcategories): verified that noallOfbranch introduces property names absent from the parent'sproperties— all branches arenot/if-thenconstraints on declared properties, so nothing is falsely rejected. ✅ However, this closes those objects toext:extensions (see §3baseObject) and mixes two closure idioms (additionalProperties: falsevs the root'sunevaluatedProperties: false). Suggested fix: standardise on one idiom per the intended extensibility model.$schemadeclarations: present and correct in every file. ✅ No legacy keywords (definitions, booleanexclusiveMinimum,additionalItems) anywhere. ✅ (cyclonedx-definition-2.0.schema.json#/$defs/definitionsis a def named "definitions", not the keyword — legal, mildly confusing.)specVersionis unconstrained:cyclonedx-2.0.schema.json#/properties/specVersionis required but has onlyexamples: ["2.0"]— any string validates. 1.x schemas pinned it withenum. Fix: add"const": "2.0"(or an enum/pattern).- Single-value enums (prefer
const):cyclonedx-2.0.schema.json#/properties/specFormat(["CycloneDX"]),ai-modelcard#/$defs/energyMeasure/properties/unit(["kWh"]),ai-modelcard#/$defs/co2Measure/properties/unit(["tCO2eq"]),common#/$defs/attachment/properties/encoding(["base64"]),evidence#/$defs/assessmentMethod/allOf/1/.../not(["filename"]). Cosmetic. jss…#/$defs/signatureObjectsetsunevaluatedProperties: true: redundant (open is the default) but intentional and documented via$commentciting X.590 clause 6.2. OK as-is.- Non-standard
meta:enumkeyword: used consistently and everymeta:enumkey set exactly matches its siblingenumvalues ✅ (established CycloneDX 1.6/1.7 convention).
6. Naming / structural inconsistencies
| Location | Issue | Suggested fix |
|---|---|---|
model/cyclonedx-jss_X590_2023_10-2.0.schema.json |
Not a typo: ITU‑T X.590 (2023‑10) is the JSON Signature Scheme (JSS) — distinct from X.509; common#/$defs/signatures even links the ITU X.590 publication. Only the style is inconsistent: underscores + embedded date vs the hyphenated, undated names of every other file. |
Optionally rename to e.g. cyclonedx-jss-x590-2.0.schema.json for consistency. |
jss signatureObject properties |
snake_case (hash_algorithm, public_key, cert_url, valid_from, …) vs camelCase everywhere else — intentional (X.590 wire format), but worth a $comment if not already obvious. |
Document; keep as-is. |
| Root container shape inconsistency | components, dependencies, compositions, vulnerabilities, controls, annotations, formulation, blueprints, citations, perspectives are arrays, but threats, risks, declarations, definitions, profiles are objects wrapping same-named arrays (bom.threats.threats[], bom.risks.risks[]). |
Accept (matches 1.6 declarations precedent) or flatten for uniformity; at minimum document the convention. |
26 of 307 $defs lack title |
e.g. common#/$defs/refType, refLinkType, component#/$defs/version, versionRange, componentData, composition#/$defs/aggregateType, formulation#/$defs/step, command, … |
Add titles for doc-generation consistency. |
schema/2.0/README.md |
Table references cyclonedx-api-2.0-bundled.schema.json, which does not exist. |
Create it or remove the row. |
schema/2.0/model/README.md |
Badly stale: lists 4 nonexistent files (cyclonedx-ai-model-parameters, cyclonedx-licensing, cyclonedx-patent-assertion, cyclonedx-patent-family) and omits ~16 real files (behavior, blueprint, business-objective, certification, citation, control, data, evidence, jss, party, perspective, physical, profile, requirement, risk, threat, usecase, weakness). |
Regenerate the model index. |
component#/$defs/component/properties/mime-type |
Kebab-case like legacy bom-ref; everything else camelCase. |
Accept as 1.x-compat or rename (mimeType) since 2.0 is a breaking release. |
7. Explicitly checked and found fine
- ✅ All 36 files parse as valid JSON and validate against the draft 2020-12 metaschema (0 errors).
- ✅ All intra-
schema/2.0$refs (file +#/$defs/...pointer) resolve; all pointers into external files (#/definitions/...) also exist. - ✅
$id↔ path/filename convention correct in all 36 files;$schemapresent everywhere. - ✅ No orphaned model files — every model file is reachable from the root schema.
- ✅ Root
unevaluatedProperties: false+allOf → extensiblePropertiescomposition behaves correctly under 2020-12 annotation rules. - ✅ No
additionalProperties: falseobject is broken by itsallOfbranches (no branch declares undeclared property names). - ✅ All regexes compile;
serialNumberurn:uuid pattern is correct;patternProperties^ext:...$anchored correctly. - ✅ No
requiredentries missing frompropertiesin closed objects; no duplicaterequiredentries; no unknownformatvalues; no$refsiblings that add conflicting constraints;meta:enumfully consistent withenumeverywhere;$defsnames uniformly lowerCamelCase. - ✅
jss_X590filename is not an X.509 typo — it correctly references ITU-T X.590 (JSS), edition 2023-10.
Priority fixes (summary)
- Fix
httpvshttps$idmismatch inschema/cryptography-defs.schema.jsonandschema/spdx.schema.json(breaks$id-based ref resolution from 2.0). - Resolve the dead extensibility design: orphaned
baseObject+ closed objects meansext:properties only work at the BOM root. - Implement or clearly stub
cyclonedx-api-2.0.schema.json; add the missingcyclonedx-api-2.0-bundled.schema.jsonor fix the README. - Finish or remove
common#/$defs/organizationalEntityOrContact(TODOstub); wire up or remove orphanedtimestamp/base64defs (and addpatternto the 48 unvalidateddate-timefields if strict validation is intended). - Constrain
specVersion(e.g.const: "2.0"). - Deduplicate
postalAddress(common vs party); regeneratemodel/README.md.
actions taken:
- will not do. the schema has an existing and working and in-use ID
- might consider - not in the scope of this PR
- out of scope for this PR
- out of scope of this PR
- not planned. it is a free string that needs to stay like this for compatibility reasons with future/previous releases.
-
postalAddress?? need to look into this - porobably out of the scope of this PR- out odscope - see [2.0] docs: update schema/2.0/model/README.md #1035
fixes or related to
additionalProperties=false#995requiredproperties actually exist #996bom-refmust be of typerefType#998see also:
besides those fixes above, this is in the PR:
refLinkTypeinherit explicitextensibleProertiesJSS$commentsextensiblePropertiesinvalid-component-choice-missing-name-2.0.json- as thenamewas optional or did not exist.❓ was this intentional/correct
tests for the things are based on: