Skip to content

sbom-cataloger merges packages from different SBOM documents that share an SPDX IDΒ #5525

Open

Description

@mprpic

What happened:

When a scanned directory contains several SPDX documents, the sbom-cataloger merges packages from different documents that use the same SPDXID. The merged package keeps the name, version and purl of one document, but collects the licenses and locations of all of them. The packages from the other documents are not reported.

SPDX element IDs only need to be unique within one document (SPDX 2.3, clause 7.2), so reusing an ID such as SPDXRef-Package across documents is valid. This happens in practice with Python wheels that embed PEP 770 SBOMs (*.dist-info/sboms/*.spdx.json) generated by a tool that uses fixed IDs. Scanning a site-packages directory then reports one package instead of one per wheel, with licenses from unrelated packages attached to it.

What you expected to happen:

One package per SPDX package element, each with only its own licenses and location, as when the IDs differ.

Steps to reproduce the issue:

Two SPDX documents describing different packages, both using SPDXRef-Package:

repro/alpha.spdx.json:

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "alpha-1.0",
  "documentNamespace": "https://example.com/spdx/alpha-1.0",
  "creationInfo": {"created": "2026-01-01T00:00:00Z", "creators": ["Tool: example"]},
  "packages": [
    {
      "SPDXID": "SPDXRef-Package",
      "name": "alpha",
      "versionInfo": "1.0",
      "downloadLocation": "NOASSERTION",
      "licenseDeclared": "MIT",
      "externalRefs": [{"referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", "referenceLocator": "pkg:pypi/alpha@1.0"}]
    }
  ],
  "relationships": [{"spdxElementId": "SPDXRef-DOCUMENT", "relationshipType": "DESCRIBES", "relatedSpdxElement": "SPDXRef-Package"}]
}

repro/beta.spdx.json: the same, with alpha β†’ beta, 1.0 β†’ 2.0 and MIT β†’ Apache-2.0.

$ syft scan dir:repro --override-default-catalogers sbom-cataloger -q
NAME   VERSION  TYPE
alpha  1.0      python

In the JSON output (-o syft-json), the single package is alpha 1.0 (pkg:pypi/alpha@1.0) with licenses ["Apache-2.0", "MIT"] and locations ["/alpha.spdx.json", "/beta.spdx.json"]. beta is missing.

With the IDs changed to SPDXRef-Package-alpha and SPDXRef-Package-beta, both packages are reported, each with its own license and location:

$ syft scan dir:unique --override-default-catalogers sbom-cataloger -q
NAME   VERSION  TYPE
alpha  1.0      python
beta   2.0      python

Anything else we need to know?:

The same happens when the documents describe the same package name and version with different data, e.g. two builds of one release from different indexes. Syft reports one package with the purl of the first document and the union of both documents' licenses. By contrast, the python-installed-package-cataloger reports one package per install location, even for identical installs.

Environment:

  • Output of syft version: 1.56.0 (ghcr.io/anchore/syft:latest, built 2026-11-02)
  • OS: Fedora 44 host, syft run in a container with podman

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions