Repository navigation
Harden CI and release supply chain - #24
Open
ndbroadbent wants to merge 4 commits into
Open
ndbroadbent wants to merge 4 commits into
ndbroadbent wants to merge 4 commits into
Conversation
…okens - Pin every third-party action to a full commit SHA (newest release within the current major), with the version in a comment. - Install Task, the Convox CLI and TruffleHog from pinned releases with SHA-256 verification instead of piping install scripts (including golangci-lint's install.sh from master) into sh. The golangci-lint action already installs the pinned version and verifies the config schema, so the separate install and config-verify steps are gone. govulncheck is pinned to v1.8.0. - ci.yml and e2e.yml run with contents: read. The docs workflow gives pages/id-token write only to the deploy job, pins Bun and installs with --frozen-lockfile. - New daily Security Scan workflow: govulncheck, bun audit (high+) for web, and a Trivy scan of the published image, so new advisories surface without a push (CI was red for a month unnoticed). - Dependabot for gomod, bun (web, docs, mock-oauth), GitHub Actions and Dockerfiles, weekly with grouped minor/patch updates.
…curl - Pin oven/bun, golang and alpine base images by digest (runtime moves from alpine:latest to alpine:3.24.2) in all Dockerfiles, including mock-oauth's floating oven/bun:1-alpine. - The production image runs as UID/GID 10001. Binaries, web assets and start-gateway.sh stay root-owned and read-only; the gateway only writes temp files under /tmp. - curl is no longer installed in the gateway images. The compose healthcheck uses busybox wget, which is already in alpine. - Fix the commit hash in the gateway binary: the build stage read an unset COMMIT_HASH arg, so every image reported CommitHash=unknown. It now uses the required COMMIT_SHA build arg that CI already passes.
- The Release workflow runs only for v* tags. workflow_dispatch is gone:
it built whatever branch it was dispatched from, then pushed :latest
and overwrote the newest release's assets. v* tags are admin-only via
a repository ruleset.
- Per-job least-privilege permissions; the tag regex is anchored; tag
values reach shell steps through env: instead of ${{ }} interpolation.
- Images are pushed as :vX.Y.Z, :<short-sha> and :latest, with SLSA
build provenance attestations for the image and the CLI binaries
(verify with `gh attestation verify`). setup-go caching is off in
release jobs so a poisoned main-branch cache can't reach a release.
- convox.yml deploys an immutable tag instead of :latest. It's pinned
to :e327add (v0.1.1, same digest as the current :latest), and
scripts/bump-version.sh now sets it to :vX.Y.Z on each bump.
- The CLI reports its real version: ldflags set main.version /
main.buildTime, not the non-existent main.Version / main.BuildTime.
- Go tooling installs are pinned rather than @latest.
- Docs (CLAUDE.md, README, deployment docs) describe the new process.
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| JavaScript | Oct 9, 2026 5:25a.m. | Review ↗ | |
| Go | Oct 9, 2026 5:25a.m. | Review ↗ |
Important
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
TruffleHog runs its auto-updater by default. In CI it tried to replace the
checksum-verified binary installed root-owned in /usr/local/bin and failed
("cannot move binary back"), failing the secret scan. A pinned binary
must not update itself anyway, so pass --no-update.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes the code side of RG-05 and related supply-chain findings (SUPPLY-1/4/6/7/9/10) from the 2026-10-09 audit. The GitHub settings part is already applied: rulesets on
mainandv*tags, secret scanning and push protection, Dependabot, and a read-only defaultGITHUB_TOKEN.CI
curl | shinstallers:install.sh, which was fetched frommaster, is removed; the action installs the pinned version.ci.ymlande2e.ymlrun withcontents: read. The docs workflow grants Pages and OIDC permissions only to its deploy job.Security Scanworkflow: govulncheck,bun audit(high and above), and Trivy on the published image. CI was red for a month without anyone noticing.Release
v*tags, which only admins can create.workflow_dispatchis removed; it built any branch and overwrote:latestand the latest release's assets.env:instead of${{ }}interpolation.:vX.Y.Z,:<short-sha>and:latest.gh attestation verify).convox.ymldeploys:e327addinstead of:latest. That's v0.1.1, and I checked it has the same digest as the current:latest.bump-version.shnow sets:vX.Y.Zon each bump.main.Versioninstead ofmain.version.COMMIT_HASHarg.Docker
alpine:latesttoalpine:3.24.2./tmp.curl: removed from the runtime image. The compose healthcheck uses busyboxwget.Verified locally
task go:test, lint, shellcheck and actionlint all pass.Dockerfileimage. I confirmed the container runs asuid=10001(gateway)and has nocurl.ci.yml/e2e.yml.release.ymlwill only run on the nextv*tag.Things to check before merging
convox deploykeeps running v0.1.1, now pinned instead of:latest. Future deploys use:vX.Y.Zfrombump-version.sh.convox exec … curlto debug the gateway,curlis no longer in the image. busyboxwgetstill is.Summary by CodeRabbit
Release Improvements
latesttag.Documentation