Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Nested Components or Services breaks BOM validation #275

Closed
peschuster opened this issue Jul 26, 2022 · 9 comments · Fixed by #276
Closed

[BUG] Nested Components or Services breaks BOM validation #275

peschuster opened this issue Jul 26, 2022 · 9 comments · Fixed by #276
Assignees
Labels
bug Something isn't working

Comments

@peschuster
Copy link

The schema documents suggest that components can be nested inside other components (i.e. for/with hierarchical merging).

Hoewever, if I try to generate such a bom an exception is raised in the validate method here:

if len(dependency_diff) > 0:

The reason for that is, because nested bom_refs underneath other components are not found by the implementation inside validate.

Am I misunderstanding the schema or is this missing from the validation?

@madpah
Copy link
Collaborator

madpah commented Jul 26, 2022

Hi @peschuster - thanks for raising this. Can you please:

  1. Confirm the version of cyclonedx-python-lib you are using?
  2. Share any PoC code that causes the described behaviour for us to reproduce?

Thanks!

@peschuster
Copy link
Author

I am using version 2.7.0 of cyclonedx-python-lib.

Here is a short example that leads to this exception:

from cyclonedx.model.component import Component
from cyclonedx.model.bom import Bom
from cyclonedx.output import BaseOutput, get_instance, OutputFormat

app = Component(name="app", version="1.0.0")
comp_a = Component(name="comp_a", version="1.0.0")
comp_b = Component(name="comp_b", version="1.0.0")
comp_c = Component(name="comp_c", version="1.0.0")

comp_b.components.add(comp_c)
comp_b.dependencies.add(comp_c.bom_ref)

libs = [ comp_a, comp_b ]
app.dependencies.add(comp_a.bom_ref)
app.dependencies.add(comp_b.bom_ref)

bom = Bom(components=libs)
bom.metadata.component = app

outputter: BaseOutput = get_instance(bom=bom, output_format=OutputFormat.JSON)
outputter.output_to_file("sbom.json", allow_overwrite=True)

@madpah madpah changed the title Support for nested components? [BUG] Support for nested Components in bom.metadata.component Jul 27, 2022
@madpah madpah self-assigned this Jul 27, 2022
@madpah madpah added the bug Something isn't working label Jul 27, 2022
@madpah
Copy link
Collaborator

madpah commented Jul 27, 2022

Thanks for the details @peschuster. Agree this is a bug in the library - so we'll work on a fix.

I'm also curious (so we can feedback to the Core CycloneDX group) what your Use Case is for nesting Components in bom.metadata.component? Would be great if you could share a real-world Use Case here.

Thanks!

@madpah
Copy link
Collaborator

madpah commented Jul 27, 2022

@peschuster - reviewing in greater depth, and whilst I can't say that your example above contradicts the CycloneDX schema, I wonder whether your example is incorrect and should re-written.

From your example, I understand that:

  • Bom is describing Component app
  • app is has direct dependencies of comp_a and comp_b
  • comp_b has a direct dependency of comp_c

If my understanding is correct, then the expected way to model this in CycloneDX is as follows:

from cyclonedx.model.bom import Bom
from cyclonedx.output import BaseOutput, get_instance, OutputFormat

app = Component(name="app", version="1.0.0")

comp_a = Component(name="comp_a", version="1.0.0")
comp_b = Component(name="comp_b", version="1.0.0")
comp_c = Component(name="comp_c", version="1.0.0")

comp_b.dependencies.add(comp_c.bom_ref)

libs = [ comp_a, comp_b, comp_c ]

bom = Bom(components=libs)
bom.metadata.component = app

outputter: BaseOutput = get_instance(bom=bom, output_format=OutputFormat.JSON)
outputter.output_to_file("sbom.json", allow_overwrite=True)

Appreciate your feedback here.

FYI @jkowalleck

@peschuster
Copy link
Author

The nesting is not in bom.metadata.component, but in the list of components.
The use case for us is to keep the hierarchy of components on integration without the need for flattening the lists.

Here is the expected output for the example:

{
  "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "serialNumber": "urn:uuid:c49c012f-7b4f-4ec3-b899-10faed6d611f",
  "version": 1,
  "metadata": {
	"timestamp": "2022-07-27T08:55:17.710857+00:00",
	"tools": [ ],
	"component": {
	  "type": "library",
	  "bom-ref": "2775d2d9-7aaa-4c18-b4ba-7e1939363122",
	  "name": "app",
	  "version": "1.0.0"
	}
  },
  "components": [
	{
	  "type": "library",
	  "bom-ref": "8d0c1cd0-54b3-4a9f-af30-00b66c341210",
	  "name": "comp_a",
	  "version": "1.0.0"
	},
	{
	  "type": "library",
	  "bom-ref": "4b682758-cb1f-4c8c-9490-e2f850c9309d",
	  "name": "comp_b",
	  "version": "1.0.0",
	  "components": [
		{
		  "type": "library",
		  "bom-ref": "4c33d6e8-16ad-4b33-8176-cf0b4629b56c",
		  "name": "comp_c",
		  "version": "1.0.0"
		}
	  ]
	}
  ],
  "dependencies": [
	{
	  "ref": "2775d2d9-7aaa-4c18-b4ba-7e1939363122",
	  "dependsOn": [
		"4b682758-cb1f-4c8c-9490-e2f850c9309d",
		"8d0c1cd0-54b3-4a9f-af30-00b66c341210"
	  ]
	},
	{
	  "ref": "8d0c1cd0-54b3-4a9f-af30-00b66c341210",
	  "dependsOn": []
	},
	{
	  "ref": "4b682758-cb1f-4c8c-9490-e2f850c9309d",
	  "dependsOn": [
		"4c33d6e8-16ad-4b33-8176-cf0b4629b56c"
	  ]
	}
  ]
}

@madpah
Copy link
Collaborator

madpah commented Jul 27, 2022

Thanks for the quick response @peschuster.

I see the root issue now - the validation in Bom.validate is not seeing the nested dependency (comp_c) when checking that we have a valid dependency tree.

Will dig in further.

madpah added a commit that referenced this issue Jul 27, 2022
madpah added a commit that referenced this issue Jul 27, 2022
@madpah madpah changed the title [BUG] Support for nested Components in bom.metadata.component [BUG] Nested Components or Services breaks BOM validation Jul 27, 2022
madpah added a commit that referenced this issue Jul 27, 2022
@madpah
Copy link
Collaborator

madpah commented Jul 27, 2022

@peschuster as you might see we are working to address the validation issue you have raised.

I did want to point out a bit of documentation which may or may not relate to how you are wishing to use CycloneDX for your reference.

With regards to Component.components (i.e. nested Components), the CycloneDX specification has this statement:

A list of software and hardware components included in the parent component. This is not a dependency tree. It provides a way to specify a hierarchical representation of component assemblies, similar to system -> subsystem -> parts assembly in physical supply chains.

This is taken from https://cyclonedx.org/docs/1.4/xml/#type_component.

Given your earlier description - I just wanted to make sure you were aware of this.

@jkowalleck
Copy link
Member

jkowalleck commented Jul 27, 2022

@madpah the nesting is not about dependencies (but it can be, too)
It is mainly about bundling - like in node as described here: CycloneDX/cyclonedx-node-npm#13

madpah added a commit that referenced this issue Jul 28, 2022
madpah added a commit that referenced this issue Jul 28, 2022
madpah added a commit that referenced this issue Jul 28, 2022
madpah added a commit that referenced this issue Aug 1, 2022
…onents-isue-275

fix: BOM validation fails when Components or Services are nested #275 

fix: updated dependencies #271, #270, #269 and #256
@madpah
Copy link
Collaborator

madpah commented Aug 1, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants