ci: harden GitHub Actions against supply chain attacks#4607
Conversation
Add `persist-credentials: false` to all 56 actions/checkout steps across 22 workflow files and the test-apps.cue template (regenerated test-apps.yml). This prevents GITHUB_TOKEN from being stored in .git/config after checkout, eliminating the primary vector used in supply chain attacks like the tj-actions/changed-files incident. sync-cue-actions.yml still performs a git push; it now injects credentials via `git remote set-url` scoped only to that step rather than persisting them for all subsequent steps. Also add explicit `permissions:` blocks to 6 workflows that were inheriting repo defaults, and fix two stale/missing version comments on checkout steps.
Add inline // vX.Y.Z comments to the three pinned action uses: lines in test-apps.cue. The Makefile generation step now post-processes cue export output with a Python one-liner that reads those comments and appends them as # vX.Y.Z annotations in the generated YAML, matching the convention used in all handwritten workflow files. Extend sync-cue-actions.yml to also extract the version comment from Dependabot's test-apps.yml update and sync it back into the test-apps.cue comment, so the annotation stays correct after each Dependabot bump.
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: 868ecd2 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback! |
BenchmarksBenchmark execution time: 2026-03-26 12:23:00 Comparing candidate commit 868ecd2 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 218 metrics, 6 unstable metrics.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files🚀 New features to boost your workflow:
|
The previous sed used an address pattern /${action}@/ to scope the
substitution, but action names like actions/checkout contain literal
slashes that break both GNU and BSD sed's address parsing. Replace it
with an inline match in the substitute expression using | as delimiter,
which handles slashes in action names correctly.
Verified with a local Dependabot simulation: SHA and version comment
in test-apps.cue both update correctly after a Dependabot bump.
What does this PR do?
Adds
persist-credentials: falseto all 56actions/checkoutsteps across 22 workflow files and thetest-apps.cueCUE template (which regeneratestest-apps.yml). Also adds explicitpermissions:blocks to 6 workflows that were inheriting repo defaults, and fixes two stale/missing version comments.Motivation
actions/checkoutdefaults topersist-credentials: true, which storesGITHUB_TOKENin.git/configashttp.https://github.com/.extraheaderfor the lifetime of the job. Any subsequent step — including third-party actions — can read that credential and use it to push code, create releases, or access private repos. This is the primary vector used in thetj-actions/changed-filessupply chain attack.Setting
persist-credentials: falseeliminates this residual credential exposure. The one workflow that performs agit push(sync-cue-actions.yml) now injects credentials viagit remote set-urlscoped only to that step.Reviewer's Checklist
make lintlocally.test-apps.ymlregenerated fromtest-apps.cue).