ci: harden GitHub Actions supply chain (pin actions, drop unused setup-deno, least-privilege permissions)#222
Merged
Conversation
Remove the unused, unpinned denolib/setup-deno@v2 third-party action from
the release and test workflows (Deno is used nowhere in the repo), pin
every remaining action to a full commit SHA, and add least-privilege
permissions blocks.
- release.yml: drop the Setup Deno step; pin checkout, setup-node, and
attest-build-provenance to SHAs; add a top-level default-deny
`permissions: {}` while the release job keeps its explicit write grants.
- test.yml: drop the Setup Deno step; upgrade checkout v2 (EOL Node 16) to
v4 pinned to a SHA; pin setup-node; add `permissions: contents: read`.
- documentation.yml: pin checkout and setup-python to SHAs; add
`permissions: contents: read`.
Resolves deepsec findings other-ci-supply-chain (0995a86e73, e6c687034d).
Deploying podnotes with
|
| Latest commit: |
bc910a6
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://409fcbbe.podnotes.pages.dev |
| Branch Preview URL: | https://chhoumann-deepsec-ci-hardeni.podnotes.pages.dev |
Contributor
|
🎉 This PR is included in version 2.17.3 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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.
Hardens all GitHub Actions workflows against the supply-chain risk class flagged by deepsec: an unused, unpinned third-party action in the privileged release pipeline, plus unpinned actions and missing least-privilege permissions across the repo.
What changed
Remove the unused, unpinned third-party action
denolib/setup-deno@v2fromrelease.ymlandtest.yml. Deno is used nowhere in the repository (a word-boundary\bdeno\bsearch across the tree returns zero real hits, nodeno.json/deno.lock/import map). It was dead weight and pure attack surface -denolibis the older project superseded by canonicaldenoland/setup-deno, andv2is a mutable major tag, so a tag re-point or org compromise would have injected code into CI. Inrelease.ymlit ran beforenpm install/npm run build/Release withcontents/issues/pull-requests/id-token/attestations: writeandGITHUB_TOKEN/NPM_TOKENin scope.Pin every remaining action to a full commit SHA (with a
# vX.Y.Zcomment for readability), so a mutable tag can no longer be silently re-pointed:actions/checkout->34e114876b0b11c390a56381ad16ebd13914f8d5# v4.3.1actions/setup-node->49933ea5288caeca8642d1e84afbd3f7d6820020# v4.4.0actions/attest-build-provenance->e8998f949152b193b063cb0ec769d69d929409be# v2.4.0actions/setup-python->a26af69be951a213d495a4c3e4e4022e16d87065# v5.6.0test.ymlcheckout was@v2(long-EOL Node 16 runtime) and is upgraded to the v4.3.1 SHA above.Each SHA was verified against the GitHub API to resolve to its claimed tag and to point at a commit object.
Add least-privilege
permissions:blocksrelease.yml: top-level default-denypermissions: {}. The release job keeps its existing explicit job-level write grants (which override the top-level for that job), so the semantic-release push, release/comment, and attestation steps are unaffected.test.yml:permissions: contents: read(checkout + install + lint/format/typecheck/build/test are read-only; the npm cache does not needactions: write).documentation.yml:permissions: contents: read(checkout + setup-python +mkdocs build; there is no deploy/push step in this workflow -docs:deploy/wrangler is a separate, manually-run script).Why these choices
persist-credentials: falseto the release checkout.@semantic-release/gitpushes the version-bump commit/tag, and the persisted token authorizes that push. semantic-release does fall back to theGITHUB_TOKEN-authenticated URL when persisted creds are absent, so it is likely safe, but it touches the production release push path and cannot be validated without a live release, so I kept it out of scope.npm install->npm ciis a similar pre-existing, separately-validatable hardening left for a follow-up.Validation
npm run lint,format:check,typecheck,build, andtest(769 tests) all pass on Node 22.uses:is a 40-hex SHA).permissionsblock sufficient and minimal, and the release job retains exactly the write scopes it needs via job-level override.Resolves deepsec findings
other-ci-supply-chain(0995a86e73,e6c687034d).