chore(security): harden release pipeline + container distribution - #42
Merged
Conversation
Acts on the code + security review of the distribution work: - Pin every GitHub Actions step (release.yml + ci.yml) to a commit SHA, so a moved tag can't inject code into a run holding id-token / attestations / packages write. - Cover the SBOM with the signed SHA256SUMS (it shipped unsigned); set sbom-action upload-release-assets: false (the release already uploads it). - Sign the image recursively (cosign sign -r) so each per-platform manifest is signed, not just the index. - Anchor the cosign verify identity to .../release.yml@refs/tags/v. - README docker run hardened: required --group-add, --read-only + --tmpfs, --cap-drop ALL, --security-opt no-new-privileges, digest pinning, a socket=host-root warning + bind-mount ownership note; document image verification (cosign verify / gh attestation verify oci://). - Dockerfile: drop the redundant build-stage chown (COPY --chown sets it). Validated locally: the hardened `docker run` (read-only + tmpfs + cap-drop + named volume + socket) starts cleanly and writes /data as uid 65532; both workflows YAML-lint and carry no unpinned action tags.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the project’s supply-chain posture and container distribution/docs without changing application (Go) code, focusing on securing GitHub Actions releases and improving container runtime guidance for users.
Changes:
- Pins GitHub Actions used in CI/release workflows to commit SHAs; enhances release signing coverage (SBOM included in signed checksums) and recursively signs multi-arch images.
- Hardens Docker runtime documentation (read-only filesystem, dropped capabilities, no-new-privileges, socket warning) and adds container image verification commands.
- Simplifies Dockerfile build stage by removing redundant ownership changes while keeping runtime ownership via
COPY --chown.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Strengthens Docker run guidance and adds image verification instructions. |
| Dockerfile | Removes redundant build-stage chown while preserving runtime ownership setup. |
| CHANGELOG.md | Records security hardening changes in the Unreleased section. |
| .github/workflows/release.yml | Pins actions by SHA, includes SBOM in signed checksums, and recursively signs images. |
| .github/workflows/ci.yml | Pins CI actions by SHA for supply-chain hardening. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
118
to
126
| docker run -d --name dockercmd \ | ||
| -p 127.0.0.1:8470:8470 \ | ||
| --group-add "$(getent group docker | cut -d: -f3)" \ | ||
| --read-only --tmpfs /tmp \ | ||
| --security-opt no-new-privileges \ | ||
| --cap-drop ALL \ | ||
| -v /var/run/docker.sock:/var/run/docker.sock \ | ||
| -v dockercmd-data:/data \ | ||
| ghcr.io/koduj-dev/docker-commander:latest |
Comment on lines
+135
to
+137
| expose it unauthenticated. The `--group-add` line hands the non-root user the | ||
| host's `docker` group so it can read the socket; on **rootless / Docker | ||
| Desktop** (user-owned socket, no `docker` group) drop that line. |
| The container image is signed and carries SLSA provenance + an SBOM as well: | ||
|
|
||
| ```bash | ||
| IMAGE=ghcr.io/koduj-dev/docker-commander:1.4.0 |
…age verify - README docker run derives the socket's owning GID via `stat` (GNU `-c %g` with a BSD `-f %g` fallback) instead of `getent group docker`, so it works without a `docker` group; updated the accompanying note to match. - The image verification example now uses an immutable `@sha256:<digest>` reference, consistent with the digest-pinning guidance just above it.
This was referenced Jun 15, 2026
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.
Summary
Acts on the code-review + security-review of the distribution work (#41), ahead of broader distribution (container registry, and later MS Store / Debian). No application/Go code changes — supply-chain and container-posture hardening only.
Supply chain (release.yml + ci.yml)
id-token/attestations/packageswrite.dockercmd.sbom.spdx.jsonis appended toSHA256SUMSbefore the cosignsign-blob, so it's no longer published without integrity.sbom-actionupload-release-assets: false(the release already ships it).cosign sign -r) so each per-platform manifest is signed, not just the index.…/release.yml@refs/tags/v(was@refs/tags/).Container posture (Dockerfile + README)
docker run: required--group-add(in the command),--read-only+--tmpfs /tmp,--cap-drop ALL,--security-opt no-new-privileges, digest pinning, an explicit socket = host-root-equivalent warning, and a bind-mount ownership note (uid 65532).cosign verify/gh attestation verify oci://…).chown(theCOPY --chownsets ownership).Type of change
Checklist
go test -short ./...andgo vet ./...pass — N/A (no Go changed)gofmtgate is clean (no.gofiles touched)web/dist— N/A (noweb/srcchange)docs/and added aCHANGELOG.mdentryNotes for reviewers
docker run(read-only + tmpfs + cap-drop ALL + no-new-privileges +--group-add docker+ socket + named volume) starts cleanly, connects to Docker, and writes/dataas uid 65532 (docker-commander.db{,-shm,-wal}owned 65532:65532). Both workflows passyaml.safe_loadand carry no unpinned@vNaction tags.gh api repos/<a>/commits/<vN>); Dependabot can keep them current.v*tag..exe(MS Store) anddpkg-sig/GPG for a Debian package — separate follow-ups once certs/keys exist.