Repository navigation
fix(ci): scope write tokens to jobs and pin actions and base images - #616
Conversation
Clears the OpenSSF Scorecard TokenPermissions and PinnedDependencies code-scanning alerts: - update-registry, promote, image and codeql now grant write scopes on the job that needs them; the workflow top level is read-only. - image.yml pins checkout and the docker/* actions to full commit SHAs (same major versions as before). - The Dockerfile pins golang:1.26.10-alpine and oven/bun 1.4.4 (the version oven/bun:1 resolves to today and the one CI tests) by digest, and Dependabot now tracks the docker ecosystem so the digests stay current. - scripts/supply-chain-pins.test.ts (part of test:unit) fails on any top-level write permission, unpinned action or undigested base image. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
This PR has been added to the review queue. Track progress: https://factory.gascity.com/city/maintainer-city/runs/gcg--9223372036837046432 |
Brings in #615 (nanoid override ^3.3.20) so the branch is up to date for the strict "CI / required" protection on main. No conflicts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…uard The supply-chain guard only read step-level `uses:`, so an unpinned reusable workflow (`jobs.<id>.uses: org/repo/.github/workflows/x.yml@main`) passed it even though Scorecard's Pinned-Dependencies check flags one. It also rejected two correctly pinned forms: a `docker://image@sha256:...` action and `FROM scratch`. Extract the detection into unpinnedActions and unpinnedBaseImages, cover job-level `uses:`, accept a digest for docker:// actions, treat `scratch` and earlier stage names (case-insensitively) as local, and pin the detection behavior with fixture tests. Against main the guard still fails exactly the six alert groups. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Max-effort review: approve and mergeVerdict: clean. This PR fixes all 15 targeted Scorecard alerts and introduces no new ones. Every job's effective token is unchanged, and all pins resolve to exactly what the floating refs gave yesterday, so CI and the shipped image behave identically. I pushed two commits (listed below) and found no blocking defects. All checks are green on the final head Alerts
Permissions, traced per jobEach of the four workflows has a single job, and a job-level
Pins
Verification (local, Bun 1.4.4 taken from the pinned image)
Commits I pushed (fast-forward)
Follow-ups (not blocking)
🤖 Generated with Claude Code |
Fixes the actionable OpenSSF Scorecard code-scanning alerts in this repo. No GHSA/CVE IDs: these are Scorecard supply-chain hardening findings.
Alerts fixed
security-events), docs: sync org TESTING.md testing standard #17 (image.ymlpackages), feat(auth): SSO-asserted registry-staff role → registry admin #26 (promote.ymlpackages), feat(auth): GitHub-only product login + /staff SSO entry (kc_idp_hint) #27 (update-registry.ymlactions), ci: publish main-<epoch> + apex-main-<epoch> tags for Flux auto-bump #28 (update-registry.ymlcontents). Each write scope now sits on the job that uses it; the workflow top level is read-only. Job permissions are unchanged in effect.actions/checkoutand thedocker/*actions are pinned to full commit SHAs at the latest release of the major version already in use (checkout v4.4.0, setup-buildx v3.12.0, login v3.7.0, metadata v5.10.0, build-push v6.19.2). The open Dependabot major-bump PRs (chore(deps): bump docker/build-push-action from 6 to 7 #29-chore(deps): bump actions/checkout from 4.4.0 to 7.0.1 #32, chore(deps): bump docker/metadata-action from 5 to 6 #40) will need a rebase after this.golang:1.26.10-alpineandoven/bun:1.4.4/oven/bun:1.4.4-alpineare pinned by digest. 1.4.4 is whatoven/bun:1resolves to today (same digests) and what CI tests since ci: test on Bun 1.4.4, the Bun that ships (eMudhra CA compromise) #614. Dependabot now tracks thedockerecosystem so the digests keep getting bumped.Test
scripts/supply-chain-pins.test.tsruns as part oftest:unit. It fails if a workflow has a top-level write permission, a non-local action isn't pinned to a 40-hex SHA, or a Dockerfile base image has no@sha256:digest. Againstorigin/mainit fails 6 tests, one per alert group above. With this change it passes.Verified locally
bun run test:unit: 480 pass, 0 failbun run typecheckandbun run generate:checkare cleanactionlintshows no new findings. The only output is the existing runner-label and SC2129 notes.docker buildof the full Dockerfile succeeds with the pinned digests, and the image runs Bun 1.4.4Not in this PR (process/false-positive items, see the triage report): #7 CodeReview, #8 CII badge, #9 Fuzzing, and the CodeQL
js/insufficient-password-hashalerts #1 and #10. Those two are false positives: they flag SHA-256 over 256-bit random API/session tokens and an HMAC over signed state.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.