The software bill of materials is public

The API serves its CycloneDX bill of materials at /api/sbom/application, the same list of dependencies the public repository already implies, so anyone can check what runs behind the site.

Status
Accepted 3 October 2026
The record
0010-public-sbom.md

Context

Until now the API exposed nothing from Actuator but health. The build already produces a CycloneDX SBOM (Spring Boot packs it into the jar) and CI scans the image with Trivy, failing on fixable high and critical vulnerabilities. The engineering page wants to show what the service is made of, and an SBOM is the standard, machine-readable answer.

The repository is public, so the dependency versions are no secret: the Gradle build names them, and the Spring Boot BOM it imports fixes the transitive ones. An SBOM spells them all out, which saves an attacker a build, not a discovery.

Decision

Expose Actuator's sbom endpoint next to health: GET /api/sbom lists the bills (application), and GET /api/sbom/application returns the CycloneDX JSON (about 350 KB). Nothing else from Actuator is exposed; a test requests the usual suspects (env, beans, heapdump, threaddump, configprops) and expects 404.

Consequences

  • The engineering page links to it, and anyone can feed it to their own scanner.
  • What it reveals is only as current as the last deploy, which is why the image is rebuilt and rescanned on every push, and why the Spring Boot BOM overrides from the Trivy run (Tomcat, Jackson) matter.
  • It is not rate-limited: it is a file read from the jar, and a flood of downloads costs cents in egress.
  • If the repository were ever made private, this decision should be revisited with it.