cyclonedx-maven-plugin icon indicating copy to clipboard operation
cyclonedx-maven-plugin copied to clipboard

Cyclonedx sbom for tycho dependencies

Open Swapnil-CSI opened this issue 4 years ago • 45 comments

Hi Cyclonedx Team,

Is there any way to scan the Tycho dependencies using cyclonedx-maven-plugin?.

I found that syft tool can generate cyclonedx format but it has limitations. It does not generate license information.

Thanks, Swapnil Bharshankar

Swapnil-CSI avatar Oct 29 '21 08:10 Swapnil-CSI

Any Maven project, including Tycho, is supported. I'd recommend integrating CycloneDX Maven plugin into the pom itself that way it becomes part of the Maven lifecycle.

stevespringett avatar Oct 29 '21 15:10 stevespringett

I tried the cyclonedx maven plugin( pom.xml) on repo : https://github.com/eclipse/tycho/tree/master/demo/itp04-rcp to generate sbom. In the generated sbom, dependencies are showing as a group of p2.eclipse-plugin and not showing original maven group/artifact id, So with this, it will not find any CVE's present in dependencies also the Licences section is missing in the report.

Used following block in pom.xml

    <plugin>
        <groupId>org.cyclonedx</groupId>
        <artifactId>cyclonedx-maven-plugin</artifactId>
        <version>2.5.3</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>makeAggregateBom</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <projectType>library</projectType>
            <schemaVersion>1.3</schemaVersion>
            <includeBomSerialNumber>true</includeBomSerialNumber>
            <includeCompileScope>true</includeCompileScope>
            <includeProvidedScope>true</includeProvidedScope>
            <includeRuntimeScope>true</includeRuntimeScope>
            <includeSystemScope>true</includeSystemScope>
            <includeTestScope>false</includeTestScope>
            <includeLicenseText>true</includeLicenseText>
            <outputFormat>all</outputFormat>
            <outputName>bom</outputName>
        </configuration>
    </plugin>

Please refer to the attached sbom report. bom.zip

Swapnil-CSI avatar Nov 16 '21 12:11 Swapnil-CSI

Sounds like the tycho project either needs to:

  1. Create a CycloneDX implementation that supports their build process and lifecycle - which seems to be very different from vanilla Maven.

or

  1. Adopt CycloneDX and automatically produce it in the build process so that every plugin automatically has a complete and accurate BOM.

I would strongly encourage the second approach. Other Eclipse projects are already adopting CycloneDX including Eclipse Temurin.

stevespringett avatar Nov 16 '21 17:11 stevespringett

Do you mean this should be done on tycho side ? so currently for projects with builds based on tycho we either need to fill a bug against tycho asking them to adopt CycloneDX, or create a CycloneDX implementation by ourself if they are not willing to do so, right ?

amergey avatar Mar 21 '22 14:03 amergey

In the generated sbom, dependencies are showing as a group of p2.eclipse-plugin and not showing original maven group/artifact id

The project you mentioned does not reference a single "maven" dependency but only P2 dependencies (beside that its using an old target+tycho version) so the question is how should this ever work?

If you use the latest Tycho version, there is an option to map P2 dependencies to "regular" maven ones as much as possible and you can reference maven dependencies directly in your target, but without that there is not much Tycho can do for you.

laeubi avatar Apr 20 '23 05:04 laeubi

@stevespringett can you please explain if the plugin can be somehow extended by a third party? A quick look at the project code does not reveal any obvious option, I don't think the problem is that the build is different but that some dependencies (not originating from maven) are need to be specifically represented, so either there should be direct support in the plugin or some way to modify the outcome, e.g. a plain maven dependency is currently represented as:

"pkg:maven/org.eclipse.sisu/[email protected]?type=jar"

while for a P2 dependency one probably want something like:

"pkg:p2/bundle/[email protected]"

laeubi avatar Apr 25 '23 04:04 laeubi

some dependencies (not originating from maven) are need to be specifically represented

@laeubi I guess there would be two ways to do this. The first being to merge the results from the Maven plugin with a BOM containing the p2 components. The CycloneDX CLI performs merging. The second option would be to add direct, but optional support for p2 in the Maven plugin. I don’t know what this would involve as I have no experience with p2.

@hboutemy at the Apache Foundation is leading the development efforts of this plugin. @hboutemy would you by chance know how this could potentially work?

stevespringett avatar Apr 26 '23 04:04 stevespringett

I know sufficiently about Tycho to know that I don't know, sorry And I fear adding even more complexity

hboutemy avatar Apr 26 '23 05:04 hboutemy

The first being to merge the results from the Maven plugin with a BOM containing the p2 components. The CycloneDX CLI performs merging

Maybe it would be possible to have a parameter in the CycloneDX Plugin to specify some "merge boms", Tycho could then just generate it at the standard location (e.g. target/tycho.sbom) and it gets merged with the default generated one. This would maybe the most felxible solotuion and allows enhancement by other tools as well (even non java/maven).

The second option would be to add direct, but optional support for p2 in the Maven plugin. I don’t know what this would involve as I have no experience with p2.

It is actually a quite easy rule:

  1. It is a system dependency
  2. the group.id starts with p2. and ends with the type (e.g. eclipse.plugin)

Then it mapped in the following way;

P2_ID = artifactId
P2_VERSION = version

then one might get a result of pkg:p2/bundle/<P2_ID>@<P2_VERSION>

laeubi avatar Apr 26 '23 05:04 laeubi

By the way is there a libary I could use to write a SBOM in CycloneDX format?

laeubi avatar Apr 26 '23 05:04 laeubi

@laeubi please share a simple Tycho project that we can transform into cyclonedx-maven-plugin IT then explain the differences between the current "base-Maven" SBOMs and the Tycho-aware ones that you want

we can try and see how hard this will be

hboutemy avatar Apr 26 '23 05:04 hboutemy

is there a libary I could use to write a SBOM in CycloneDX format?

https://github.com/CycloneDX/cyclonedx-core-java is used by cyclonedx-maven-plugin

hboutemy avatar Apr 26 '23 05:04 hboutemy

I'll try to prepare a demo for this purpose, for a quick look there is the example from the comment above: https://github.com/CycloneDX/cyclonedx-maven-plugin/issues/137#issuecomment-970213093

it has a zip file attached and there you can search for p2.eclipse-plugin and see for example:

"purl" : "pkg:maven/p2.eclipse-plugin/[email protected]?type=jar",

this is actually a P2 dependency with ID = org.eclipse.core.runtime and version 3.11.1.v20150903-1804 and one would most probably not find that on maven central with the given PURL (there is no p2.eclipse-plugin groupId) even though some versions are deployed under different groupIds because it originates from here: https://download.eclipse.org/releases/2022-06/

laeubi avatar Apr 26 '23 05:04 laeubi

What is the status of this? I read the conversation several times but I didn't fully get what can/should be done in order to get "real" Maven PURLs out of Eclipse plug-ins. Is there some information that can be put into the the Eclipse plug-in Jars that can be consumes by the cyclonedx Maven plug-in? Or are there code changes required in the Maven plug-in or in Tycho? I'm happy to invest some time since we are very interested in this feature but I will need some more concrete hints where and how to start.

sithmein avatar Jul 21 '23 19:07 sithmein

@sithmein it all depends on the context and use case, to summarize a Eclipse plug-in can be a maven deployed in which case it can be mapped as a maven PURL, if that's not the case it can't and one obviously needs a different scheme, but its not clear how useful this is.

It seems this is not really something the usual committer/contributors encounter and thus handled with very low priority, so if this is crucial to your business and you likes to speed up the development you can contact me for an individual contract for working dedicated on this specific issue.

laeubi avatar Jul 22 '23 04:07 laeubi

I completely overlooked the example, now diving into it:

I now understand the problem in provided bom.json is for example

    {
      "group" : "p2.eclipse-plugin",
      "name" : "javax.annotation",
      "version" : "1.2.0.v201401042248",

is a Tycho / OSGi bundle (with its specific hashes) associated to I suppose an original "classical" non-OSGi jar (and its original hashes)

and you want to track the transformation of the original jar file (that is known to the usual non-OSGi community) into the OSGi bundle

I still need to understand the magic behind these OSGi bundle. I ran the example, and as of today, I got this download

[INFO] Fetching javax.annotation_1.3.5.v20200909-1856.jar from https://eclipse.c3sl.ufpr.br/releases/2022-06/202206151000/plugins/ (46,27kB)

(I suppose the version difference is just an update in the example code)

What Maven coordinates is this OSGi bundle supposed to match? I guess a clear groupId, but not artifactId, looking at https://repo.maven.apache.org/maven2/javax/annotation/ : is it supposed to be javax.annotation-api? Is there an algorithm to extract that info?

FYI, rebuilding today, the group in generated bom.json is nowadays p2.eclipse.plugin instead of p2.eclipse-plugin that you had in the past: I don't know where the magic group was defined, but it has changed Notice: I find this "Eclipse Plugin" term quite confusing here: IIUC, this has nothing to do with Eclipse plugins, but OSGI-fied jars (that sometimes are used in Eclipse plugins context, but not always)

please help clarifying the problem, then we'll see what solutions may be found (probably at multiple levels)

hboutemy avatar Jul 22 '23 07:07 hboutemy

As said there is not a 1:1 mapping to maven artifacts, it might be that a maven artifact was used and just wrapped as a bundle, it might be build from source with some modification, it might even not be on maven central at all, it could even be directly consumed from maven, but the unit-id does not mean anything in this regard.

laeubi avatar Jul 22 '23 09:07 laeubi

What we see in our applications is the following:

  1. OSGi bundles that only exist as OSGi bundles, such as most of org.eclipse.*. Having them under the p2.eclipse.plugin group id is totally fine.

  2. OSGi bundles that have been converted from Maven artifacts using the p2 Maven plug-in or more generally bnd. The problem is that the bundle name does reflect the Maven name 1:1 in many cases. Oftentimes the group ID is stripped during the conversion. For example, org.slf4j:slf4j-api:1.7.15 simply becomes slf4j.api_1.7.25.jar. However, in all these cases the bundle jar contains the original pom.xml, e.g. META-INF/maven/org.slf4j/slf4j-api/pom.xml. Therefore I could image that some new code looks into the bundle jar, tries to find a pom.xml file, and uses this information to get to the Maven coordinates.

  3. OSGi bundles that were converted from Maven artifacts by some other means (e.g. manually). javax.annotation_1.3.5.v20200909-1856.jar is an example. It also contains the original pom.xml, but at a slightly different path META-INF/maven/org.eclipse.orbit.bundles/javax.annotation/pom.xml (notice the org.eclipse.orbit.bundles).

  4. OSGi bundles that are hand-crafted. Name and content is more or less arbitrary.

Case 1 is already covered in my opinion. Having a solution for case 2 would cover > 80% (in our case). Case 3 is very similar to case 2 and I guess they could be solved together. Case 4 isn't something that has to (or can be) be supported.

sithmein avatar Jul 22 '23 11:07 sithmein

ok, I think I'm starting to understand the problem space

I propose the following plan:

  1. add p2 to purl spec: https://github.com/package-url/purl-spec
  2. have cyclonedx-maven-plugin generate p2 coordinates when it finds Maven pseudo-coordinates generated by Tycho (IIUC: I'd love to have a pointer to the code that generates the groupId, because I'd love to have the value changed)
  3. eventually try to implement some heuristics to generate some pedigree when it looks like a p2 artifact is a re-packaging from a Maven one https://cyclonedx.org/docs/1.4/json/#components_items_pedigree

when I see the javax.annotation_1.3.5.v20200909-1856.jar bundle that contains META-INF/maven/org.eclipse.orbit.bundles/javax.annotation/pom.xml, perhaps Tycho should generate in org.eclipse.orbit.bundles groupId instead of p2.eclipse.plugin / p2.eclipse-plugin: having a pointer to the Tycho doc on this pseudo groupId wuold be useful to share for non-experts if we want more people to understand p2/Tycho vs Maven

hboutemy avatar Jul 23 '23 06:07 hboutemy

add p2 to purl spec: https://github.com/package-url/purl-spec

It should be something like pkg:p2/bundle/<P2_ID>@<P2_VERSION> but I have no clue how to modify the spec, so if someone wants to do so I can help review / give further information.

have cyclonedx-maven-plugin generate p2 coordinates when it finds Maven pseudo-coordinates generated by Tycho (IIUC: I'd love to have a pointer to the code that generates the groupId, because I'd love to have the value changed)

The value is an implementation detail of Tycho and can't be changed it is purely used inside the current reactor build to specify system scoped dependencies in the maven model, the only thing we somehow gurantee as stable is that is starts with p2. as defined here:

https://github.com/eclipse-tycho/tycho/blob/ff1f7538c8ecd9718a1bd269dd791289ff1c7ffb/tycho-api/src/main/java/org/eclipse/tycho/TychoConstants.java#L27

eventually try to implement some heuristics to generate some pedigree when it looks like a p2 artifact is a re-packaging from a Maven one https://cyclonedx.org/docs/1.4/json/#components_items_pedigree

The is no guarantee at all that a P2 artifact has ever been "repacked" from a maven artifact, the tycho-packaging:update-consumer-pom performs some back-resolving for items that where consumed directly from maven but this is more to support consumers of the pom not as a mean of what is shipped with a product.

perhaps Tycho should generate in org.eclipse.orbit.bundles groupId instead of p2.eclipse.plugin / p2.eclipse-plugin

This has nothing to do with Tycho and not every bundle build by Tycho is an orbit one, actually orbit uses bnd to build its bundles. Please don't repeat the error of the Eclipse license tool to assume every bundle originates from orbit, that is simply wrong.

having a pointer to the Tycho doc on this pseudo groupId would be useful to share for non-experts if we want more people to understand p2/Tycho vs Maven

See above, there is no such documentation because it is internal behavior of Tycho to overcome the restrictions of the maven model, also note that P2 != Tycho, Tycho just supports using P2 repositories as it supports to use Maven Repositories as well.

laeubi avatar Jul 23 '23 08:07 laeubi

on updating https://github.com/package-url/purl-spec, it all starts with a PR I suppose that the bundle word in pkg:p2/bundle/<P2_ID>@<P2_VERSION> is not necessary: I suppose pkg:p2/<P2_ID>@<P2_VERSION> is what is expected

On cyclonedx-maven-plugin generating such p2 purl, IIUC, it' about detecting Maven p2.* groupId to know that a p2 purl should be done, and that's it: looks reasonable

We'll see later if heuristics can be done to try to generate a pedigree from a p2 purl to a Maven artifact: honestly, that part is the type of tricks that I'd prefer to keep out of cyclonedx-maven-plugin

hboutemy avatar Jul 23 '23 15:07 hboutemy

I suppose that the bundle word in pkg:p2/bundle/<P2_ID>@<P2_VERSION> is not necessary:

P2 can store different type, e.g. bundles, features, products, ... so the type should be represented somehow to not run into issues later on.

On cyclonedx-maven-plugin generating such p2 purl, IIUC, it' about detecting Maven p2.* groupId to know that a p2 purl should be done, and that's it: looks reasonable

If that helps anything it could be done that way yes, another indication is that it is a system scoped dependency.

laeubi avatar Jul 23 '23 15:07 laeubi

if there are different "types" for p2 that need to be represented in purl , pkg:p2/<P2_TYPE>/<P2_ID>@<P2_VERSION> what are these types, and how can cyclonedx-maven-plugin determine which type a p2 dependency is? this will have to be clearly defined

hboutemy avatar Jul 24 '23 10:07 hboutemy

I think the most relevant ones are

  • p2.eclipse.plugin = bundle
  • p2.eclipse.feature = feature

There are also update sites, products and target but those are usually nothing one can depend on.

laeubi avatar Jul 24 '23 16:07 laeubi

are all these really related to an artifact? When I read, it feels to me that it is related to the repository where the artifact comes from

hboutemy avatar Jul 25 '23 06:07 hboutemy

Sorry I don't fully understand. A bundle is not a feature even if both are stored as a jar file (a feature usually groups bundles and other features), the repository (like a maven repository) can store different things but do not really care of course much here but I'm not that familiar with SBOM to decide if / hwo it makes a difference so would say it should be handled like in maven where an artifact can be type xml, jar, zip, ....

laeubi avatar Jul 25 '23 12:07 laeubi

nobody of us is expert in both p2 Tycho and SBOM, that's why we need to share examples to try to define what best fits the different aspects

the current question is to define if p2 has a notion of namespace or not: see scheme:type/namespace/name@version?qualifiers#subpath fields description in purl description and examples at https://github.com/package-url/purl-spec#purl (we'll see later optionql qualifiers and subpath)

It seems that the "bundle", "feature", "update site", "product", "target" examples that you shares are in fact a precision of a sub-part of a p2 repository location but an artifact like javax.annotation_1.3.5.v20200909-1856.jar can be stored in the bundle or feature parts of a p2 repository: it's only one content (with one hash), it would not make sense to have a different content (hash) when it is stored in bundle or feature part, isn't it?

is pkg:p2/[email protected] describing sufficiently the artifact? or is it absolutely necessary to write pkg:p2/plugin/[email protected] to show that it is fundamentally different from pkg:p2/feature/[email protected] or pkg:p2/product/[email protected]? Perhaps accepting both is what p2 needs, like npm and Docker purls are supported with or without namespace

Notice: perhaps that instead of having this discussion in this cyclonedx-maven-plugin issue, we should move to the same discussion in a purl issue...

hboutemy avatar Aug 03 '23 09:08 hboutemy

another source of examples for purl is https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst

can be useful to imagine how p2 would be added to the page; eclipse, osgi and p2 are already listed at the end as candidates (I don't how eclipse, osgi and p2 relate or not...)

hboutemy avatar Aug 03 '23 09:08 hboutemy

P2 artifacts originate from P2 repositories, such a repository for example can look like this:

https://download.eclipse.org/technology/m2e/releases/latest/

if you download the content.jar you will see a set of units each unit can have artifacts, a unit usually provides a capability of org.eclipse.equinox.p2.eclipse.type for example for a bundle

<provided namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' version='1.0.0'/>

or for a feature

<provided namespace='org.eclipse.equinox.p2.eclipse.type' name='feature' version='1.0.0'/>

So feature and bundle are different types and never point to the same artifact, as the artifact of a bundle type is a jar file that contains some compiled classes while a feature is a jar file that contains a feature.xml file and usually requires other bundle/feature units in the metadata (so this is maybe similar to a maven project of packaging jar versus packing pom).

laeubi avatar Aug 03 '23 09:08 laeubi

when I see https://download.eclipse.org/technology/m2e/releases/latest/features/ and https://download.eclipse.org/technology/m2e/releases/latest/plugins/ it looks very similar but I now understand that it would not really make sense to have a copy of the same file in the 2 directories, since in fact the expected content is from a different nature

ok, why not: this will have to be described in https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst with the same approach as other types

I won't lead p2 addition to purl, as I'm not an expert of p2: once p2 will be added to purl types, I hope that the way Tycho defines Maven coordinates will permit us to implement in cyclonedx-maven-plugin a way to point to a p2 purl instead of a fake maven purl as it is currently the case

hboutemy avatar Aug 03 '23 09:08 hboutemy