Skip to content

Commit f2d43ae

Browse files
committed
Support for embedding dependency SBOMs in applications and exposing them
through an endpoint
1 parent 192272e commit f2d43ae

File tree

24 files changed

+1113
-60
lines changed

24 files changed

+1113
-60
lines changed

bom/application/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,26 @@
882882
<artifactId>quarkus-cyclonedx-deployment</artifactId>
883883
<version>${project.version}</version>
884884
</dependency>
885+
<dependency>
886+
<groupId>io.quarkus</groupId>
887+
<artifactId>quarkus-cyclonedx-deployment-spi</artifactId>
888+
<version>${project.version}</version>
889+
</dependency>
885890
<dependency>
886891
<groupId>io.quarkus</groupId>
887892
<artifactId>quarkus-cyclonedx-generator</artifactId>
888893
<version>${project.version}</version>
889894
</dependency>
895+
<dependency>
896+
<groupId>io.quarkus</groupId>
897+
<artifactId>quarkus-cyclonedx-endpoint</artifactId>
898+
<version>${project.version}</version>
899+
</dependency>
900+
<dependency>
901+
<groupId>io.quarkus</groupId>
902+
<artifactId>quarkus-cyclonedx-endpoint-deployment</artifactId>
903+
<version>${project.version}</version>
904+
</dependency>
890905
<dependency>
891906
<groupId>io.quarkus</groupId>
892907
<artifactId>quarkus-datasource-common</artifactId>

devtools/bom-descriptor-json/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,19 @@
518518
</exclusion>
519519
</exclusions>
520520
</dependency>
521+
<dependency>
522+
<groupId>io.quarkus</groupId>
523+
<artifactId>quarkus-cyclonedx-endpoint</artifactId>
524+
<version>${project.version}</version>
525+
<type>pom</type>
526+
<scope>test</scope>
527+
<exclusions>
528+
<exclusion>
529+
<groupId>*</groupId>
530+
<artifactId>*</artifactId>
531+
</exclusion>
532+
</exclusions>
533+
</dependency>
521534
<dependency>
522535
<groupId>io.quarkus</groupId>
523536
<artifactId>quarkus-datasource</artifactId>

docs/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,19 @@
482482
</exclusion>
483483
</exclusions>
484484
</dependency>
485+
<dependency>
486+
<groupId>io.quarkus</groupId>
487+
<artifactId>quarkus-cyclonedx-endpoint-deployment</artifactId>
488+
<version>${project.version}</version>
489+
<type>pom</type>
490+
<scope>test</scope>
491+
<exclusions>
492+
<exclusion>
493+
<groupId>*</groupId>
494+
<artifactId>*</artifactId>
495+
</exclusion>
496+
</exclusions>
497+
</dependency>
485498
<dependency>
486499
<groupId>io.quarkus</groupId>
487500
<artifactId>quarkus-datasource-deployment</artifactId>

docs/src/main/asciidoc/cyclonedx.adoc

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,39 @@ and pull requests should be submitted there:
44
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
55
////
66
[id="cyclonedx"]
7-
= Generating CycloneDX BOMs
7+
= Generating CycloneDX SBOMs
88
include::_attributes.adoc[]
99
:categories: tooling
1010
:summary: This guide explains how to generate SBOMs for Quarkus applications in the CycloneDX format.
1111
:topics: sbom
1212
:extensions: io.quarkus:quarkus-cyclonedx
1313

14-
An SBOM (Software Bill of Material) is a manifest that describes what a given software distribution consists of in terms of components. In addition to that, it may include a lot more information such as relationships between those components, licenses, provenance, etc.
15-
SBOMs would typically be used by software security and software supply chain risk management tools to perform vulnerability and compliance related analysis.
14+
An SBOM (Software Bill of Materials) is a manifest that describes what a given software distribution consists of in terms of components. In addition to that, it may include a lot more information such as relationships between those components, licenses, provenance, etc.
15+
SBOMs are typically used by software security and software supply chain risk management tools to perform vulnerability and compliance related analysis.
1616

17-
This guide describes Quarkus SBOM generation capabilities following https://cyclonedx.org/[CycloneDX] specification.
17+
This guide describes Quarkus SBOM generation capabilities following the https://cyclonedx.org/[CycloneDX] specification.
1818

1919
== Why Quarkus-specific tooling?
2020

2121
While Quarkus integrates with build tools such as https://maven.apache.org/[Maven] and https://gradle.org/[Gradle], it could itself be categorized as a build tool with its own component and dependency model, build steps, and build outcomes. One of the essential component types of a Quarkus application is a Quarkus extension, which consists of a runtime and a build time artifacts, and their dependencies.
2222

23-
To properly resolve Quarkus extension and other application dependencies Quarkus uses its own dependency resolver, which is implemented on top of the dependency resolver provided by the underlying build tool: Maven or Gradle.
23+
To properly resolve Quarkus extension and other application dependencies, Quarkus uses its own dependency resolver, which is implemented on top of the dependency resolver provided by the underlying build tool: Maven or Gradle.
2424

25-
As a consequence, in case of Maven, for example, the results of `dependency:tree` will not include all the dependencies Quarkus will use to build an application. A similar issue will affect other dependency analysis tools that assume a project adheres to the standard Maven dependency model: they will not be able to capture the effective Quarkus application dependency graph. Unfortunately, that includes the implementation of the https://github.com/CycloneDX/cyclonedx-maven-plugin[CycloneDX Maven plugin].
25+
As a consequence, in the case of Maven, for example, the results of `dependency:tree` will not include all the dependencies Quarkus will use to build an application. A similar issue will affect other dependency analysis tools that assume a project adheres to the standard Maven dependency model: they will not be able to capture the effective Quarkus application dependency graph. Unfortunately, that includes the implementation of the https://github.com/CycloneDX/cyclonedx-maven-plugin[CycloneDX Maven plugin].
2626

2727
Besides the dependencies, that are an input to a build process, there is also an outcome of the build that is the final distribution of an application. Users of an application may request an SBOM manifesting not only the dependencies (the input to a build) but also the final distribution (the outcome of the build) before they agree to deploy the application. Quarkus allows application developers to choose various packaging types for their applications, some of which are Quarkus-specific. Providing certain Quarkus-specific details about components included in a distribution may help better evaluate the impact of potential security-related issues.
2828

2929
== Dependency SBOMs
3030

31-
This chapter describes how to generate SBOMs manifesting only the dependencies of an application before it is built. In other words, these SBOMs will manifest the input into a build. These SBOMs could be used to perform vulnerability and compliance related analysis before building applications.
31+
Dependency SBOMs manifest the dependencies of an application before it is built. In other words, they describe the input to a build. These SBOMs can be used to perform vulnerability and compliance related analysis before building applications.
3232

3333
=== Maven Dependency SBOMs
3434

35-
For Quarkus Maven projects dependency SBOMs can be generated with the `quarkus:dependency-sbom` goal. The outcome of the goal will be saved in a `target/<artifactId>-<version>-dependency-cyclonedx.json` file (which can be changed by setting the `outputFile` goal parameter or the `quarkus.dependency.sbom.output-file` property). The complete Quarkus build and runtime dependency graphs will be recorded in the https://cyclonedx.org/[CycloneDX] `JSON` format.
35+
For Quarkus Maven projects, dependency SBOMs can be generated with the `quarkus:dependency-sbom` goal. The outcome of the goal will be saved in a `target/<artifactId>-<version>-dependency-cyclonedx.json` file (which can be changed by setting the `outputFile` goal parameter or the `quarkus.dependency.sbom.output-file` property). The complete Quarkus build and runtime dependency graphs will be recorded in the https://cyclonedx.org/[CycloneDX] `JSON` format.
3636

37-
`XML` format can be requested by setting `format` goal parameter (or `quarkus.dependency.sbom.format` property) to `xml`.
37+
`XML` format can be requested by setting the `format` goal parameter (or `quarkus.dependency.sbom.format` property) to `xml`.
3838

39-
Each component in the generated SBOM will include the `quarkus:component:scope` property that will indicate whether this component is used at runtime or only development/build time.
39+
Each component in the generated SBOM will include the `quarkus:component:scope` property indicating whether the component is used at runtime or only at development/build time.
4040
[source,json]
4141
----
4242
{
@@ -53,7 +53,7 @@ The complete set of parameters and their description can be obtained by executin
5353

5454
Unlike Maven, the https://github.com/CycloneDX/cyclonedx-gradle-plugin[Gradle CycloneDX plugin implementation] can be used in Quarkus projects to generate dependency SBOMs, since the implementation manifests dependency configurations registered by configured plugins.
5555

56-
Please, refer to the https://github.com/CycloneDX/cyclonedx-gradle-plugin[Gradle CycloneDX plugin] documentation for its configuration options. Here is a list of Quarkus dependency configurations that would be relevant for manifesting:
56+
Please refer to the https://github.com/CycloneDX/cyclonedx-gradle-plugin[Gradle CycloneDX plugin] documentation for its configuration options. Here is a list of Quarkus dependency configurations that would be relevant for manifesting:
5757

5858
* `quarkusProdRuntimeClasspathConfiguration` - Quarkus application production runtime dependencies;
5959
* `quarkusProdRuntimeClasspathConfigurationDeployment` - Quarkus application production runtime and build time dependencies;
@@ -62,18 +62,54 @@ Please, refer to the https://github.com/CycloneDX/cyclonedx-gradle-plugin[Gradle
6262
* `quarkusDevRuntimeClasspathConfiguration` - Quarkus application dev mode runtime dependencies;
6363
* `quarkusDevRuntimeClasspathConfigurationDeployment` - Quarkus application dev mode runtime and build time dependencies.
6464

65-
Given that the plugin is not aware of how Quarkus uses these dependencies, it will not be able to set the `quarkus:component:scope` property for components. On the other hand, the requested configuration name can be used indicate which scope to target.
65+
Given that the plugin is not aware of how Quarkus uses these dependencies, it will not be able to set the `quarkus:component:scope` property for components. On the other hand, the requested configuration name can be used to indicate which scope to target.
66+
67+
=== Embedded Dependency SBOMs
68+
69+
In addition to generating dependency SBOMs as separate files, Quarkus can embed a dependency SBOM directly into the built application as a classpath resource. This allows the application to carry its own bill of materials at runtime, which can be useful for runtime auditing or to expose via a REST endpoint (see <<sbom-endpoint>>).
70+
71+
To embed a dependency SBOM in the application:
72+
73+
[source,properties]
74+
----
75+
quarkus.cyclonedx.embedded.enabled=true
76+
----
77+
78+
The SBOM will be embedded as a classpath resource at `META-INF/sbom/application.cdx.json` by default. The resource name can be customized:
79+
80+
[source,properties]
81+
----
82+
quarkus.cyclonedx.embedded.resource-name=META-INF/custom-sbom.json
83+
----
84+
85+
The format is determined by the resource name extension: `.json` for JSON, `.xml` for XML.
86+
87+
[[sbom-endpoint]]
88+
=== SBOM REST Endpoint
89+
90+
The embedded SBOM can be exposed through a REST endpoint, making it accessible to external tools and scanners at runtime. To enable the endpoint:
91+
92+
[source,properties]
93+
----
94+
quarkus.cyclonedx.endpoint.enabled=true
95+
----
96+
97+
This will serve the embedded SBOM at `/.well-known/sbom` with the `application/vnd.cyclonedx+json` content type (or `application/vnd.cyclonedx+xml` for XML SBOMs). The path can be customized using the `quarkus.cyclonedx.endpoint.path` property.
98+
99+
NOTE: Enabling the endpoint will automatically trigger SBOM embedding, even if `quarkus.cyclonedx.embedded.enabled` is not explicitly set to `true`.
100+
101+
The endpoint requires `quarkus-vertx-http` to be present on the classpath, which is the case for most web applications (e.g., those using `quarkus-rest`).
66102

67103
== Distribution SBOMs
68104

69-
This chapter describes SBOMs that manifest outcomes of Quarkus builds that are final application distributions.
105+
Distribution SBOMs manifest the outcomes of Quarkus builds — the final application distributions. Unlike dependency SBOMs, which describe the input to a build, distribution SBOMs describe what was actually produced.
70106

71-
During an application build and package assembly process, Quarkus captures certain details about the produced distribution and then allows an SBOM generator to consume and record that information in an SBOM format.
107+
During the build and package assembly process, Quarkus captures details about the produced distribution and allows an SBOM generator to record that information in an SBOM format.
72108

73-
At this point, the only SBOM generator available for Quarkus users that can manifest application distributions is `io.quarkus:quarkus-cyclonedx`. Once it's added as a project dependency it will generate SBOMs every time an application is built. SBOMs will be saved in the project's build output directory under `<executable-name>-cyclonedx.<format>` name, where
109+
To generate CycloneDX distribution SBOMs, add `io.quarkus:quarkus-cyclonedx` as a project dependency. It will generate SBOMs every time an application is built. SBOMs will be saved in the project's build output directory under `<executable-name>-cyclonedx.<format>` name, where
74110

75-
* `<executable-name>` is the base file name (without the extension) of the executable that launches an application;
76-
* `<format>` is either `json` (the default) or `xml`, which can be configured using `quarkus.cyclonedx.format` property. If both formats are desired `quarkus.cyclonedx.format` can be set to `all`.
111+
* `<executable-name>` is the base file name (without the extension) of the executable that launches the application;
112+
* `<format>` is either `json` (the default) or `xml`, which can be configured using the `quarkus.cyclonedx.format` property. If both formats are desired, `quarkus.cyclonedx.format` can be set to `all`.
77113

78114
=== Fast JAR
79115

@@ -161,7 +197,7 @@ SBOMs for native images will use the native executable file as their main compon
161197

162198
Since native executables are not currently attached to projects as Maven artifacts, their SBOMs will not be attached as Maven artifacts either.
163199

164-
As in the case of an Uber JAR, runtime components in an SBOM generated for an native executable will not include `evidence.occurrences.location` since their corresponding code and resources are included in a single native executable file.
200+
As in the case of an Uber JAR, runtime components in an SBOM generated for a native executable will not include `evidence.occurrences.location` since their corresponding code and resources are included in a single native executable file.
165201

166202
=== Mutable JAR
167203

@@ -195,4 +231,4 @@ SBOMs generated for Mutable JAR distributions will also record locations of comp
195231

196232
|`quarkus:component:scope` |`runtime` or `development` |Indicates whether a component is a runtime or a build/development time dependency of an application.
197233
|`quarkus:component:location` |String representing a file system path using `/` as a path element |Used in SBOMs with schema versions 1.4 or older. Starting from schema 1.5, `evidence.occurrences.location` is used instead. This property is used only if a component is found in the distribution. The value is a relative path to a file pointing to the location of a component in a distribution using `/` as a path element separator.
198-
|===
234+
|===
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>quarkus-cyclonedx-parent</artifactId>
7+
<groupId>io.quarkus</groupId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>quarkus-cyclonedx-deployment-spi</artifactId>
13+
<name>Quarkus - CycloneDX - Deployment SPI</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>io.quarkus</groupId>
18+
<artifactId>quarkus-core-deployment</artifactId>
19+
</dependency>
20+
</dependencies>
21+
22+
</project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.quarkus.cyclonedx.deployment.spi;
2+
3+
import io.quarkus.builder.item.MultiBuildItem;
4+
5+
/**
6+
* Produced by extensions that require an embedded dependency SBOM to be generated
7+
* as a classpath resource.
8+
*/
9+
public final class EmbeddedSbomRequestBuildItem extends MultiBuildItem {
10+
}

extensions/cyclonedx/deployment/pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
<groupId>io.quarkus</groupId>
3232
<artifactId>quarkus-cyclonedx-generator</artifactId>
3333
</dependency>
34+
<dependency>
35+
<groupId>io.quarkus</groupId>
36+
<artifactId>quarkus-cyclonedx-deployment-spi</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>io.quarkus</groupId>
40+
<artifactId>quarkus-cyclonedx-endpoint-deployment</artifactId>
41+
<optional>true</optional>
42+
</dependency>
3443
</dependencies>
3544

3645
<build>

0 commit comments

Comments
 (0)