Record a build system reference inside the SBOM, a URL that points to the CI job that created it. The CycloneDX Gradle plugin can do this automatically for several CI systems when includeBuildSystem is true, and lets you build a custom URL from environment variables for others.
Why bother
An SBOM file on its own says what a build contained, not where it came from. Months later someone asks which job produced it, which commit, and whether it can be trusted. If the file carries a link to the CI run, those questions have a starting point. Without one, you depend on file names and memory.
A build reference is not proof. Anyone who can edit the file can edit the link. It is a pointer that helps investigation and audit, and it complements, not replaces, signatures and provenance.
What the Gradle plugin does
According to the README, when includeBuildSystem is true the plugin automatically detects build URLs from GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis CI and Drone. For anything else, buildSystemEnvironmentVariable lets you name an environment variable, or compose a URL from several.
A rule to know: every variable in a template must exist and have a non blank value, otherwise no build system reference is added. The failure is silent, in the sense that the build still succeeds and the SBOM is produced without the link.
Kotlin DSL example from the README:
tasks.cyclonedxDirectBom {
buildSystemEnvironmentVariable = "\${CI_SERVER_URL}/jobs/\${CI_JOB_ID}"
}
To read one variable directly, set the property to its name, for example BUILD_URL.
Steps to adopt it
- Choose the CI system and find the variables that make up a link to a single job.
- Turn the build reference on in your plugin configuration.
- Run a build in CI, not locally, since local runs lack the variables.
- Open the SBOM and confirm the reference exists and the link opens the right job.
- Add a pipeline check that fails if the reference is missing, since the plugin will not.
Step 5 turns a silent gap into a visible one.
What else belongs next to the link
A build reference answers "which job". A good release record also holds:
| Item | Why |
|---|---|
| Commit hash | Identifies the source |
| Tool name and version | Lets someone reproduce the output |
| Generation time | Shows freshness |
| Checksum or signature | Detects later changes |
The SBOM format has places for several of these, such as tool metadata and timestamps. Store the rest in your release record.
Other ecosystems
The same idea applies in Maven and npm builds, even though the plugin details differ. If your generator has no build reference setting, you can record the link in your release record next to the file, or add it as metadata in a post processing step. If you edit the file after generation, document the step and keep the original, since an SBOM that has been changed needs an explanation.
What to avoid
Do not put secrets or internal hostnames you would not share in a link. If the SBOM goes to customers, a CI URL on an internal domain tells them nothing and reveals a hostname. Decide whether the shared copy should carry the link or whether it stays in your internal copy.
Safeguard's SBOM and dependency scanning keeps each SBOM with its inventory and findings, and the free scan is a way to see how a file is read.
Quick check
Does the reference prove who built the file?
No. It is a pointer for tracing. Use signatures and build provenance for stronger assurance.
Why is my build reference missing?
Likely a variable in the template is unset or blank, or the build ran locally. The plugin adds no reference in that case.
Sources
Last reviewed: 19 October 2026.