ci: add SBOM generation to Docker and CLI releases#580
Conversation
Generate CycloneDX JSON SBOMs for all released artifacts using Syft: - Container images: anchore/sbom-action scans each pushed image, SBOMs uploaded as release assets via update-release job - CLI binaries: GoReleaser sboms: stanza generates per-archive SBOMs - Finalize-release extracts SBOM data and renders download links in the Verification section - LICENSE now included in CLI binary archives - docs/security.md documents the new SBOM subsection - CLAUDE.md and tech-stack.md updated to reflect SBOM generation Satisfies OpenSSF Best Practices badge criterion QA-02.02. Pre-reviewed by 2 agents, 5 findings addressed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the project's supply chain security posture by integrating comprehensive Software Bill of Materials (SBOM) generation into the release process for both Docker container images and CLI binaries. These changes ensure that all released artifacts are accompanied by detailed CycloneDX JSON SBOMs, improving transparency and compliance with security best practices. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (7)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🧰 Additional context used📓 Path-based instructions (1)docs/**/*.md📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (23)📓 Common learnings📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T09:01:47.243ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
🪛 LanguageToolCLAUDE.md[uncategorized] ~107-~107: The official name of this software platform is spelled with a capital “H”. (GITHUB) docs/security.md[style] ~175-~175: A comma is missing here. (EG_NO_COMMA) 🔇 Additional comments (22)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis change adds Software Bill of Materials (SBOM) generation across the CI/CD pipeline for both CLI and container releases. SBOMs are generated using Syft and included as CycloneDX JSON artifacts, with metadata embedded in release notes through HTML comments and extracted during finalization. Changes
Sequence Diagram(s)sequenceDiagram
participant GHA as GitHub Actions
participant Syft as Syft Tool
participant GR as GoReleaser
participant Artifacts as Artifact Storage
participant Release as GitHub Release
participant Finalize as Finalize Job
GHA->>Syft: Install Syft binary
rect rgba(100, 150, 200, 0.5)
Note over GHA,GR: CLI Release Path
GHA->>GR: Execute GoReleaser with sboms config
GR->>Syft: Invoke for each archive
Syft-->>GR: Generate .cdx.json per archive
GR->>Artifacts: Upload .tar.gz/.zip + .cdx.json
GHA->>Release: Create draft with CLI_SBOM_DATA metadata
end
rect rgba(150, 100, 200, 0.5)
Note over GHA,Artifacts: Container Release Path
GHA->>Syft: Run anchore/sbom-action per image
Syft-->>Artifacts: Output sbom-*.cdx.json per image
GHA->>Artifacts: Upload SBOM artifacts (30-day retention)
GHA->>Release: Create draft with CONTAINER_SBOM_DATA metadata
end
rect rgba(200, 150, 100, 0.5)
Note over Finalize,Release: Finalize Phase
Finalize->>Release: Extract CLI_SBOM_DATA and CONTAINER_SBOM_DATA
Finalize->>Artifacts: Download all sbom-*.cdx.json files
Finalize->>Release: Upload downloaded SBOMs to release
Finalize->>Release: Build combined Verification section with SBOM subsection
Finalize->>Release: Publish finalized release with all SBOMs
end
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly Related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces SBOM generation for Docker images and CLI binaries using Syft, a significant step in enhancing supply chain security. The changes include updating the GoReleaser configuration to automate SBOM creation for CLI archives and to bundle the LICENSE file within them. Correspondingly, the documentation across CLAUDE.md, docs/architecture/tech-stack.md, and docs/security.md has been updated to reflect these new capabilities. The implementation in .goreleaser.yml appears correct. My review focuses on minor stylistic inconsistencies in the documentation to ensure consistency and readability.
| - **Sandbox**: `synthorg-sandbox` — Python 3.14 + Node.js + git, non-root (UID 10001), agent code execution sandbox | ||
| - **Config**: all Docker files in `docker/` — Dockerfiles, compose, `.env.example` | ||
| - **CI**: `.github/workflows/docker.yml` — build → scan → push to GHCR + cosign sign + SLSA L3 provenance via `attest-build-provenance` (images only pushed after Trivy/Grype scans pass) | ||
| - **CI**: `.github/workflows/docker.yml` -- build -> scan -> push to GHCR + cosign sign + SLSA L3 provenance via `attest-build-provenance` + Syft SBOM generation (CycloneDX JSON, one per image) attached to releases (images only pushed after Trivy/Grype scans pass) |
There was a problem hiding this comment.
For stylistic consistency with other list items in this file that use an em-dash (—), please replace the two hyphens (--) with an em-dash.
| - **CI**: `.github/workflows/docker.yml` -- build -> scan -> push to GHCR + cosign sign + SLSA L3 provenance via `attest-build-provenance` + Syft SBOM generation (CycloneDX JSON, one per image) attached to releases (images only pushed after Trivy/Grype scans pass) | |
| - **CI**: `.github/workflows/docker.yml` — build -> scan -> push to GHCR + cosign sign + SLSA L3 provenance via `attest-build-provenance` + Syft SBOM generation (CycloneDX JSON, one per image) attached to releases (images only pushed after Trivy/Grype scans pass) |
| - **Docker**: `.github/workflows/docker.yml` — builds backend + web + sandbox images, pushes to GHCR, signs with cosign. SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed, pushed to registry). Scans: Trivy (CRITICAL = hard fail, HIGH = warn-only) + Grype (critical cutoff) + CIS Docker Benchmark v1.6.0 compliance (informational). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`). | ||
| - **Matrix**: Python 3.14 | ||
| - **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 5 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). Cosign keyless signing of `checksums.txt` (`.sig` + `.pem` attached to release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed) for individual binaries and checksums file. Sigstore provenance bundle (`.sigstore.json`) attached to release for OpenSSF Scorecard signed-releases scoring. Post-release step appends install instructions + checksum table + cosign verification + provenance verification instructions to the draft release notes (while still in draft — before finalize-release publishes). | ||
| - **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 5 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). Syft SBOM generation per binary archive (CycloneDX JSON, via GoReleaser `sboms:` stanza). Cosign keyless signing of `checksums.txt` (`.sig` + `.pem` attached to release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed) for individual binaries and checksums file. Sigstore provenance bundle (`.sigstore.json`) attached to release for OpenSSF Scorecard signed-releases scoring. Post-release step appends install instructions + checksum table + cosign verification + provenance verification + SBOM file listings to the draft release notes (while still in draft -- before finalize-release publishes). |
There was a problem hiding this comment.
For stylistic consistency, please use an em-dash (—) here instead of two hyphens (--).
| - **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 5 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). Syft SBOM generation per binary archive (CycloneDX JSON, via GoReleaser `sboms:` stanza). Cosign keyless signing of `checksums.txt` (`.sig` + `.pem` attached to release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed) for individual binaries and checksums file. Sigstore provenance bundle (`.sigstore.json`) attached to release for OpenSSF Scorecard signed-releases scoring. Post-release step appends install instructions + checksum table + cosign verification + provenance verification + SBOM file listings to the draft release notes (while still in draft -- before finalize-release publishes). | |
| - **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 5 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). Syft SBOM generation per binary archive (CycloneDX JSON, via GoReleaser `sboms:` stanza). Cosign keyless signing of `checksums.txt` (`.sig` + `.pem` attached to release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed) for individual binaries and checksums file. Sigstore provenance bundle (`.sigstore.json`) attached to release for OpenSSF Scorecard signed-releases scoring. Post-release step appends install instructions + checksum table + cosign verification + provenance verification + SBOM file listings to the draft release notes (while still in draft — before finalize-release publishes). |
| - **Dependabot** auto-updates digests daily for all three Dockerfiles | ||
| - **cosign keyless signing** on every pushed image (Sigstore OIDC-bound) | ||
| - **SBOM and build-level provenance** (SLSA L1) auto-generated by Docker Buildx | ||
| - **Buildx SPDX SBOMs** (SLSA L1) auto-generated and pushed to GHCR as registry attestations (inspect via `docker buildx imagetools inspect`). Standalone CycloneDX JSON SBOMs are generated separately by Syft -- see [Software Bill of Materials](#software-bill-of-materials-sbom) below. |
There was a problem hiding this comment.
For stylistic consistency with other prose in this document, please use an em-dash (—) for separation instead of two hyphens (--).
| - **Buildx SPDX SBOMs** (SLSA L1) auto-generated and pushed to GHCR as registry attestations (inspect via `docker buildx imagetools inspect`). Standalone CycloneDX JSON SBOMs are generated separately by Syft -- see [Software Bill of Materials](#software-bill-of-materials-sbom) below. | |
| - **Buildx SPDX SBOMs** (SLSA L1) auto-generated and pushed to GHCR as registry attestations (inspect via `docker buildx imagetools inspect`). Standalone CycloneDX JSON SBOMs are generated separately by Syft — see [Software Bill of Materials](#software-bill-of-materials-sbom) below. |
| - **Git commits**: GPG/SSH signed (enforced by branch protection ruleset) | ||
| - **GitHub Actions**: All actions pinned by full SHA commit hash | ||
| - **GitHub Releases**: Immutable releases enabled — once published, assets and body cannot be modified (prevents supply chain tampering). Releases are created as drafts by Release Please, finalized after all assets are attached. | ||
| - **GitHub Releases**: Immutable releases enabled -- once published, assets and body cannot be modified (prevents supply chain tampering). Releases are created as drafts by Release Please, finalized after all assets are attached. |
There was a problem hiding this comment.
This change introduces a stylistic inconsistency. The original line used an em-dash (—), which is consistent with other prose in the document. Please revert the change from two hyphens (--) back to an em-dash.
| - **GitHub Releases**: Immutable releases enabled -- once published, assets and body cannot be modified (prevents supply chain tampering). Releases are created as drafts by Release Please, finalized after all assets are attached. | |
| - **GitHub Releases**: Immutable releases enabled — once published, assets and body cannot be modified (prevents supply chain tampering). Releases are created as drafts by Release Please, finalized after all assets are attached. |
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) ### Maintenance * **main:** release 0.3.7 ([#583](#583)) ([bf58779](bf58779)) * reset failed v0.3.7 release ([#591](#591)) ([b69000d](b69000d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added engine Hybrid Plan + ReAct execution loop * Added first-run setup wizard * **Bug Fixes** * Addressed ZAP DAST scan issues * Fixed CLI Windows/image/update issues * **Maintenance** * Added SBOM generation for Docker/CLI releases * General maintenance updates <!-- end of auto-generated comment: release notes by coderabbit.ai -->
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **ci:** reset failed v0.3.7 release and fix syft SBOM scan ([#593](#593)) ([d1508c2](d1508c2)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **ci:** remove CLI SBOM generation, reset failed v0.3.7 ([#595](#595)) ([d0f4992](d0f4992)) * **ci:** reset failed v0.3.7 release and fix syft SBOM scan ([#593](#593)) ([d1508c2](d1508c2)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
anchore/sbom-actionscans each pushed image (backend, web, sandbox), SBOMs uploaded as release assets viaupdate-releasejobsboms:stanza generates per-archive SBOMs (6 total), uploaded alongside checksums and binariesfiles:stanza)docs/security.md,CLAUDE.md,docs/architecture/tech-stack.mdanchore/sbom-action@*added to GitHub Actions allowlistSatisfies OpenSSF Best Practices badge criterion QA-02.02 (SBOM with releases).
Test plan
v*tag release, verify:sbom-backend.cdx.json,sbom-web.cdx.json,sbom-sandbox.cdx.json) attached to releasesynthorg_{os}_{arch}.{tar.gz,zip}.cdx.json) attached to release## Verificationsection includes SBOM download linksReview coverage
Pre-reviewed by 2 agents (docs-consistency, infra-reviewer). 5 findings addressed (all documentation drift fixes). Infra review passed clean -- no security or correctness issues found.
🤖 Generated with Claude Code