anchore / syft

CLI tool and library for generating a Software Bill of Materials from container images and filesystems
Apache License 2.0
5.98k stars 551 forks source link

Dependency graph of BOMs generated with Syft is incomplete due to missing root node #3071

Open t-k-u opened 1 month ago

t-k-u commented 1 month ago

What happened: After uploading SBOMs in Dependency Track (v4.11.5), created by syft, we encountered the problem that the dependency graphs could not be displayed.

We tested it with the latest alpine version: image

This results in the following SBOM sbom_diy.json

The logs do not include anything noticeable: image

What you expected to happen: A complete (displayable) Dependency Graph

Steps to reproduce the issue: 1) Create SBOM - run: docker pull alpine:latest

  • name: Generate SBOM run: | ${{ runner.temp }}/syft/syft alpine:latest -o cyclonedx-json=sbom_diy.json
    env: PATH: ${{ runner.temp }}/syft:$PATH

2) Upload SBOM to DT using

  • name: Upload SBOM to Dependency Track using curl run: | curl -X "POST" "DTINSTANCELINK/api/v1/bom" -H "Content-Type: multipart/form-data" -H "X-Api-Key: working API KEY" -F "autoCreate=true" -F "projectName=DIY_test_image_alpine" -F "projectVersion=1" -F "bom=@sbom_diy.json"

Anything else we need to know?: We already created an issue for Dependency Track. It was determined that it is not a problem in DT, but in the SBOM itself, as it has a missing root.

Environment:

willmurphyscode commented 1 month ago

Hi @t-k-u thanks for the issue! We'll try to discuss this at an upcoming community meeting. In general, Syft doesn't guarantee that there will always be a root package because Syft doesn't assume that the thing scanned is a single artifact. For example, what is the "root" of alpine:latest? There are a number of packages with their own dependency graphs.

willmurphyscode commented 1 month ago

@t-k-u when scanning alpine:latest as you did here, what would you expect the root of the dependency graph to be?

t-k-u commented 1 month ago

Without any expertise, but my expectation would be that alpine is the root, if alpine as a "package" is the source of the SBOM.

kzantow commented 3 weeks ago

Hey @t-k-u, we discussed this issue this week on the livestream and we think it would be ok to add an option for Syft to generate these dependencies and add them to CycloneDX output.

As has been discussed elsewhere, we do not believe it is accurate to include dependency relationships in this case, but CycloneDX does not provide any other relationship types that would be more appropriate (such as CONTAINS). However, this is clearly a cause of friction for users, so I think it would be ok to add an option to enable this behavior of adding dependency relationships from the metadata.component to the appropriate top-level package components.

Note for anyone implementing this -- the encoders have configurations that it would be simple to pass options for, see here: https://github.com/anchore/syft/blob/main/syft/format/encoders.go#L36-L53.

Other note: CycloneDX allows for nesting of components. It is possible a better/more accurate solution would be to nest all components in the metadata.component.components, but this has the potential to prevent other tools from properly reading the Syft generated files, too.