skip to content

How do you ensure the generated bom.xml/bom.json is published alongside your build, and how is it consumed downstream?

level: seniorimportance: should knowfreq 30%

answer

  1. attached artifact + cyclonedx classifier
  2. install/deploy publishes it
  3. skipAttach toggle
  4. Dependency-Track re-scans stored BOMs
  5. Grype/Trivy fail the build

basics

~10 s

The cyclonedx-maven-plugin attaches the BOM as a secondary build artifact by default, so mvn install/deploy publish it next to the JAR with a 'cyclonedx' classifier. CI then feeds it to scanners like Dependency-Track.

solid answer

~40 s

By default the cyclonedx-maven-plugin sets `projectType` and attaches the BOM as a **secondary (attached) artifact** with a `cyclonedx` classifier, so when `install`/`deploy` run, the `bom.xml`/`bom.json` is published to your local repo or remote repository (Nexus/Artifactory) alongside the primary JAR — same GAV, different classifier/extension. That means consumers and CI can pull the SBOM by coordinate. You can toggle this with the `<skipAttach>` config. Downstream, CI typically uploads the BOM to **OWASP Dependency-Track** (which continuously re-scans stored BOMs as new CVEs appear) or runs a scanner like **Grype**/**Trivy** against the BOM in the same pipeline to fail the build on policy violations. Storing the SBOM as a release artifact also satisfies audit/compliance requirements to retain a per-release inventory.

code

bash · 4 lines
bash
mvn -B package org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom
curl -X POST https://dtrack/api/v1/bom \
  -H "X-Api-Key: $DT_KEY" \
  -F project=$PROJECT_UUID -F bom=@target/bom.json

go deeper

for a junior

Knows the BOM ends up in target/ and can be published.

for a middle

Knows it's attached with a cyclonedx classifier on install/deploy and can toggle skipAttach.

for a senior

Designs CI to upload to Dependency-Track or gate with Grype/Trivy.

for a principal

Owns retention/compliance policy and continuous post-release vulnerability monitoring.

## Attaching the BOM as an artifact Maven distinguishes the **primary artifact** (your JAR/WAR) from **attached/secondary artifacts** — extra files published under the same coordinates (groupId:artifactId:version, or **GAV**) but distinguished by a **classifier** and/or extension. The `cyclonedx-maven-plugin` **attaches the BOM by default**. So after: ```bash mvn deploy ``` your repository gets, e.g.: - `app-1.2.0.jar` (primary) - `app-1.2.0-cyclonedx.xml` and `app-1.2.0-cyclonedx.json` (attached SBOMs) This means any consumer or scanner can retrieve the SBOM **by coordinate**, not just from the build's `target/` dir. Control it via config: ```xml <configuration> <outputFormat>all</outputFormat> <skipAttach>false</skipAttach> <!-- default: attach --> <projectType>application</projectType> </configuration> ``` Set `<skipAttach>true</skipAttach>` if you only want the file in `target/` (e.g., you push it elsewhere yourself). ## Downstream consumption 1. **OWASP Dependency-Track** — the most common pattern. CI uploads the CycloneDX BOM to a Dependency-Track server, which stores it and **continuously re-evaluates** it against vulnerability feeds. The power here: a CVE disclosed *after* your release still flags your stored SBOM without rebuilding. 2. **Scanners in CI** — tools like **Grype** or **Trivy** can scan a CycloneDX file directly and **fail the pipeline** on findings above a severity threshold. 3. **License/compliance** — feed the component inventory (with license fields) into a compliance gate that blocks disallowed licenses (e.g., GPL in a proprietary product). 4. **Audit retention** — keeping the SBOM as a published release artifact provides the per-release inventory regulators and customers increasingly require. ## CI example ```bash mvn -B package org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom curl -X POST https://dtrack/api/v1/bom \ -H "X-Api-Key: $DT_KEY" \ -F project=$PROJECT_UUID \ -F bom=@target/bom.json ``` ## Gotchas - The classifier is `cyclonedx`; the SBOM shares the project's version, so SNAPSHOT BOMs follow SNAPSHOT semantics. - If you skip attach, remember to publish/upload the file another way or your downstream gate sees nothing.

  • What classifier does the attached SBOM use?
    cyclonedx — so it deploys as artifactId-version-cyclonedx.xml/.json under the same GAV as the primary artifact.
  • Why upload to Dependency-Track instead of only scanning at build time?
    Dependency-Track re-evaluates the stored SBOM against new vulnerability data continuously, so CVEs disclosed after release are caught without rebuilding.
  • How do you stop the plugin from attaching the BOM?
    Set <skipAttach>true</skipAttach>; the file still lands in target/ but isn't published with install/deploy.

saying these in an interview costs you the question

  • Believing the BOM is lost after the build unless you copy it manually (it's attached by default)
  • Thinking a one-time CI scan is sufficient — continuous re-scanning catches post-release CVEs
  • Forgetting SNAPSHOT BOMs inherit SNAPSHOT versioning

context