Skip to content

feat(cyclonedx): use evidence.occurrences for file paths instead of FilePath property#10937

Open
kevglynn wants to merge 1 commit into
aquasecurity:mainfrom
kevglynn:contrib/9832-cyclonedx-occurrences
Open

feat(cyclonedx): use evidence.occurrences for file paths instead of FilePath property#10937
kevglynn wants to merge 1 commit into
aquasecurity:mainfrom
kevglynn:contrib/9832-cyclonedx-occurrences

Conversation

@kevglynn

@kevglynn kevglynn commented Jul 8, 2026

Copy link
Copy Markdown

Description

CycloneDX has a native field for recording where a component was found: evidence.occurrences (available since spec 1.5). Trivy currently records this in a proprietary aquasecurity:trivy:FilePath property instead.

This PR switches CycloneDX output to evidence.occurrences:

  • pkg/sbom/io/encode.go: no longer adds the FilePath property to component properties (the file path is already carried in core.Component.Files).
  • pkg/sbom/cyclonedx/marshal.go: marshals core.Component.Files paths as evidence.occurrences[].location.
  • pkg/sbom/cyclonedx/unmarshal.go: parses evidence.occurrences back into core.Component.Files, so re-scanning a Trivy SBOM preserves file paths.

Backward compatibility

  • pkg/sbom/io/decode.go still parses the aquasecurity:trivy:FilePath property, so SBOMs generated by older versions of Trivy keep working. Existing test fixtures using the old property (testdata/happy/bom.json, testdata/happy/group-in-name.json, fanal SBOM testdata, and the fluentd-multiple-lockfiles-cyclonedx.json integration fixture) are intentionally left unchanged so they keep covering this path.
  • A new fixture (testdata/happy/evidence-occurrences.json) covers the new path.
  • core.PropertyFilePath remains in duplicateProperties in the SPDX marshaler: when an older SBOM is rescanned, reuseExistingBOM() passes the original components (which still contain the property) directly to the marshaler, so the filter is still needed to prevent a duplicate FilePath annotation in SPDX output.
  • integration/testdata/fluentd-multiple-lockfiles-short.cdx.json.golden is intentionally not changed: that test scans an old-style SBOM and outputs CycloneDX via reuseExistingBOM(), which passes the original components through unchanged, so the old property is (correctly) preserved in that output.

Before

{
  "purl": "pkg:conda/openssl@1.1.1q",
  "properties": [
    {
      "name": "aquasecurity:trivy:FilePath",
      "value": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json"
    },
    {
      "name": "aquasecurity:trivy:PkgType",
      "value": "conda-pkg"
    }
  ]
}

After

{
  "purl": "pkg:conda/openssl@1.1.1q",
  "properties": [
    {
      "name": "aquasecurity:trivy:PkgType",
      "value": "conda-pkg"
    }
  ],
  "evidence": {
    "occurrences": [
      {
        "location": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json"
      }
    ]
  }
}

(Output of trivy rootfs --format cyclonedx on integration/testdata/fixtures/repo/conda.)

Related issues

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

Made with Cursor

…ilePath property

CycloneDX has a native field for recording where a component was found:
evidence.occurrences. Use it in CycloneDX output instead of the
proprietary aquasecurity:trivy:FilePath property.

The aquasecurity:trivy:FilePath property is still parsed when scanning
SBOMs generated by older versions of Trivy.

Close aquasecurity#9832

Co-authored-by: Cursor <cursoragent@cursor.com>
@CLAassistant

CLAassistant commented Jul 8, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@kevglynn

Copy link
Copy Markdown
Author

Hi @knqyf263 @DmitriyLewen — gentle ping when you have a moment.

CLA is signed and this is ready for review. The Test and Validate PR Title workflows are still waiting on first-time contributor approval, so CI hasn't run yet on our side.

Locally: mage lint:run (changed packages), mage test:unit, and all ./pkg/sbom/... tests pass. Before/after CycloneDX output is in the PR description.

Happy to adjust anything — especially around backward compat for old aquasecurity:trivy:FilePath SBOMs (addressed per review feedback on the prior attempt in #10377).

Thanks for your time!

@kevglynn

Copy link
Copy Markdown
Author

Note on golden file diffs

The large diffs in integration/testdata/conda-cyclonedx.json.golden and integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden are purely mechanical — the only change is:

  • aquasecurity:trivy:FilePath property removed from each component's properties array
  • evidence.occurrences block added to each component with the same path value

No other content was changed. These were regenerated via the patched binary against the same integration fixtures and roundtrip-verified.

(fluentd-multiple-lockfiles-short.cdx.json.golden is intentionally not changed — that test rescans an old-style SBOM via reuseExistingBOM(), which passes original components through unchanged, so the old property is correctly preserved.)

@DmitriyLewen

Copy link
Copy Markdown
Contributor

Hello @kevglynn

We're currently busy with other priority tasks.
I'll take a look at your PR a bit later.

Thanks for your work and your patience.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

enhancement(cyclonedx): use component.evidence.occurrences.location for filapaths and linenumber

3 participants