Skip to content
Novus Examples
md2.1 KB

SBOM Format Crosswalk (CycloneDX to SPDX)

The field-by-field map between the CycloneDX 1.6 and SPDX 2.3 documents in this category, plus the five invariants a correct conversion preserves and the three things it legitimately loses. Every package, version, hash and licence is fictional — the tree describes nothing real.

Preview — first 32 linesmd
# SBOM format crosswalk — CycloneDX 1.6 vs SPDX 2.3

> SAMPLE — fictional supply-chain data. Every package, registry, version, hash, licence, advisory identifier and signature in this document is invented.

Both serialisations in this category describe the same fictional tree: `orchard-gateway` 4.2.0 and nine invented dependencies. This table is the field map a converter has to implement, and the checklist to diff a conversion against.

| Concept | CycloneDX 1.6 | SPDX 2.3 | Value in these fixtures |
| --- | --- | --- | --- |
| Document id | `serialNumber` (urn:uuid) | `documentNamespace` + `SPDXID` | distinct per file, derived from a fixed seed |
| Root subject | `metadata.component` | `documentDescribes` / DESCRIBES | `@orchard-example/gateway` 4.2.0 |
| Component id | `bom-ref` (purl) | `SPDXID` (`SPDXRef-Package-*`) | one per package |
| Package URL | `purl` | `externalRefs` PACKAGE-MANAGER/purl | identical strings |
| Licence | `licenses[].license.id` or `.expression` | `licenseConcluded` / `licenseDeclared` | same SPDX ids |
| Integrity | `hashes[].alg` + `.content` | `checksums[].algorithm` + `.checksumValue` | same SHA-256 hex |
| Graph edge | `dependencies[].dependsOn` | `Relationship … DEPENDS_ON …` | 10 edges |
| Supplier | `supplier.name` | `PackageSupplier: Organization:` | Example Softworks (fictional) |
| Vulnerabilities | `vulnerabilities[]` (VEX in BOM) | separate VEX/CSAF document | 4 SAMPLE advisories |

## What a correct conversion preserves

1. Component count: **9** dependencies plus the root application.
2. Edge count: **10** dependency relationships.
3. The two diamonds — `example-logger@3.4.1` reached by three parents, `example-json-path@2.0.5` by two — stay single nodes.
4. Every SHA-256 value is byte-identical across formats.
5. Compound licence expressions are not flattened to a single identifier.

## What it legitimately loses

- CycloneDX `services` and `compositions` have no direct SPDX 2.3 equivalent.
- SPDX `snippets` have no CycloneDX equivalent.
- SPDX `LicenseRef-*` extracted text must be carried as a CycloneDX `licenses[].expression` plus a property, or it is dropped.

Specifications

Seed
51200
Sample Only
true
Format
Markdown
Mapped Fields
9
Invariants
5
Line Endings
LF

Testing contract

Reference control
Scenario
Score an SBOM converter against a documented expectation instead of eyeballing the output.
Expected result
A conversion that keeps 9 components, 10 edges, both diamonds, identical SHA-256 values and unflattened licence expressions passes all five invariants.

What is a .md file?

Markdown (MD) is a lightweight plain-text markup language that uses simple punctuation conventions to denote headings, lists, links, emphasis, and code. It is designed to be readable as-is and to convert cleanly to HTML. It is widely used for documentation, READMEs, and content authoring.

How to use this file

Use an example Markdown file to test parsers and renderers, verify GitHub-Flavored Markdown extensions like tables and fenced code, and exercise HTML-conversion pipelines.

How to use this file for testing

“SBOM Format Crosswalk (CycloneDX to SPDX)” is a deterministic Novus Examples fixture for Conversion testing, Editor testing. The same content exported across many formats and linked as a group, so you can convert one and diff against the expected twin.

Documented properties for this file: seed 51200 · LF · Markdown. Compare results against paired or grouped companions on this page when present (clean↔damaged, searchable↔scanned, or format twins) so scores stay reproducible across runs.

Download the file once, keep the path stable in CI or local scripts, and treat the spec table as the contract: dimensions, seeds, field lists, and roles are intentional. Corrupt or invalid samples are labelled as such — expect parsers to fail loudly rather than silently accept them.

SBOM, lockfile, provenance, and advisory fixtures describe the same fabricated component tree across formats, so a converter or scanner can be diffed against a known answer. Every package name, version, hash, and advisory ID is invented — never treat a finding here as real.

Code examples

import markdown  # pip install markdown

html = markdown.markdown(open("sbom-format-crosswalk.md").read())
print(html[:200])

Generated by generation/supply_chain.py. Free for any use, no attribution required — license.