fix: replace slsa-github-generator with attest-build-provenance, fix DAST#424
fix: replace slsa-github-generator with attest-build-provenance, fix DAST#424
Conversation
…DAST slsa-github-generator reusable workflows cannot be SHA-pinned (GitHub Actions limitation for job-level uses:), which conflicts with the repo's sha_pinning_required policy. Replace with actions/attest-build-provenance (GitHub-owned, step-level, SHA-pinnable) for SLSA L3 provenance on both CLI binaries and container images. This simplifies the architecture: provenance attestation is now a step within existing build jobs instead of separate reusable workflow jobs. Verification uses `gh attestation verify` instead of `slsa-verifier`. Also fix DAST startup_failure caused by the package rename PR switching the Dockerfile CMD from exec form to shell form (/bin/sh doesn't exist on distroless). Restore exec form and bridge SYNTHORG_HOST/PORT to uvicorn's native UVICORN_HOST/PORT env vars via compose.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughSummary by CodeRabbit
WalkthroughConsolidates provenance attestation by replacing multi-job SLSA generators with Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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 |
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 and operational efficiency. It modernizes the provenance generation process by adopting a new GitHub Action, improves Docker image compatibility with distroless environments, and streamlines continuous integration workflows. These changes collectively lead to a more robust and maintainable build and release pipeline. Highlights
Changelog
Ignored Files
Activity
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. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request is a solid improvement, migrating to the GitHub-native actions/attest-build-provenance for SLSA L3 provenance and fixing the DAST workflow by ensuring distroless compatibility for the backend Docker image. The simplification of CI jobs and thorough documentation updates are also valuable changes. My review includes one suggestion for the Dockerfile to improve configuration clarity for users who are not using Docker Compose.
| SYNTHORG_HOST="0.0.0.0" \ | ||
| SYNTHORG_PORT="8000" | ||
| SYNTHORG_PORT="8000" \ | ||
| UVICORN_HOST="0.0.0.0" \ | ||
| UVICORN_PORT="8000" |
There was a problem hiding this comment.
With the CMD now using the exec form and relying on uvicorn to pick up its configuration from UVICORN_* environment variables, the SYNTHORG_HOST and SYNTHORG_PORT variables are no longer used to configure the web server within this Dockerfile's context.
Keeping them here can be misleading for users who might run the image with docker run and expect -e SYNTHORG_HOST=... to work, as it would have no effect. Since the bridging from SYNTHORG_* to UVICORN_* is handled in docker-compose.yml, I suggest removing SYNTHORG_HOST and SYNTHORG_PORT from this ENV block to make it clear that UVICORN_* are the variables for configuring the server at the image level.
UVICORN_HOST="0.0.0.0" \
UVICORN_PORT="8000"
There was a problem hiding this comment.
Pull request overview
This PR migrates supply-chain provenance generation from slsa-framework/slsa-github-generator to GitHub’s native actions/attest-build-provenance, updates the backend container startup to work on distroless images, and refreshes docs/release-note guidance accordingly.
Changes:
- Replace SLSA generator reusable workflows with inline
actions/attest-build-provenancesteps for CLI releases and GHCR images. - Update backend Dockerfile
CMDto exec-form for distroless compatibility; addUVICORN_HOST/UVICORN_PORTwiring. - Update docs/site/CLAUDE guidance to reference
gh attestation verifyinstead ofslsa-verifier.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| site/src/pages/get/index.astro | Updates installation page provenance verification text to gh attestation verify. |
| docs/security.md | Updates security documentation to reference GitHub attestations. |
| docs/architecture/tech-stack.md | Updates tech stack doc to reference new provenance tooling. |
| docker/compose.yml | Adds UVICORN_HOST/UVICORN_PORT env bridging for exec-form CMD. |
| docker/backend/Dockerfile | Switches CMD to exec-form uvicorn; adds UVICORN env vars for distroless. |
| CLAUDE.md | Updates repo/CI documentation to reference attest-build-provenance. |
| .github/workflows/docker.yml | Adds attestation permissions and inline provenance attestation steps; removes separate provenance jobs. |
| .github/workflows/cli.yml | Collapses CLI release flow and adds attest-build-provenance using subject-checksums. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: Attest build provenance (SLSA Level 3) | ||
| uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 | ||
| with: | ||
| subject-checksums: cli/dist/checksums.txt | ||
|
|
site/src/pages/get/index.astro
Outdated
| Each release includes <a href="https://slsa.dev" class="text-teal-400 hover:underline">SLSA L3 provenance</a> — verify with | ||
| <a href="https://github.com/slsa-framework/slsa-verifier" class="text-teal-400 hover:underline"><code class="text-gray-300">slsa-verifier</code></a>. | ||
| <code class="text-gray-300">gh attestation verify</code>. |
| # Bridge SYNTHORG_* to uvicorn's native env vars (exec form CMD, no shell) | ||
| UVICORN_HOST: "${SYNTHORG_HOST:-0.0.0.0}" | ||
| UVICORN_PORT: "${SYNTHORG_PORT:-8000}" |
| ENV PATH="/app/.venv/bin:$PATH" \ | ||
| PYTHONUNBUFFERED=1 \ | ||
| PYTHONDONTWRITEBYTECODE=1 \ | ||
| SYNTHORG_HOST="0.0.0.0" \ | ||
| SYNTHORG_PORT="8000" | ||
| SYNTHORG_PORT="8000" \ | ||
| UVICORN_HOST="0.0.0.0" \ | ||
| UVICORN_PORT="8000" |
| - name: Attest build provenance (SLSA Level 3) | ||
| if: github.event_name != 'pull_request' | ||
| uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 | ||
| with: | ||
| subject-name: ghcr.io/aureliolo/synthorg-backend | ||
| subject-digest: ${{ steps.push.outputs.digest }} |
Greptile SummaryThis PR replaces the Key changes:
Confidence Score: 4/5
Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: .github/workflows/docker.yml
Line: 389
Comment:
**Use `--notes-file` for consistency and robustness**
The `cli-release` job (in `cli.yml`) writes the combined notes to a tmpfile and passes `--notes-file "$tmpfile"` to `gh release edit`. This is the safer pattern: it avoids shell argument-length limits and is robust to any special characters in the content.
The `update-release` job here passes content directly via `--notes "${CLEANED}${IMAGES}"`. The `$IMAGES` block now contains backtick-fenced code blocks for the new provenance section, which are safe in double-quotes but could become a footgun if the content grows further.
Consider mirroring the CLI pattern:
```suggestion
tmpfile="$(mktemp)"
printf '%s' "${CLEANED}${IMAGES}" > "$tmpfile"
gh release edit "$TAG" --notes-file "$tmpfile"
rm -f "$tmpfile"
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: bedafd9 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/cli.yml:
- Around line 347-350: The current logic builds FULL_BODY by blindly
concatenating EXISTING_BODY and INSTALL_NOTES which causes duplicate
Installation/Checksums/Provenance blocks on reruns; change the flow that sets
FULL_BODY so it first checks EXISTING_BODY (from gh release view) for the
presence of INSTALL_NOTES (or a stable marker header from INSTALL_NOTES) and
only appends INSTALL_NOTES when not already present, otherwise leave
EXISTING_BODY unchanged (or replace the existing block by removing the old
marker-delimited section and appending the updated INSTALL_NOTES); reference the
variables/commands EXISTING_BODY, FULL_BODY, INSTALL_NOTES, TAG and the gh
release view invocation to locate and update the logic.
In `@docker/compose.yml`:
- Around line 16-18: SYNTHORG_HOST and SYNTHORG_PORT are hard-coded while
UVICORN_HOST/UVICORN_PORT use host interpolation, which can lead to divergence;
make both pairs read from the same host environment variables instead of
referencing sibling keys—change SYNTHORG_HOST and SYNTHORG_PORT to use
interpolation with defaults (e.g., SYNTHORG_HOST: "${SYNTHORG_HOST:-0.0.0.0}"
and SYNTHORG_PORT: "${SYNTHORG_PORT:-8000}") and ensure
UVICORN_HOST/UVICORN_PORT use the same host env names (e.g., UVICORN_HOST:
"${SYNTHORG_HOST:-0.0.0.0}", UVICORN_PORT: "${SYNTHORG_PORT:-8000}") so both
sets stay synchronized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7434bf7c-d8a0-4a9f-a511-a8134e2b1606
📒 Files selected for processing (8)
.github/workflows/cli.yml.github/workflows/docker.ymlCLAUDE.mddocker/backend/Dockerfiledocker/compose.ymldocs/architecture/tech-stack.mddocs/security.mdsite/src/pages/get/index.astro
📜 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). (5)
- GitHub Check: Agent
- GitHub Check: Build Backend
- GitHub Check: Build Web
- GitHub Check: Greptile Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
docker/**/Dockerfile*
📄 CodeRabbit inference engine (CLAUDE.md)
Lint all Dockerfiles (backend, web, sandbox) with hadolint
Files:
docker/backend/Dockerfile
docker/backend/Dockerfile
📄 CodeRabbit inference engine (CLAUDE.md)
docker/backend/Dockerfile: Use 3-stage Docker build pattern (builder → setup → distroless runtime) for backend
Use Chainguard Python base image and non-root UID 65532 in backend Dockerfile
Files:
docker/backend/Dockerfile
docker/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Configure all Docker files (Dockerfiles, compose, .env) in docker/ directory; use .dockerignore at repo root
Files:
docker/backend/Dockerfiledocker/compose.yml
docker/compose.yml
📄 CodeRabbit inference engine (CLAUDE.md)
Use docker-compose for multi-container orchestration with compose.yml
Files:
docker/compose.yml
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/backend/Dockerfile : Use 3-stage Docker build pattern (builder → setup → distroless runtime) for backend
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/backend/Dockerfile : Use Chainguard Python base image and non-root UID 65532 in backend Dockerfile
Applied to files:
docker/backend/DockerfileCLAUDE.md
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/backend/Dockerfile : Use 3-stage Docker build pattern (builder → setup → distroless runtime) for backend
Applied to files:
docker/backend/DockerfileCLAUDE.md
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/compose.yml : Use docker-compose for multi-container orchestration with compose.yml
Applied to files:
docker/compose.yml
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Sign all commits on main with GPG/SSH; enforce via branch protection
Applied to files:
docs/security.md
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to cli/**/*.go : Run golangci-lint and go vet for CLI Go code linting
Applied to files:
.github/workflows/cli.yml
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/web/Dockerfile : Use nginxinc/nginx-unprivileged base image for web Dockerfile
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T23:43:21.164Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T23:43:21.164Z
Learning: Applies to docker/**/Dockerfile* : Lint all Dockerfiles (backend, web, sandbox) with hadolint
Applied to files:
CLAUDE.md
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~106-~106: The official name of this software platform is spelled with a capital “H”.
Context: ...iles, compose, .env.example - CI: .github/workflows/docker.yml — build → scan → ...
(GITHUB)
[uncategorized] ~260-~260: The official name of this software platform is spelled with a capital “H”.
Context: ...le builds on rapid pushes - Docker: .github/workflows/docker.yml — builds backend ...
(GITHUB)
[uncategorized] ~260-~260: The official name of this software platform is spelled with a capital “H”.
Context: ...Grype (critical cutoff). CVE triage via .github/.trivyignore.yaml and `.github/.grype....
(GITHUB)
[uncategorized] ~260-~260: The official name of this software platform is spelled with a capital “H”.
Context: ...age via .github/.trivyignore.yaml and .github/.grype.yaml. Images only pushed after ...
(GITHUB)
🔇 Additional comments (7)
CLAUDE.md (1)
106-107: Documentation updates are consistent with the CI pipeline changes.No concerns in these updated CI/provenance references.
Also applies to: 260-263
site/src/pages/get/index.astro (1)
199-200: Copy update looks good.The provenance verification wording is clear and aligned with the rest of this PR.
docs/architecture/tech-stack.md (1)
82-82: Tech stack entry update is coherent.No concerns with this container packaging/provenance wording change.
docs/security.md (1)
122-123: Security documentation updates are consistent.No issues in these provenance/signing verification updates.
Also applies to: 152-153
docker/backend/Dockerfile (1)
115-118: Exec-form startup change is correct for distroless runtime.This resolves shell dependency in container startup without introducing regressions in the command path.
As per coding guidelines,
docker/backend/Dockerfileshould use the 3-stage backend pattern and non-root UID65532, and this change remains compliant with that requirement..github/workflows/docker.yml (1)
64-65: Workflow restructuring in these hunks looks sound.The release gating and provenance-note update flow remain consistent after the job simplification.
Also applies to: 174-181, 190-191, 299-305, 310-312, 373-379, 389-389
.github/workflows/cli.yml (1)
239-290: Release-job consolidation is clean and coherent.No concerns in this release/provenance flow simplification hunk.
| # Bridge SYNTHORG_* to uvicorn's native env vars (exec form CMD, no shell) | ||
| UVICORN_HOST: "${SYNTHORG_HOST:-0.0.0.0}" | ||
| UVICORN_PORT: "${SYNTHORG_PORT:-8000}" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Verify whether UVICORN_* can diverge from hard-coded SYNTHORG_*.
export SYNTHORG_HOST=127.0.0.1
export SYNTHORG_PORT=9999
docker compose -f docker/compose.yml config | sed -n '/backend:/,/web:/p'Repository: Aureliolo/synthorg
Length of output: 108
🏁 Script executed:
cat -n docker/compose.ymlRepository: Aureliolo/synthorg
Length of output: 1624
Synchronize SYNTHORG_ and UVICORN_ environment variables.**
Currently, SYNTHORG_HOST and SYNTHORG_PORT are hard-coded (lines 12–13), while UVICORN_HOST and UVICORN_PORT use interpolation to reference them (lines 17–18). Since Docker Compose variable interpolation reads from the host environment, not sibling environment keys, they can diverge: if the host exports SYNTHORG_PORT=9999, then SYNTHORG_PORT remains "8000" but UVICORN_PORT resolves to "9999".
🔧 Proposed fix
environment:
- SYNTHORG_HOST: "0.0.0.0"
- SYNTHORG_PORT: "8000"
+ SYNTHORG_HOST: "${SYNTHORG_HOST:-0.0.0.0}"
+ SYNTHORG_PORT: "${SYNTHORG_PORT:-8000}"
SYNTHORG_DB_PATH: "/data/synthorg.db"
SYNTHORG_MEMORY_DIR: "/data/memory"
# Bridge SYNTHORG_* to uvicorn's native env vars (exec form CMD, no shell)
UVICORN_HOST: "${SYNTHORG_HOST:-0.0.0.0}"
UVICORN_PORT: "${SYNTHORG_PORT:-8000}"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docker/compose.yml` around lines 16 - 18, SYNTHORG_HOST and SYNTHORG_PORT are
hard-coded while UVICORN_HOST/UVICORN_PORT use host interpolation, which can
lead to divergence; make both pairs read from the same host environment
variables instead of referencing sibling keys—change SYNTHORG_HOST and
SYNTHORG_PORT to use interpolation with defaults (e.g., SYNTHORG_HOST:
"${SYNTHORG_HOST:-0.0.0.0}" and SYNTHORG_PORT: "${SYNTHORG_PORT:-8000}") and
ensure UVICORN_HOST/UVICORN_PORT use the same host env names (e.g.,
UVICORN_HOST: "${SYNTHORG_HOST:-0.0.0.0}", UVICORN_PORT:
"${SYNTHORG_PORT:-8000}") so both sets stay synchronized.
…eRabbit - compose.yml: SYNTHORG_HOST/PORT now use interpolation (synced with UVICORN_*) - Dockerfile: clarify SYNTHORG_* vs UVICORN_* role in ENV comment - Dockerfile: healthcheck reads UVICORN_PORT dynamically (not hardcoded 8000) - cli.yml: validate checksums.txt exists before attestation action - cli.yml: idempotent release note append (strips existing Installation block) - site: add concrete verification example and docs link
🤖 I have created a release *beep* *boop* --- ## [0.2.0](v0.1.4...v0.2.0) (2026-03-15) ##First probably usable release? Most likely not no and everything will break ### Features * add /get/ installation page for CLI installer ([#413](#413)) ([6a47e4a](6a47e4a)) * add cross-platform Go CLI for container lifecycle management ([#401](#401)) ([0353d9e](0353d9e)), closes [#392](#392) * add explicit ScanOutcome signal to OutputScanResult ([#394](#394)) ([be33414](be33414)), closes [#284](#284) * add meeting scheduler, event-triggered meetings, and Go CLI lint fixes ([#407](#407)) ([5550fa1](5550fa1)) * wire MultiAgentCoordinator into runtime ([#396](#396)) ([7a9e516](7a9e516)) ### Bug Fixes * CLA signatures branch + declutter repo root ([#409](#409)) ([cabe953](cabe953)) * correct Release Please branch name in release workflow ([#410](#410)) ([515d816](515d816)) * replace slsa-github-generator with attest-build-provenance, fix DAST ([#424](#424)) ([eeaadff](eeaadff)) * resolve CodeQL path-injection alerts in Go CLI ([#412](#412)) ([f41bf16](f41bf16)) ### Refactoring * rename package from ai_company to synthorg ([#422](#422)) ([df27c6e](df27c6e)), closes [#398](#398) ### Tests * add fuzz and property-based testing across all layers ([#421](#421)) ([115a742](115a742)) ### CI/CD * add SLSA L3 provenance for CLI binaries and container images ([#423](#423)) ([d3dc75d](d3dc75d)) * bump the major group with 4 updates ([#405](#405)) ([20c7a04](20c7a04)) ### Maintenance * bump github.com/spf13/cobra from 1.9.1 to 1.10.2 in /cli in the minor-and-patch group ([#402](#402)) ([e31edbb](e31edbb)) * narrow BSL Additional Use Grant and add CLA ([#408](#408)) ([5ab15bd](5ab15bd)), closes [#406](#406) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
slsa-framework/slsa-github-generatorwithactions/attest-build-provenancefor SLSA L3 provenance on both CLI binaries and container images — simpler (inline step vs reusable workflow), GitHub-native attestation store, verified withgh attestation verify/bin/sh -c "exec uvicorn ...") to exec form (["/app/.venv/bin/uvicorn", ...]), since Chainguard distroless has no/bin/sh. AddUVICORN_HOST/UVICORN_PORTenv vars (read natively by uvicorn) with compose bridging fromSYNTHORG_*cli-release-build→cli-release-provenance→cli-release-notes) to 1 job (cli-release). Docker workflow removes separateprovenance-backend/provenance-webjobs in favor of inline attestation stepsTest plan
docker compose -f docker/compose.yml up -d backend+ health check)v*tag: GoReleaser +attest-build-provenancewithsubject-checksumsv*tag: inline attestation steps +update-releasenotesgh attestation verifyworks against published attestationsReview coverage
Pre-reviewed by 2 agents (docs-consistency, infra-reviewer). 0 findings — all changes consistent and correct.
🤖 Generated with Claude Code