GODRIVER-3599 Add task and script to generate CycloneDX SBOM#2154
GODRIVER-3599 Add task and script to generate CycloneDX SBOM#2154jasonhills-mongodb wants to merge 19 commits into
Conversation
API Change ReportNo changes found! |
The GODRIVER SBOM (sbom.json) does not contain the direct and transitive dependencies defined in go.mod. Added code to generate a CycloneDX SBOM in order to better meet NITA Minimum Elements for Software Bill of Materials, OWASP Software Component Verification Standard (SCVS) Level 1, as well as include the necessary component identifiers for vulnerability discovery and VEX responses. Added a task, etc/script, and pre-commit hook for generating a CycloneDX SBOM using a pinned version of the cyclonedx-gomod tool. The SBOM includes the aggregate of modules required by packages in the mongo-go-driver library, excluding examples, tests and test packages. The task (generate-sbom) is added to the default tasks and will run only when go.mod is newer than sbom.cdx.json. The pre-commit hook (sbom-currency) ensures that if go.mod is staged for commit, that an updated sbom.json is also staged. Future TODO: Add libmongocrypt as an optional component once the libmongocrypt SBOM is updated with newer automation
7c63b31 to
a0af51a
Compare
Co-authored-by: Preston Vasquez <prestonvasquez@icloud.com>
🧪 Performance ResultsCommit SHA: e1810f1The following benchmark tests for version 6a32e3d89ddf40000726ce4e had statistically significant changes (i.e., |z-score| > 1.96):
For a comprehensive view of all microbenchmark results for this PR's commit, please check out the Evergreen perf task for this patch. |
…edx-gomod Resolves merge conflicts and redesigns SBOM automation: - Add GitHub Actions workflow to generate sbom.json and open a PR when go.mod changes - Add Evergreen upload-sbom task + build variant (paths: sbom.json) to upload via silkbomb - Add etc/sbom.sh for silkbomb augment invocation - Remove sbom-currency pre-commit hook (CI now owns generation) - Remove generate-sbom from Taskfile default deps - Update cyclonedx-gomod to v1.10.0 and cyclonedx-cli to v0.32.0
Derives the version from etc/install-libmongocrypt.sh and injects the component into sbom.json after cyclonedx-gomod generation, including the dependency relationship on the main module.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds tooling and CI automation to generate, validate, and upload a CycloneDX SBOM for the Go driver, including Evergreen integration and a GitHub Actions workflow to auto-open SBOM update PRs.
Changes:
- Generate
sbom.jsonviacyclonedx-gomodand injectlibmongocryptas an optional component. - Add GitHub Actions workflow to regenerate/validate SBOM on
go.modchanges and open PRs when it differs. - Add Evergreen task and helper script to upload/compare augmented SBOMs via Silkbomb.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| sbom.json | Replaces placeholder SBOM with a populated CycloneDX 1.5 SBOM including dependencies and libmongocrypt. |
| etc/sbom.sh | Adds Silkbomb-based augmented SBOM generation/comparison logic for CI uploads. |
| etc/generate-sbom.sh | Adds a generator script using cyclonedx-gomod plus post-processing with jq. |
| Taskfile.yml | Adds a generate-sbom task to produce sbom.json based on timestamps. |
| .github/workflows/sbom.yml | Adds workflow to regenerate/validate SBOM and open PRs automatically. |
| .evergreen/config.yml | Adds upload-sbom task and an sbom buildvariant to run it on sbom.json changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use set -eo pipefail to catch pipeline failures in generate-sbom.sh - Replace curl -L -s with curl -fsSL for clearer HTTP error reporting - Remove stale CHECK_CURRENCY/-c scaffolding (pre-commit hook removed)
- Use cyclonedx-gomod -serial, -std=true, -short-purls=true flags; -short-purls replaces the jq PURL-stripping workaround - Hardcode serialNumber; increment .version only on meaningful content change - Workflow diff strips only .metadata.timestamp (not .version) - Add AWS_SESSION_TOKEN to etc/sbom.sh and Evergreen upload-sbom task - Drop -it from podman run in etc/sbom.sh - Add go.sum and etc/install-libmongocrypt.sh to Taskfile generate-sbom sources
- Expand automated PR body to describe what changed and why - Add SBOM section to CONTRIBUTING.md explaining the automated workflow
…m_generation_using_cyclonedx-gomod
…e tag cyclonedx-gomod auto-detects a pseudo-version from the current branch commit, which changes on every commit and is meaningless outside the branch. Use git describe --tags --abbrev=0 to pin to the latest release tag (currently v2.6.0) so the SBOM reflects the actual module version.
…t release tag" This reverts commit 556bd8e.
|
|
||
| silkbomb="901841024863.dkr.ecr.us-east-1.amazonaws.com/release-infrastructure/silkbomb:2.0" | ||
|
|
||
| podman pull "${silkbomb:?}" |
There was a problem hiding this comment.
[blocking] Is there a reason we use podman over docker? Docker is preferred by the team. If it needs to be agnostic, we should make this an env variable. E.g.
| @@ -0,0 +1,52 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
[blocking] CycloneDX notes that you can use as a library ( > v1.2.0). We should opt for this to avoid a CLI dependency in local dev and VM CI and convert etc/generate-sbom.sh to a go script at internal/cmd/generate-sbom/. Despite being more LoC, it's easier for the team to read, update, and bump.
Here is a gist: https://gist.github.com/prestonvasquez/04a194f2f0aff1ba010754e5e9057eb5
Typically, we would defer this work to a followup ticket, but I'm concerned that we could easily miss something with a de facto re-write. Let me know if this would work better if we wrote the Go code and you reviewed for correctness.
| @@ -0,0 +1,59 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
[blocking] Same with generate-sbom.sh, this could be a Go script that leverages the docker API. Here is a gist: https://gist.github.com/prestonvasquez/7d83b6bd919fbcb133bcbcc053e4a2ed
GODRIVER-3599
Background & Motivation
The GODRIVER SBOM (
sbom.json) does not contain the direct and transitive dependencies defined in go.mod. Added code to generate a CycloneDX SBOM in order to better meet NITA Minimum Elements for Software Bill of Materials, OWASP Software Component Verification Standard (SCVS) Level 1, as well as include the necessary component identifiers for vulnerability discovery and VEX responses.Summary
Implements a two-stage CI pipeline for SBOM generation and upload, and adds libmongocrypt as an optional SBOM component.
GitHub Actions (
.github/workflows/sbom.yml): triggers on push tomasterwhengo.mod,go.sum, oretc/install-libmongocrypt.shchanges, or viaworkflow_dispatch. Generatessbom.jsonwith cyclonedx-gomod v1.10.0, validates it with CycloneDX CLI v0.32.0 (hash-verified download), and opens a follow-up PR with the updated file only if substantive content has changed (timestamps and version excluded from diff).Evergreen (
generate-sbom+upload-sbomtasks,sbombuild variant):generate-sbomruns in thestatic-analysisbuild variant on every commit withEXPECT_ERROR=1— it fails ifsbom.jsonis out of date, catching cases where a developer merged ago.modchange without runningtask generate-sbom.upload-sbomtriggers only whensbom.jsonchanges onmaster(viapaths:on the build variant); it usesec2.assume_role+ silkbomb to augment and upload the SBOM to the Dependency-Track backend. Evergreen is used for the upload because GitHub Actions does not have IP access to the Dependency-Track backend. Comparison artifacts (old/new/diff) are uploaded to S3.libmongocrypt is injected as an optional component after SBOM generation: the version is derived from
etc/install-libmongocrypt.shand the component plus its dependency relationship are added viajq.Files changed
.github/workflows/sbom.ymlgo.modchanges and opens a PRetc/generate-sbom.shEXPECT_ERROR=1ifsbom.jsonis staleetc/sbom.sh.evergreen/config.ymlgenerate-sbomtask (static-analysis tag, EXPECT_ERROR=1) andupload-sbomtask +sbombuild variant; docker instead of podmanTaskfile.ymlgenerate-sbomtask for local developer usedocs/CONTRIBUTING.mdsbom.json