Skip to content

ci: pin actions to commit SHAs, and the audit tools and base images to fixed versions - #233

Open
distronode-com wants to merge 2 commits into
Calnode:mainfrom
distronode-corporation:up/pin-dependencies
Open

distronode-com wants to merge 2 commits into
Calnode:mainfrom
distronode-corporation:up/pin-dependencies

Conversation

@distronode-com

@distronode-com distronode-com commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Pins only. No action moves to a new major, and no workflow logic changes.

Why

Pinned-Dependencies is at 0. The Scorecard details list 34 action references by tag, three go install ...@latest lines in audit.yml, and the Dockerfile's three base images by tag. A tag can be moved to different code after it has been reviewed; a commit SHA or an image digest cannot.

What changes

The PR has two commits, so the Dockerfile part can be dropped on its own.

Commit 1: workflows

Actions. Every uses: names a full commit SHA with its release as a trailing comment, for example actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1. The existing github-actions entry in .github/dependabot.yml understands this form and bumps the SHA and the comment together, so the pins keep moving on your monthly Dependabot schedule. Each SHA was resolved from its release tag through the GitHub API and cross-checked with git ls-remote.

Action Was Pinned to
actions/checkout v7 v7.0.1
actions/setup-node v7 v7.1.0
actions/setup-go v7 v7.0.0
actions/cache v6 v6.1.0
actions/upload-artifact v7 v7.0.2
actions/download-artifact v8 v8.0.2
github/codeql-action/upload-sarif v4 v4.39.1
docker/setup-qemu-action v4 v4.4.0
docker/setup-buildx-action v4 v4.4.1
docker/login-action v4 (docker-publish), v3 (ns8-module) v4.7.0, v3.7.0
docker/metadata-action v6 v6.2.0
docker/build-push-action v7 v7.4.0
pnpm/action-setup v6 v6.1.0
anchore/sbom-action v0 v0.24.3
contributor-assistant/github-action v2.6.1 v2.6.1
pullfrog/pullfrog v0 v0.1.107
NethServer test-on-digitalocean-infra.yml v1 (a branch) commit 3dc3a49 (see below)

For most of these the pin is exactly the commit the floating tag gives today. The exceptions:

  • codeql-action (v4 is now v4.39.3), login-action v4 (now v4.8.0), pnpm/action-setup (now v6.1.1) and pullfrog (now v0.1.118): their latest releases are only days old, so each is pinned to the last release before those. Dependabot will offer the newer ones.
  • anchore/sbom-action: its v0 tag has stayed on v0.24.0; the pin is v0.24.3, the newest release, so this one is a small patch bump.
  • contributor-assistant/github-action was already on an exact tag; it is the same code, now by SHA. zizmor points out that its repository is archived, so v2.6.1 is the last release it will get.
  • ossf/scorecard-action was already pinned to a commit. Its comment said v2.4.3, but that commit is the v2.4.4 tag, so the comment now says v2.4.4 (Dependabot reads it). v2.5.0 is out, and Dependabot should now offer it.
  • NethServer's @v1 is a branch, and its latest commit deleted test-on-digitalocean-infra.yml (NethServer moved to test-module-qemu.yml). So on main, test-module.yml currently names a reusable workflow that no longer exists on v1. It is pinned to 3dc3a49, the last commit that has the file, which is the version the workflow was written against; a comment says why. Dependabot may offer to move it to the branch head, which would break it again. The pin makes the reference resolve, but the workflow still will not run as it is: besides the do_token secret, the called job asks for issues: write, which this job does not grant, and GitHub refuses to start a called workflow that asks for more than its caller allows. It also fetches its test script from NethServer's v1 branch at run time. Porting to test-module-qemu.yml is probably the real fix. I could not run it: it needs the do_token secret.
  • pullfrog.yml starts with "DO NOT EDIT EXCEPT WHERE INDICATED", and pinning changes its two uses: lines. If you would rather keep pullfrog floating, drop the pullfrog/pullfrog line; the expected score is then 9 rather than 10.

Go tools in audit.yml. govulncheck v1.9.0, gosec v2.30.0 and gitleaks v8.30.1 instead of @latest. Each is the current latest release, so the gate behaves as it does today. Scorecard counts go install pkg@vX.Y.Z as pinned, since the Go checksum database makes a module version immutable. The cost is that Dependabot does not read go install lines, so these get bumped by hand; a comment above them says so. govulncheck downloads the vulnerability database on every run whatever its own version, so the pin does not freeze what it knows about. AUDIT.md's local-run block still says @latest, which seemed right for someone auditing by hand, so I left it.

The alpine:3 helper in docker-publish.yml. The arm64 smoke test's docker run alpine:3 ... is pinned to the multi-arch index digest. Scorecard does not count this one and Dependabot does not update it; it is there for consistency, with a comment.

Commit 2: the Dockerfile's base images

node:22-alpine, golang:1.27.3-alpine and alpine:3.24 now carry the digest of their multi-arch index, for example FROM alpine:3.24@sha256:be26...2c9a, so every platform in BUILD_PLATFORMS resolves from the same pin. The existing Dependabot docker entry for / bumps the digest when the tag moves.

The trade-off is real, which is why this is a separate commit. Today every image build picks up the newest base-image patch on its own; with digests, a refreshed base only arrives when you merge the Dependabot PR, which is monthly on your current schedule (weekly might suit the docker entry better). The digests are the images from before the Alpine 3.24.4 rebuild, which is only days old, so alpine:3.24 here is 3.24.3 (same Node and Go versions). 3.24.4's fixes are in openssh-server, which these images do not include, and in apk-tools, which only runs during the build; Dependabot will offer the new digests. Each digest was read from the docker-library/repo-info history for its tag and checked against Docker Hub: the manifest hashes to the pinned digest and lists linux/amd64 and linux/arm64.

Expected Scorecard effect

Pinned-Dependencies should go from 0 to 10 with both commits. scorecard --local (v5.5.0) on this branch reports 10, "all dependencies are pinned": 20 of 20 GitHub-owned actions, 15 of 15 third-party, 3 of 3 container images and 3 of 3 go install lines. Without commit 2 it reports 8; without the pullfrog line, 9. These are expectations; the published score comes from Scorecard's scheduled run.

How it was checked

  • Every workflow parses. actionlint 1.7.12 reports the same six shellcheck notes as on main, and nothing new.
  • zizmor 1.31.1 with online audits: unpinned-uses goes from 34 to 0, with no impostor-commit or version-comment findings. Its auditor persona flags only the NethServer pin as not being a tag, which is expected.
  • docker buildx build --check --platform linux/amd64,linux/arm64 . resolves all three digests with no warnings. I did not run a full image build; this PR's docker-publish.yml run builds both architectures.
  • Not run: the workflows themselves. What the jobs do is unchanged, only which exact revision of each action runs.

Part of a small set of Scorecard changes: #231 (token permissions), #232 (CodeQL) and #234 (release provenance); discussion #235 lists the repository settings only a maintainer can change. Each stands on its own and they merge in any order.

🤖 Generated with Claude Code

distronode-com and others added 2 commits November 6, 2026 00:31
Every `uses:` in .github/workflows now names a full commit SHA, with the
release it came from as a trailing comment (`# v7.0.1`). The existing
Dependabot github-actions entry understands that form and bumps the SHA
and the comment together, so the pins stay current.

Each SHA was resolved from its release tag through the GitHub API and
cross-checked with `git ls-remote`. Pins stay on the major the workflow
already used:

- actions/checkout v7.0.1, actions/setup-node v7.1.0, actions/setup-go
  v7.0.0, actions/cache v6.1.0, actions/upload-artifact v7.0.2,
  actions/download-artifact v8.0.2
- github/codeql-action/upload-sarif v4.39.1
- docker/setup-qemu-action v4.4.0, docker/setup-buildx-action v4.4.1,
  docker/login-action v4.7.0 (docker-publish) and v3.7.0 (ns8-module),
  docker/metadata-action v6.2.0, docker/build-push-action v7.4.0
- pnpm/action-setup v6.1.0, anchore/sbom-action v0.24.3,
  contributor-assistant/github-action v2.6.1, pullfrog/pullfrog v0.1.107

Also in the workflows:

- test-module.yml: NethServer's `@v1` is a branch, and its latest commit
  removed test-on-digitalocean-infra.yml. The reusable workflow is
  pinned to 3dc3a49, the last commit that has it.
- audit.yml: govulncheck v1.9.0, gosec v2.30.0 and gitleaks v8.30.1
  instead of @latest (the current latest release of each). Dependabot
  does not read `go install` lines, so these are bumped by hand.
- audit.yml: the scorecard-action pin was already a commit, but its
  comment said v2.4.3; that commit is the v2.4.4 tag.
- docker-publish.yml: the alpine:3 helper in the arm64 smoke test is
  pinned to its multi-arch index digest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
node:22-alpine, golang:1.27.3-alpine and alpine:3.24 now carry the
digest of their multi-arch index, so every platform in BUILD_PLATFORMS
resolves from the same pin. The tag stays beside each digest, and the
existing Dependabot docker entry for / bumps the digest when the tag
moves.

These are the images from before the current Alpine 3.24.4 rebuild
(alpine:3.24 here is 3.24.3). Dependabot will offer the newer digests.

This is a separate commit so it can be dropped on its own: with digests,
a rebuild no longer picks up a refreshed base image until the Dependabot
bump is merged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — all nine files, both commits; every pin was resolved against its upstream source:

  • Action pins in all eight workflows — each SHA matches the tag in its trailing comment (git ls-remote per repo), including the four annotated tags (codeql-action v4.39.1, pnpm/action-setup v6.1.0, anchore/sbom-action v0.24.3, ossf/scorecard-action v2.4.4), where the pin is correctly the commit deref rather than the tag object. No uses: under .github/ is left floating.
  • Scorecard comment correction — v2 really is gone upstream, v2.4.4 is the right tag for 2d11466…, and v2.5.0 exists for Dependabot to offer.
  • audit.yml tool pins — govulncheck v1.9.0, gosec v2.30.0 and gitleaks v8.30.1 all resolve on the module proxy with their documented module paths; golang.org/x/vuln v1.9.0 needs Go 1.26.0, which go.mod's toolchain go1.26.10 satisfies.
  • NethServer pin — 3dc3a49 still contains test-on-digitalocean-infra.yml while branch head 2a78503 does not, and that revision declares every input the caller passes (path, args, leader_nodes, run_ui_tests, debug_shell) plus do_token, so the pin introduces no input mismatch.
  • Dockerfile digests — node:22-alpine, golang:1.27.3-alpine, alpine:3.24 and the alpine:3 smoke-test helper all resolve as multi-arch OCI indexes containing both amd64 and arm64, so the $BUILDPLATFORM stages and the unpinned final stage still work on both legs. YAML parses for all changed workflows.

Two things worth knowing before merge, neither a defect: the base-image patch latency now follows the monthly docker Dependabot schedule (the PR body already flags weekly as the alternative), and the pinned test-module.yml revision resolves but still cannot start — the called job requests issues: write, which the caller's job does not grant, and the called workflow itself checks out ns8-github-actions@v1 at run time. Porting to test-module-qemu.yml remains the real fix.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant