skip to content

What is lost when you convert a CycloneDX BOM with an inline vulnerabilities array into SPDX?

level: seniorimportance: should knowfreq 38%

answer

  1. one format grew from compliance, one from security
  2. no vulnerability object to land in
  3. a link is not a record
  4. pedigree and completeness vanish too
  5. the supplier signed the original bytes

basics

~20 s

The vulnerability records themselves. SPDX 2.x has no object to hold a vulnerability record, so a converter either drops the array or degrades it to an external link. Pedigree, composition-completeness and service entries have no clean home either.

solid answer

~50 s

CycloneDX carries constructs SPDX 2.x simply has no place for: an inline `vulnerabilities` array with identifiers, sources and ratings, a `pedigree` block describing ancestry, variants and applied patches, a `compositions` statement about how complete the listing is, and a `services` array. A converter can point at an advisory through an SPDX external reference of the security category, but a link is not the record — the ratings, the affected-range detail and the vendor's analysis do not survive. Two second-order losses matter more in practice. First, any signature over the supplier's original bytes does not transfer: the converted document is your assertion, not theirs. Second, the loss is silent, because the output validates. So I keep the received document as the system of record, treat the converted copy as a derived view, and record which tool produced it.

go deeper

for a junior

Know that the two formats are not interchangeable and that converting between them can drop information, so the file you received is worth keeping.

for a middle

Name concrete constructs that fail to map — inline vulnerability records, pedigree, completeness statements — and explain why an external link is weaker than the record it replaces.

for a senior

Show the operational discipline: retain the received document and its signature, make the converter report what it dropped, and never let a derived copy become the system of record.

for a principal

Own the estate decision. Normalising to one format buys tooling simplicity and costs supplier fidelity; the defensible position is to store originals plus a derived index, and to say so in the supplier agreement.

## Why this comes up Estates standardise. A platform team picks one BOM format for its store, and suppliers send whatever their build produces. Conversion becomes routine, and because both formats describe *components in an artifact*, people assume it is a re-encoding like YAML to JSON. It is not. The formats have different centres of gravity — one grew out of license and compliance documentation, the other out of security tooling — and each has constructs the other never modelled. ## What CycloneDX carries that SPDX 2.x has no object for - **`vulnerabilities`** — an inline array of vulnerability records, each with identifiers, the source that published them, severity ratings, affected components and, optionally, an analysis block. SPDX 2.x has no vulnerability object at all. The closest thing is an external reference in the security category, which can link to an advisory. A link is a pointer, not the record: the ratings, the affected-version detail and the supplier's own assessment do not travel with it. Later SPDX work introduces a security-oriented profile, but a converter targeting the 2.x documents most tooling emits and consumes has nowhere to put this data today. (What the analysis block *says* about exploitability is its own topic; here the point is purely structural — the target format has no field.) - **`pedigree`** — ancestry, variants, commits and applied patches for a component. This is precisely the information that tells you a component is not the upstream release but a modified build, which is exactly what makes name-based matching go wrong. Losing it makes a rebuilt or patched component look pristine. - **`compositions`** — a document-level statement of how complete an assembly or dependency listing is. Losing it converts *this listing is incomplete* into no statement at all, which readers will interpret as complete. - **`services`** — endpoints an application talks to, which have no package-shaped equivalent. ## What SPDX carries that CycloneDX degrades The loss is not one-directional. - The **typed relationship vocabulary** collapses toward a single dependency edge, so containment, generation and linkage nuance flatten. - The **NONE versus NOASSERTION** distinction disappears, because CycloneDX expresses unknowns by omitting optional fields; an explicit refusal to assert and a field that was never populated become indistinguishable. - **Annotations** — reviewer comments attached to elements — have no direct equivalent. So neither direction is a safe one-way archive. ## The two losses people forget **Signatures do not survive.** If the supplier signed the document they sent you, that signature is over those bytes. Your converted SPDX is a new document, signed by nobody or, worse, re-signed by your own pipeline — at which point your organisation is vouching for a claim the supplier never made, in a document that says less than theirs did. The rule follows directly: keep the received artifact, verify it in the form it was received, and treat any converted copy as a derived view. **The loss is silent.** The converter emits a schema-valid document. Nothing fails. A year later an audit asks why your record of a supplier component shows no applied patches and no vulnerability history, and the answer — the format we normalise into cannot represent those — is a bad answer to have to give about your own system of record. ## How to run conversion responsibly 1. **Keep the original.** Store the received document verbatim alongside any derived form, together with the signature or attestation that came with it. 2. **Make loss loud.** Have the conversion step report what it could not map: counts of dropped vulnerability records, pedigree blocks, composition statements, and edges whose type it had to weaken. Silence should not be the default output. 3. **Record the transformation.** Both formats have a place to record the tools that produced a document. Write the converter and direction there so a reader can tell a derived document from a first-party one. 4. **Carry the unmappable data beside, not inside.** Vulnerability and exploitability information can travel as its own signed document referencing the same subject; forcing it into a format with no field for it is how it gets dropped. 5. **Do not convert twice.** A round trip through two lossy mappings compounds, and the result is often confidently wrong rather than obviously empty. ## The judgment being tested An interviewer asking this wants to hear that you treat a supplier BOM as *evidence you received* rather than *data you own*. Candidates who answer only *some fields do not map* have described a format problem. Candidates who add *and the thing we keep is no longer the thing they vouched for* have described the security problem, which is the one that matters when someone later has to prove what a supplier actually stated.

  • Your supplier signed the CycloneDX document they sent. What happens to that signature when your pipeline converts it to SPDX?
    It does not transfer. The signature covers the bytes the supplier produced; the converted document is a different artifact, so at best it is unsigned and at worst your pipeline signs it, making your organisation the asserting party for a claim the supplier never made. Verify and retain the original as received, and treat the conversion as a view.
  • Which direction of conversion loses more?
    It depends on what the source document actually populated. Going to SPDX 2.x, the security-oriented constructs — vulnerability records, pedigree, composition completeness — have no target object. Going the other way, the typed relationship vocabulary and the explicit NONE versus NOASSERTION distinction degrade. Neither direction is safe as a one-way archive.
  • How would you make conversion loss visible rather than silent?
    Have the conversion step emit a report: how many components and edges went in and came out, which constructs had no mapping, and which edge types were weakened. Fail loudly when a populated source construct has no target field rather than dropping it. Record the converter and direction in the document's tool metadata so readers can tell derived from first-party.
  • A vendor's BOM also carries an external-reference block. Does that survive?
    Partially. Both formats have external-reference constructs, but their category and type vocabularies differ, so references map unevenly and some are reduced to a bare URL with the reason for the link lost. It is a good example of a construct that appears to convert cleanly while quietly losing its meaning.

saying these in an interview costs you the question

  • Calls conversion a pure re-encoding between formats
  • Claims SPDX 2.x can carry vulnerability ratings inline
  • Says an advisory link preserves the vulnerability record
  • Discards the received original and keeps only the converted copy
  • Re-signs a converted document as if it were the supplier's claim

context