interlynk-io / sbomasm

SBOM Assembler - A tool to edit SBOM or assemble multiple sboms into a single sbom.
Apache License 2.0
56 stars 4 forks source link

Hierarchical merges assumes dependencies. Should it not allow simple containment #51

Closed flemminglau closed 2 months ago

flemminglau commented 5 months ago

It seems like a hierarchical merge will always generate dependency data forcing the merged sboms to become nodes in the resulting sbom dependency tree. On the level above the individual sboms dependency trees.

Many systems (like Dependency Track) makes the assumption that the top level in the dependency tree is the application direct dependencies.

However if an application is stitched together from multiple (unrelated) components it makes no sense to claim that there is a dependency relationship between the combined application and the components. Here the relationship is simply a containment.

If this was changed applications like DT would again be able to rely on the top level in the dependency tree being the direct dependencies.

At least it should be an option to allow this distinction between containment and dependency.

riteshnoronha commented 5 months ago

Yes we should support a mode called "Merge as assembly". Will work on it soon.

riteshnoronha commented 2 months ago

@flemminglau thanks for this feedback, this has been implemented only for Cyclonedx. Please give it a shot.

flemminglau commented 1 month ago

I had a hard time identifying the new option to use. I had to go and check the code changes made to identify the new option.

The documentation does not describe the options and no help is provided by the application.

At least not that I could find.

I was not able to verify if the output is what I need as I have some issues at the moment with unsupported Cyclonedx versions in my pipeline.

riteshnoronha commented 1 month ago

Good feedback. Let me address those soon. Also if you need any help resolving unsupported Cyclonedx versions would be glad to help out.

flemminglau commented 1 month ago

It seems help (usage) is indeed available in the application when I specify the "assemble" keyword". Otherwise not. So not a huge point.

My issue is that sbomasm produces CDX 1.6 compliant output.

And the cdx2spdx utility is not yet supporting anything beyond 1.4.

I don't see how you can help with that except by offering your assistance to that project. Unless the sbomasm can be made produce 1.4 compliant output.

riteshnoronha commented 1 month ago

@flemminglau We have a free tier in our commercial product which you could use to achieve this, if you are interested let me know, i can set u up.

riteshnoronha commented 1 month ago

@flemminglau we added a new option to assemble command to restrict the output sbom version, details are here the last example https://github.com/interlynk-io/sbomasm?tab=readme-ov-file#assemle-sboms . This should unblock you. We have also added a new Edit command, to edit sbom metadata after the merge. More details are here. https://github.com/interlynk-io/sbomasm?tab=readme-ov-file#edit-sboms

flemminglau commented 1 month ago

to restrict the output sbom version

Not sure I get your point here. It seems you are now able to define the SBOM version in the output.

What I have issues with is the fact that sbomasm uses the 1.6 version of the CycloneDX format specification (only). So unless you add a CDX 1.5, 1.4, ... backwards compatibility mode using the older specs I think I will have to wait for cdx2spdx to get their act together.

riteshnoronha commented 1 month ago

@flemminglau not sure i understand, sbomasm can accept input as CycloneDX 1.4, 1.5 and 1.6 and output 1.4, 1.5 and 1.6. Yes it default outputs to 1.6. So we have made a new control to restrict the output version.

Let me know if i am missing something here.

flemminglau commented 1 month ago

Sorry, my mistake.

I see now that a new -e option can control the output format. I tested it and indeed I get an output accepted by the latest version of cdx2spdx. (v1.4)

However from what I can assess so far it does actually not solve my root issue. I am looking for a way to define in the resulting SBOM that modules contained in the application which is stitched together by component sboms has direct dependencies on the modules which are direct dependencies in the individual component SBOMs.

What I see in DT now is that no dependencies exist at all. (No dependency tree is available) Without the -a flag the individual SBOMs components are the direct dependencies. As these are typically arbitrary internal component names this is also wrong.

riteshnoronha commented 1 month ago

@flemminglau

My interpretation of what you need is

The tools needs to be able to do the following

I have tried to visualize this below with a simple example.


+-----------------------+   +-----------------------+   +-----------------------+
|  Application SBOM     |   |  Comp A v1.0.0        |   |  Comp B v2.2          |
|-----------------------|   |-----------------------|   |-----------------------|
|  CompA v1.0.0         |   |  CompC v2.3.2         |   |  CompE v3.7           |
|  CompB v2.2           |   |  CompD v3.5           |   |  CompF v2.1           |
|                       |   |                       |   |                       |
|                       |   |                       |   |                       |
|  Dep (CompA -> App)   |   |  Dep (CompC -> CompA) |   |  Dep (CompE -> CompB) |
|  Dep (CompB -> App)   |   |  Dep (CompD -> CompA) |   |  Dep (CompE -> CompB) |
|-----------------------|   |-----------------------|   |-----------------------|
|          ↓            |   |          ↓            |   |          ↓            |
+-----------------------+   +-----------------------+   +-----------------------+
                                      ↓
                      +------------------------------------+
                      |           Application SBOM         |
                      |------------------------------------|
                      |  ComponentA v1.0.0                 |
                      |  ComponenB v2.2                    |
                      |  ComponenC v2.3.2                  |
                      |  ComponenD v3.5                    |
                      |  ComponenE v3.7                    |
                      |  ComponenF v2.1                    |
                      |                                    |
                      |  Dep (CompA -> App)                |
                      |  Dep (CompB -> App)                |
                      |  Dep (CompC -> CompA)              |
                      |  Dep (CompD -> CompA)              |
                      |  Dep (CompE -> CompB)              |
                      |  Dep (CompE -> CompB)              |
                      |                                    |
                      +------------------------------------+
flemminglau commented 1 month ago

Actually no.

2 points.

  1. I don't want to start with a "master Application SBOM". The Application can easily be defined simply as the merged SBOM is created. This is basically how it works now. It implicitly contains/depends on the content of the provided SBOMs.

  2. In your example Comp A and Comp B have been invented by the inventory processing to represent the "imaginary" split of the Application into 2 components. It is an abstraction as it simply represents a logical split of the application code due to tooling or simply practical reasons. From a dependency point of view I need in the resulting SBOM that they disappear completely or gets demoted to empty appendices.

Then (again from a dependency point of view) I want CompC, CompD, CompE and CompF to all be direct dependencies of the application. This is in reality what they are. The application uses them directly by calling into them.

The result will be that tools like Dependency Track will show the (CompA and CompB) direct dependencies as the direct dependencies of the application. And anything beyond that as transitive ones. Which in my view represents reality.

If possible the original Component layout (including CompA and CompB) could additionally be modelled as containment/assembly. E.g. CompC and CompD are physically provided inside CompA but this is not a dependency. Not sure how this would be visually represented in tools like DT.

Alternatively if tools like DT could in some other way be told what is in reality direct dependencies and what is not that would solve (in the end) the same challenge although I still do not like that CompA and CompB are considered dependencies when they are in fact just arbitrary sections of the application code.

riteshnoronha commented 1 month ago

@flemminglau this seems like an interesting use-case i would like to solve for you. I was wondering, if you could provide me samples of your input and expected output, that would crystalize the point in my mind.

flemminglau commented 4 weeks ago

My challenge here is that I do not have a good example of the desired output. I am not even sure if there is a way to get Dependency Track to show what I want.

So right now I kind of lost the plot on what it really is I want.

It seems that a non-hierarchical merge does what I want when it comes to direct dependencies.

What is my big challenge is that I want still to be able to document (mostly for internal debugging purposes) which component is contributing which dependencies. When a CVE is raised against the application it is vital to quickly understand how it should be dispatched to the component teams.

As it is now (choosing between hierarchical and non-hierarchical) I can choose between getting the traceability I need but messing up the direct dependencies or getting the direct dependencies right but loosing all traceability.

On the other hand DT (and other similar systems) are not able to show containment so I am not sure there is a way out. (As you can hear I no longer remember how I imagined this to work at the time when I raised the issue)

I still believe that the -e option should not remove the dependency tree altogether (if that is what it does). But I am unsure in CycloneDX if it is possible to provide separate complete containment and dependency trees. Until that is available for sure no application would be able to provide both views.