CLOVER🍀

That was when it all began.

CycloneDX Maven Plugin(CycloneDX for Maven)でSBOM(Software Bill of Materials)を作ってみる

これは、なにをしたくて書いたもの?

前に、SBOM(Software Bill of Materials)について調べてみました。

SBOM(Software Bill of Materials)について少し調べてみる - CLOVER🍀

今回は、SBOMの作成をやってみたいと思います。フォーマットとしてはCycloneDX、SBOMを作成するツールとしては
CycloneDX Maven Plugin(CycloneDX for Maven)を使います。

CycloneDX

CycloneDXとはなんだったか?というところからですが、これはOWASPコミュニティが開発したセキュリティに得化した
SBOMフォーマットです。

コンポーネントやライセンス、コピーライト等の情報も含みます。

CycloneDX Bill of Materials Standard | CycloneDX

OWASP CycloneDX (ECMA-424) | OWASP Foundation

OWASPのページにリストがありますが、サポートしている仕様は以下のようです。

  • Software Bill of Materials (SBOM)
  • Software-as-a-Service Bill of Materials (SaaSBOM)
  • Hardware Bill of Materials (HBOM)
  • Machine Learning Bill of Materials (ML-BOM)
  • Cryptography Bill of Materials (CBOM)
  • Manufacturing Bill of Materials (MBOM)
  • Operations Bill of Materials (OBOM)
  • Vulnerability Disclosure Reports (VDR)
  • Vulnerability Exploitability eXchange (VEX)
  • CycloneDX Attestations (CDXA)

こちらからも確認できます。

Software Bill of Materials (SBOM) | CycloneDX

ユースケースについてはこちら。

Security Use Cases and Examples | CycloneDX

仕様。メディアタイプはXMLJSON、Protocol Buffersがあるようです。

Specification Overview | CycloneDX

リファレンス。

CycloneDX v1.6 JSON Reference

CycloneDX Maven Plugin(CycloneDX for Maven

CycloneDX Maven PluginのWebサイトはこちら。

CycloneDX Maven plugin –

GitHubリポジトリーはこちら。

GitHub - CycloneDX/cyclonedx-maven-plugin: Creates CycloneDX Software Bill of Materials (SBOM) from Maven projects

CycloneDX Maven Pluginは、CycloneDXに関するツールの一種です。

CycloneDX Capabilities | CycloneDX

Mavenプロジェクトの推移的依存関係を含む、CycloneDXフォーマットのSBOMを生成することができます。

The CycloneDX Maven plugin generates CycloneDX Software Bill of Materials (SBOM) containing the aggregate of all direct and transitive dependencies of a project. CycloneDX is a full-stack SBOM standard designed for use in application security contexts and supply chain component analysis.

ゴールは以下の3つがあります。

  • makeBom … 各Mavenモジュールとその依存関係に対してBOMを作成する
  • makeAggregateBom … マルチモジュールビルド全体の依存関係を含む集約BOMを作成する。各モジュールのBOMも作成する
  • makePackageBom … WARまたはEARでパッケージングされた各Mavenモジュールに対してBOMを作成する

CycloneDX Maven Plugin / Goals

以下が使用例として載せられていますが、packageゴール時にSBOMを生成するようにするみたいです。

<!-- uses default configuration -->
<plugins>
    <plugin>
        <groupId>org.cyclonedx</groupId>
        <artifactId>cyclonedx-maven-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>makeAggregateBom</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

デフォルト値は以下で、およその意味はだいたいわかりそうな感じですね。

<plugins>
    <plugin>
        <groupId>org.cyclonedx</groupId>
        <artifactId>cyclonedx-maven-plugin</artifactId>
        <configuration>
            <projectType>library</projectType>
            <schemaVersion>1.6</schemaVersion>
            <includeBomSerialNumber>true</includeBomSerialNumber>
            <includeCompileScope>true</includeCompileScope>
            <includeProvidedScope>true</includeProvidedScope>
            <includeRuntimeScope>true</includeRuntimeScope>
            <includeSystemScope>true</includeSystemScope>
            <includeTestScope>false</includeTestScope>
            <includeLicenseText>false</includeLicenseText>
            <outputReactorProjects>true</outputReactorProjects>
            <outputFormat>all</outputFormat>
            <outputName>bom</outputName>
            <outputDirectory>${project.build.directory}</outputDirectory><!-- usually target, if not redefined in pom.xml -->
            <verbose>false</verbose><!-- = ${cyclonedx.verbose} -->
        </configuration>
    </plugin>
</plugins>

projectTypeというのはコンポーネントの種類を表し、デフォルトはlibraryです。どんな種類があるかは仕様に書かれています。

CycloneDX v1.6 JSON Reference / metadata / component / type

また、デフォルトではinstallまたはdeployゴール実行時に、cyclonedxというclassifierで生成したSBOM(XMLJSON)を
添付するようです。

By default, the BOM(s) will be attached as an additional artifacts with cyclonedx classifier (can be customized by setting cyclonedx.classifier) and xml or json extension during a Maven install or deploy:

デフォルトのファイル名は以下になります。

  • ${project.artifactId}-${project.version}-cyclonedx.xml
  • ${project.artifactId}-${project.version}-cyclonedx.json

CycloneDX Maven Plugin / Goals

classifier、ファイル名、添付するかどうかは設定可能です。

それでは簡単に使ってみましょう。

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.5 2024-10-15
OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu124.04)
OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu124.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.5, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-52-generic", arch: "amd64", family: "unix"

準備

今回はRESTEasyでJakarta RESTful Web ServicesのSeBootstrapを使ったサンプルを作り、このプロジェクトでSBOMを
生成してみたいと思います。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.littlewings</groupId>
    <artifactId>cyclonedx-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-core</artifactId>
            <version>6.2.11.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-undertow-cdi</artifactId>
            <version>6.2.11.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
            <version>6.2.11.Final</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.11.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.27.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.8.1</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.4.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>org.littlewings.cyclonedx.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

なんとなくテストライブラリーも足しています。

JAX-RSのリソースクラス。

src/main/java/org/littlewings/cyclonedx/MessageResource.java

package org.littlewings.cyclonedx;

import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

@Path("/message")
@ApplicationScoped
public class MessageResource {
    @Inject
    private MessageService messageService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, Object> get(@QueryParam("value") String value) {
        return Map.of("message", messageService.decorate(value));
    }
}

JAX-RSの有効化。

src/main/java/org/littlewings/cyclonedx/RestApplication.java

package org.littlewings.cyclonedx;

import java.util.Set;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("/")
public class RestApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        return Set.of(MessageResource.class);
    }
}

src/main/java/org/littlewings/cyclonedx/MessageService.java

package org.littlewings.cyclonedx;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MessageService {
    public String decorate(String value) {
        return String.format("★★★%s★★★", value);
    }
}

mainクラス。

src/main/java/org/littlewings/cyclonedx/App.java

package org.littlewings.cyclonedx;

import java.util.concurrent.ExecutionException;

import jakarta.ws.rs.SeBootstrap;

public class App {
    public static void main(String... args) throws ExecutionException, InterruptedException {
        SeBootstrap.Configuration configuration = SeBootstrap.Configuration.builder()
                .host("0.0.0.0")
                .port(8080)
                .build();

        SeBootstrap.Instance instance =
                SeBootstrap.start(RestApplication.class, configuration).toCompletableFuture().get();

        System.console().readLine("> Enter stop");

        instance.stop().toCompletableFuture().get();
    }
}

Jakarta Contexts and Dependency Injection(CDI)の有効化。

src/main/resources/META-INF/beans.xml
※中身は空です




テストコード。

src/test/java/org/littlewings/cyclonedx/MessageServiceTest.java

package org.littlewings.cyclonedx;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class MessageServiceTest {
    @Test
    void test() {
        MessageService messageService = new MessageService();
        assertThat(messageService.decorate("hello world"))
                .isEqualTo("★★★hello world★★★");
    }
}

動作確認。

$ mvn package
$ java -jar target/cyclonedx-example-0.0.1-SNAPSHOT.jar

OKですね。

$ curl localhost:8080/message?value=Hello
{"message":"★★★Hello★★★"}

準備はできました。

CycloneDX Maven Pluginを使ってSBOMを生成してみる

それでは、CycloneDX Maven Pluginを使ってSBOMを生成してみたいと思います。

まずはこちらを追加。

            <plugin>
                <groupId>org.cyclonedx</groupId>
                <artifactId>cyclonedx-maven-plugin</artifactId>
                <version>2.9.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>makeAggregateBom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

パッケージングしてみます。

$ mvn package

すると、JARファイルを作成した後にSBOMが生成されます。

[INFO] --- cyclonedx:2.9.1:makeAggregateBom (default) @ cyclonedx-example ---
[INFO] CycloneDX: Resolving Dependencies
[INFO] CycloneDX: Creating BOM version 1.6 with 52 component(s)
[INFO] CycloneDX: Writing and validating BOM (XML): /path/to/target/bom.xml
[INFO]            attaching as cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.xml
[INFO] CycloneDX: Writing and validating BOM (JSON): /path/to/target/bom.json
[WARNING] Unknown keyword meta:enum - you should define your own Meta Schema. If the keyword is irrelevant for validation, just use a NonValidationKeyword or if it should generate annotations AnnotationKeyword
[WARNING] Unknown keyword deprecated - you should define your own Meta Schema. If the keyword is irrelevant for validation, just use a NonValidationKeyword or if it should generate annotations AnnotationKeyword
[INFO]            attaching as cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.json

2ファイル作成されたようです。

[INFO] CycloneDX: Writing and validating BOM (XML): /path/to/target/bom.xml


[INFO] CycloneDX: Writing and validating BOM (JSON): /path/to/target/bom.json

デフォルトでは、target配下にbom.xmlbom.jsonというファイル名で作成されます。

installdeploy時に添付するSBOMというのはこちらですね。

[INFO]            attaching as cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.json

全部で4000行くらいのJSONのSBOMになったので、最初の200行を載せておきます。

$ head -n 200 target/bom.json
{
  "bomFormat" : "CycloneDX",
  "specVersion" : "1.6",
  "serialNumber" : "urn:uuid:bcff4a8b-2583-33c6-acba-6123b2796462",
  "version" : 1,
  "metadata" : {
    "timestamp" : "2025-01-29T15:17:56Z",
    "lifecycles" : [
      {
        "phase" : "build"
      }
    ],
    "tools" : {
      "components" : [
        {
          "type" : "library",
          "author" : "OWASP Foundation",
          "group" : "org.cyclonedx",
          "name" : "cyclonedx-maven-plugin",
          "version" : "2.9.1",
          "description" : "CycloneDX Maven plugin",
          "hashes" : [
            {
              "alg" : "MD5",
              "content" : "9c7a565cf28cce58557d0c621c5ea4b1"
            },
            {
              "alg" : "SHA-1",
              "content" : "be882d5a22050bfa9d19090b1420c188617d0e1c"
            },
            {
              "alg" : "SHA-256",
              "content" : "698e0f37184a5b28c245c4065fd036dfce253b52f82fbb7113d81d36326cc249"
            },
            {
              "alg" : "SHA-512",
              "content" : "c0f0b11026858166f872a2eb54719492e5cecaa0bc9cd6b30b3ecb4a174eed220f4a1b5829d18d6734128e778d3cb3db7ffed177c92866133129cb29081814a0"
            },
            {
              "alg" : "SHA-384",
              "content" : "d80964707dfe5caca8c70521d5066f57589304c0a657e6fbc7c0614ea0fc7b3b3dbe7778361eee0f54ba111e9cb0ffcb"
            },
            {
              "alg" : "SHA3-384",
              "content" : "80bc3a275d9514bc457461ff52a72add8c7ecbbc01d8912efce57139016c544ee776981851be0a58fa977ab4221f703f"
            },
            {
              "alg" : "SHA3-256",
              "content" : "142317d6f245390f4fd2d0c100b16281b8dfc5c0c2cff86943bdcc97039cb699"
            },
            {
              "alg" : "SHA3-512",
              "content" : "af0fb9137c90b65d1a07f72e4d51ae509956cdb8800f35c961b037cdda1fe4a14ce3b496cef71ba85f1621affcfe29cd42704ae4191ff0b090a9602087c8997b"
            }
          ]
        }
      ]
    },
    "component" : {
      "type" : "library",
      "bom-ref" : "pkg:maven/org.littlewings/cyclonedx-example@0.0.1-SNAPSHOT?type=jar",
      "group" : "org.littlewings",
      "name" : "cyclonedx-example",
      "version" : "0.0.1-SNAPSHOT",
      "purl" : "pkg:maven/org.littlewings/cyclonedx-example@0.0.1-SNAPSHOT?type=jar"
    },
    "properties" : [
      {
        "name" : "maven.goal",
        "value" : "makeAggregateBom"
      },
      {
        "name" : "maven.scopes",
        "value" : "compile,provided,runtime,system"
      }
    ]
  },
  "components" : [
    {
      "type" : "library",
      "bom-ref" : "pkg:maven/org.jboss.resteasy/resteasy-core@6.2.11.Final?type=jar",
      "publisher" : "JBoss by Red Hat",
      "group" : "org.jboss.resteasy",
      "name" : "resteasy-core",
      "version" : "6.2.11.Final",
      "description" : "",
      "scope" : "required",
      "hashes" : [
        {
          "alg" : "MD5",
          "content" : "a1639d8faa44c7163bbb41b16c522c44"
        },
        {
          "alg" : "SHA-1",
          "content" : "ceb296efcba0df34ffa9801be70ed74f60f67d9c"
        },
        {
          "alg" : "SHA-256",
          "content" : "9668c60d2e683404ac13a91212a1e54dc7a6b19f0e247178e36531955c802cdb"
        },
        {
          "alg" : "SHA-512",
          "content" : "442d2fecc63c5a6263ba07081de34816dc9fb938b547d5a23a6aaa9bc02b8b764a7c28e879c4d2c01ecfdbd56bc0899bc4065fc7e26d6c95462d322bd69448bb"
        },
        {
          "alg" : "SHA-384",
          "content" : "f905fb177f8b399031076b6c11f31af3ef625651d704fc67fc9b2e67715293ae763a773ca8e4b9ffe0d416dd1cde98ca"
        },
        {
          "alg" : "SHA3-384",
          "content" : "a24ca748cc10c59307fe866fcf2e99e9b4d82be0b3b127354252d5716f32f0bc4d84d2a8952f43eb9f08b14b0d9fcc54"
        },
        {
          "alg" : "SHA3-256",
          "content" : "b03de5d6c368dd5adbff0e393fabce65c1c2b923fe54cf232da2fba3431c3550"
        },
        {
          "alg" : "SHA3-512",
          "content" : "fa73cbbe92dae3833a85f8e52fb4a5456178618e4deefdfe013d8ebaa0525c8351505f42617735137138a58e18d6d7e2c7d4188ca9a3390d6b4cf00194b02bc4"
        }
      ],
      "licenses" : [
        {
          "license" : {
            "id" : "Apache-2.0",
            "url" : "https://www.apache.org/licenses/LICENSE-2.0"
          }
        }
      ],
      "purl" : "pkg:maven/org.jboss.resteasy/resteasy-core@6.2.11.Final?type=jar",
      "externalReferences" : [
        {
          "type" : "website",
          "url" : "https://resteasy.dev"
        },
        {
          "type" : "issue-tracker",
          "url" : "https://issues.redhat.com/browse/RESTEASY"
        },
        {
          "type" : "mailing-list",
          "url" : "http://lists.jboss.org/pipermail/jboss-user/"
        },
        {
          "type" : "vcs",
          "url" : "https://github.com/resteasy/resteasy/tree/main/"
        }
      ]
    },
    {
      "type" : "library",
      "bom-ref" : "pkg:maven/org.jboss.logging/jboss-logging@3.5.3.Final?type=jar",
      "publisher" : "JBoss by Red Hat",
      "group" : "org.jboss.logging",
      "name" : "jboss-logging",
      "version" : "3.5.3.Final",
      "description" : "The JBoss Logging Framework",
      "scope" : "required",
      "hashes" : [
        {
          "alg" : "MD5",
          "content" : "ee7e24e94235c13f53392ecaa53f938c"
        },
        {
          "alg" : "SHA-1",
          "content" : "c88fc1d8a96d4c3491f55d4317458ccad53ca663"
        },
        {
          "alg" : "SHA-256",
          "content" : "7b119460de174195aca412dfed52ca0bbef0ece26c2d74301b6172cfadf4ff59"
        },
        {
          "alg" : "SHA-512",
          "content" : "cf3d5ccb791c3cf52d6af509056a1027cb6182a552b6fc66a593cf119812ba229f52d73f26f11555f248c8ef7ac45c11c27acb3c56dc73e627feee8b53275766"
        },
        {
          "alg" : "SHA-384",
          "content" : "1b266fa1a354f8ec938066db3f41b778c421d67150919213946c5022310a45fa37f7d81cd6ddbd3e0fdc97fb9db2beac"
        },
        {
          "alg" : "SHA3-384",
          "content" : "319213adb97dd49a5e1e2d76ac0f906624707580f7997c25c9ab0771a95a2d5110393d2c4cca4ef463b9ba6735d6a22a"
        },
        {
          "alg" : "SHA3-256",
          "content" : "0b8a39595fd082a12943142c8a856210a9edb38d7c4690b10e0fbf4b5310f517"
        },
        {
          "alg" : "SHA3-512",
          "content" : "d338491f03dddd461255aca2a054d414cfcddc8cc02546eb946941e3a2b6cb99b5a6e0f295059e34a0ed381d456c22ccce03644d7d19d41d99c2a61651b1e4a6"
        }
      ],
      "licenses" : [
        {
          "license" : {
            "id" : "Apache-2.0",
            "url" : "https://www.apache.org/licenses/LICENSE-2.0"
          }
        }
      ],

CycloneDXのSBOMのリファレンスはこちらでした。

CycloneDX v1.6 JSON Reference

デフォルトではテストスコープは含まれていないようだったので、JUnitはSBOMには入っていません。

$ grep junit target/bom.json

推移的依存関係であるJacksonは入っています。

$ grep jackson target/bom.json | head -n 20
      "bom-ref" : "pkg:maven/org.jboss.resteasy/resteasy-jackson2-provider@6.2.11.Final?type=jar",
      "name" : "resteasy-jackson2-provider",
      "purl" : "pkg:maven/org.jboss.resteasy/resteasy-jackson2-provider@6.2.11.Final?type=jar",
      "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.18.1?type=jar",
      "group" : "com.fasterxml.jackson.core",
      "name" : "jackson-core",
      "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.18.1?type=jar",
          "url" : "https://github.com/FasterXML/jackson-core"
          "url" : "https://github.com/FasterXML/jackson-core/issues"
          "url" : "https://github.com/FasterXML/jackson-core"
      "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.18.1?type=jar",
      "group" : "com.fasterxml.jackson.core",
      "name" : "jackson-databind",
      "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.18.1?type=jar",
          "url" : "https://github.com/FasterXML/jackson"
          "url" : "https://github.com/FasterXML/jackson-databind/issues"
          "url" : "https://github.com/FasterXML/jackson-databind"
      "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.18.1?type=jar",
      "group" : "com.fasterxml.jackson.core",
      "name" : "jackson-annotations",

たくさん出てきますが…。

mvn installすると

$ mvn install

JARやpom.xmlと一緒にSBOMもインストールされます。

[INFO] --- install:3.1.2:install (default-install) @ cyclonedx-example ---
[INFO] Installing /path/to/pom.xml to $HOME/.m2/repository/org/littlewings/cyclonedx-example/0.0.1-SNAPSHOT/cyclonedx-example-0.0.1-SNAPSHOT.pom
[INFO] Installing /path/to/target/cyclonedx-example-0.0.1-SNAPSHOT.jar to $HOME/.m2/repository/org/littlewings/cyclonedx-example/0.0.1-SNAPSHOT/cyclonedx-example-0.0.1-SNAPSHOT.jar
[INFO] Installing /path/to/target/bom.xml to $HOME/.m2/repository/org/littlewings/cyclonedx-example/0.0.1-SNAPSHOT/cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.xml
[INFO] Installing /path/to/target/bom.json to $HOME/.m2/repository/org/littlewings/cyclonedx-example/0.0.1-SNAPSHOT/cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.json

少し設定してみましょう。

            <plugin>
                <groupId>org.cyclonedx</groupId>
                <artifactId>cyclonedx-maven-plugin</artifactId>
                <version>2.9.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>makeAggregateBom</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <projectType>application</projectType>
                    <outputName>application.cdx</outputName>
                    <outputFormat>json</outputFormat>
                </configuration>
            </plugin>

configurationJSONにしたり、生成するファイル名を変えたり、出力するのをJSONのみにしたりしてみました。

パッケージング。

$ mvn package

生成されるのがJSONのみになり、ファイル名も変わりました。

[INFO] --- cyclonedx:2.9.1:makeAggregateBom (default) @ cyclonedx-example ---
[INFO] CycloneDX: Resolving Dependencies
[INFO] CycloneDX: Creating BOM version 1.6 with 52 component(s)
[INFO] CycloneDX: Writing and validating BOM (JSON): /path/to/target/application.cdx.json
[WARNING] Unknown keyword meta:enum - you should define your own Meta Schema. If the keyword is irrelevant for validation, just use a NonValidationKeyword or if it should generate annotations AnnotationKeyword
[WARNING] Unknown keyword deprecated - you should define your own Meta Schema. If the keyword is irrelevant for validation, just use a NonValidationKeyword or if it should generate annotations AnnotationKeyword
[INFO]            attaching as cyclonedx-example-0.0.1-SNAPSHOT-cyclonedx.json
[INFO] ------------------------------------------------------------------------

こちらですね。

[INFO] CycloneDX: Writing and validating BOM (JSON): /path/to/target/application.cdx.json

ひとまず、MavenプロジェクトからSBOMを生成できることは確認できました。

おわりに

CycloneDX Maven Plugin(CycloneDX for Maven)でSBOM(Software Bill of Materials)を作ってみました。

作るだけならとても簡単ですね。Mavenプラグインを追加すればいいいので。

これをどう使っていくのかはまた別ですが…。