ci(security): enforce immutable dependency pins - #24
Merged
Conversation
Reject mutable action refs, unpinned container bases, missing lockfile integrity, and non-frozen CI installs. Run the policy in local verification and every CI workflow.
There was a problem hiding this comment.
Pull request overview
Introduces a CI-enforced “immutable dependency pins” policy for uDDNS by adding a repository-side validator script, wiring it into the developer verification pipeline, and running it as an unconditional GitHub Actions job.
Changes:
- Add
scripts/check-dependency-pins.mjsto enforce pinned GitHub Actions, pinned Docker images, pnpm lockfile integrity, and frozen CI installs. - Add
deps:checkscript and run the dependency-pin validator as part ofpnpm run verify. - Document the dependency pinning policy in
docs/security.mdand add asupply-chainCI job to run the validator.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| scripts/check-dependency-pins.mjs | New policy validator for action/image pins, pnpm integrity, and frozen installs. |
| package.json | Adds deps:check and runs the validator during verify. |
| docs/security.md | Documents the new dependency pinning requirements and how to run the check. |
| .github/workflows/ci.yml | Adds an unconditional supply-chain job that runs the validator. |
Suppressed comments (2)
scripts/check-dependency-pins.mjs:44
- Commit SHA matching is case-sensitive (
[a-f0-9]), which can incorrectly reject valid full SHAs that contain uppercase hex digits. Since the policy is “40-character commit SHA”, the check should be case-insensitive.
if (!/@[a-f0-9]{40}$/u.test(reference)) {
fail(file, index + 1, `action is not pinned to a full commit SHA: ${reference}`);
}
scripts/check-dependency-pins.mjs:66
- Docker image digest matching is case-sensitive (
[a-f0-9]), which can incorrectly reject valid SHA-256 digests if they ever appear with uppercase hex digits. Digest hex should be treated case-insensitively.
if (!/@sha256:[a-f0-9]{64}$/u.test(image)) {
fail(file, index + 1, `base image is not pinned by digest: ${image}`);
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+34
to
+38
| const reference = line.match(/^\s*uses:\s*([^\s#]+)/u)?.[1]; | ||
| if (!reference || reference.startsWith('./')) return; | ||
| if (reference.startsWith('docker://')) { | ||
| if (!/@sha256:[a-f0-9]{64}$/u.test(reference)) { | ||
| fail(file, index + 1, `container action is not pinned by digest: ${reference}`); |
Comment on lines
+55
to
+56
| const stage = line.match(/^\s*FROM\s+\S+(?:\s+AS\s+(\S+))?/iu)?.[1]; | ||
| if (stage) stages.add(stage); |
Comment on lines
+94
to
+96
| if (/\bpnpm install\b/u.test(line) && !/--frozen-lockfile\b/u.test(line)) { | ||
| fail(file, index + 1, 'CI dependency install must use --frozen-lockfile'); | ||
| } |
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
Verification
pnpm run verifypnpm run deps:checkpnpm run checkAfter merge, the
supply-chainstatus will be made required onmain.