Cyclonedx SBOM files do not pass cyclonedx cli validate command when SMAIL-GPL included as licenses

I am using syft version 1.32.0 to scan docker images but the resulting files do not pass validation by dependency-tracker nor by the cyclonedx-cli, so I can’t really use them, e.g. :

$> syft scan docker:nginx -o cyclonedx-json >sbom.json
$>  cyclonedx validate --input-file temp.json          
Validation failed:
Expected 1 matching subschema but found 0
http://cyclonedx.org/schema/bom-1.6.schema.json#/definitions/licenseChoice
On instance: /components/12/licenses:
[{"license":{"id":"GPL-2.0-only"}},{"license":{"id":"GPL-2.0-or-later"}},{"license":{"id":"SMAIL-GPL"}},{"license":{"name":"public-domain"}}]
Value should have at most 1 items
http://cyclonedx.org/schema/bom-1.6.schema.json#/oneOf/1
[...]
Unable to validate against any JSON schemas.
BOM is not valid.

From what I understand I would need to modify the sbom file after generation to fix the license issues in a post process step, but I was wondering if there is a simpler solution around this problem?

Hi @Diamantis_Sellis,

It looks to me like maybe there are some SPDX expressions Syft uses that CycloneDX doesn’t accept.

Here’s a one line repro script that might help people investigating in the future:

syft -o cyclonedx-json docker:nginx:latest | docker run -i --platform linux/amd64 cyclonedx/cyclonedx-cli:latest validate --input-format json

Based on the complaints, it looks to me like there are several ways of representing licenses in CycloneDX JSON, and Syft doesn’t seem always to choose the right one: CycloneDX v1.6 JSON Reference

We’ll take a look. Thanks for the report!

@Diamantis_Sellis

I think cyclonedx and dependency-tracker need to roll forward in their schema validation here.

If you remove this item from the license list then the document becomes “valid” (note I think it’s insane that you should have to remove this item for a valid document but that’s besides the point). You can also change “id“ → “name“ for SMAIL-GPL and see a valid document as well (also insane).

    {
      "license": {
        "id": "SMAIL-GPL"
      }
    },

After removing the `SMAIL-GPL` licenses from .components[12] or changing id → name the tool runs “successfully“

cat test.json | docker run -i --platform linux/amd64 cyclonedx/cyclonedx-cli:latest validate --input-format json
BOM validated successfully.

This is a valid spdx license ID. See list below and ctrl-f “SMAIL-GPL“

Syft generates documents with licenses that are valid SPDX ID. The only way for that “id“: “<SPDX-ID>“field to be populated is if it comes from here which we generate from the spdx license list.

Cyclone-DX and dependency track need to make sure their enums for validation ALSO are tracking valid IDs and keeping up to date with the spdx licenses list above.

Their validation output is very confusing and non intuitive, but basically you need to start from the bottom, “fix“ that suggestion, and see if the other logs above it were noise caused by the initial validation error.

On instance: /components/12/licenses/2/license:
{"id":"SMAIL-GPL"}
Value should match one of the values specified by the enum
http://cyclonedx.org/schema/spdx.schema.json
On instance: /components/12/licenses/2/license/id:
SMAIL-GPL
Unable to validate against any JSON schemas.
BOM is not valid.

Their current schema includes this as a valid ID so I’m not sure why their validation tooling or dependency track are out of sync with these enums:

https://cyclonedx.org/schema/spdx.xsd

I’m actually very confused here since: https://cyclonedx.org/schema/spdx.schema.json includes the correct ID, but the validator tooling says the below error, which is triggering the “invalid“ state.

I’ve filed an issue with their CLI team. I think someone should also file one with dependency track as well.

{“id”:“SMAIL-GPL”}
Value should match one of the values specified by the enum (see above link)
On instance: /components/12/licenses/2/license/id:
SMAIL-GPL
Unable to validate against any JSON schemas.
BOM is not valid.

If I have some time later I’ll dig into the validator code on the cyclonedx cli side and see why it’s not resolving the latest SPDX list they have at runtime and where it’s getting the outdated data from.

See my above comment - I followed up with their validator tool here:

Similar linked dependency track issue: