fix(ci): harden GitHub Actions workflows (#1221) - #1227
hf-security-analysis[bot] wants to merge 1 commit into
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
There was a problem hiding this comment.
Alignment Review Report
Supply-chain hardening: pins the four actions/* steps in the two PyPI publish workflows to full 40-char commit SHAs (annotated # vX.Y.Z), replacing floating tags. This is the exact follow-up recommended on #1221. Reviewed the single hardening commit d5d896ce (diff base 48a767dd).
Automated Checks
- Lint: N/A for this diff.
.claude/hooks/lint.shis a Python-only hook (usort/ruffoversrc/ tests/ envs/) and this PR changes zero.pyfiles. Both changed YAML files parse cleanly (yaml.safe_load). - Debug code: CLEAN for this PR.
check-debug.shscanssrc/only; all its hits are pre-existing and none are in this diff.
SHA authenticity (core security check) — all 4 verified
Each pin was resolved with gh api repos/<owner>/<repo>/commits/<tag> and string-compared. Every pin matches, and each equals both the current floating-major tag tip and the latest release, so this is a zero-behavioral-change freeze:
| Action | Pinned SHA | Comment | Result |
|---|---|---|---|
| actions/checkout | 3d3c42e5…90b1 |
v7.0.1 | matches v7.0.1 == @v7 tip |
| actions/setup-python | 5fda3b95…4b97 |
v7.0.0 | matches v7.0.0 == @v7 tip |
| actions/upload-artifact | 043fb46d…6a0a |
v7.0.1 | matches v7.0.1 == @v7 tip |
| actions/download-artifact | 3e5f45b2…1e7c |
v8.0.1 | matches v8.0.1 == @v8 tip |
publish-testpypi.yml uses the identical verified pins. upload-artifact v7 and download-artifact v8 are the intentionally-paired-compatible releases, so the "7 vs 8" is correct, not a version skew. The stacked merge into the base branch is clean (git merge-tree → no conflicts).
Open RFCs Context
Current RFCs: 000/001/002/003/005/008/012 (In Review), 010/011 (Draft), 004 (Rubrics, no status header). None govern CI / GitHub Actions / dependency pinning — including 011 (behind discovery-catalog.yml) and 008 (env validation), which are orthogonal to this change.
Tier 1: Fixes Required
None.
Tier 2: Alignment Discussion
Principle Conflicts
None identified. SHA-pinning is a supply-chain improvement and does not touch the runtime surface the principles/invariants govern (Gym/MCP APIs, rewards-in-environment, client-server separation, container/credential isolation). The publish jobs already use secrets.*/OIDC and persist-credentials: false; no credential-exposure surface changed.
RFC Conflicts
None identified.
Informational (non-blocking)
- The actual publish step
pypa/gh-action-pypi-publish@release/v1(publish-pypi.yml:126,publish-testpypi.yml:141) is still on a mutable branch ref — the most trust-sensitive step here. The PR body says 2 findings were deliberately left for a human decision; this is presumably one. Pinning a movingrelease/v1branch to a SHA is a genuine maintenance trade-off (you'd stop receiving publish-action updates unless Dependabot tracks it), so deferring to a maintainer is reasonable — noting only for visibility. - Scope is intentionally the two publish workflows; other workflows (
test.yml,docker-build.yml,deploy-hf-env.yml,openspiel_base_build.yml, etc.) still use floating tags and are a natural repo-wide follow-up. - Suggested human check: @burtenshaw (owns/last edited the publish workflows) — worth a release-pipeline smoke test after merge, since this is stacked on the #1221 Dependabot branch rather than
main.
Summary
- 0 mechanical issues to fix (Tier 1)
- 0 alignment points for human review (Tier 2)
- 0 RFC conflicts
- 4/4 action pins verified authentic and behavior-preserving. Clean, well-scoped supply-chain hardening.
Sent by Cursor Automation: Pre-review
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v7 | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
There was a problem hiding this comment.
Verified: 3d3c42e5aac5ba805825da76410c181273ba90b1 == actions/checkout v7.0.1 (gh api repos/actions/checkout/commits/v7.0.1), which is also the current @v7 tag tip and latest release ⇒ zero behavioral change.
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v7 | ||
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 |
There was a problem hiding this comment.
Verified: 5fda3b95a4ea91299a34e894583c3862153e4b97 == actions/setup-python v7.0.0, which is the current @v7 tag tip and latest release. (Patch level reads lower than the others, v7.0.0 vs v7.0.1, but it is the current v7 tip — correct.)
|
|
||
| - name: Upload release distribution artifact | ||
| uses: actions/upload-artifact@v7.0.1 | ||
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 |
There was a problem hiding this comment.
Verified: 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a == actions/upload-artifact v7.0.1 == current @v7 tip. Pairs with download-artifact v8 below (the intentionally-compatible v7⇄v8 release pair); upload steps use only name/path, so default zip behavior is preserved.
| steps: | ||
| - name: Download release distribution artifact | ||
| uses: actions/download-artifact@v8 | ||
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 |
There was a problem hiding this comment.
Verified: 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c == actions/download-artifact v8.0.1 == current @v8 tip. Same verified pin is reused at line 139 and in publish-testpypi.yml:135.


Automated hardening of the workflow files flagged on #1221.
Targets
dependabot/github_actions/actions/upload-artifact-7.0.1. Files changed, and what changed them:.github/workflows/publish-pypi.yml— action pins.github/workflows/publish-testpypi.yml— action pinsFixed by this PR:
unpinned-action(pinact) — .github/workflows/publish-pypi.yml:31unpinned-action(pinact) — .github/workflows/publish-pypi.yml:69unpinned-action(pinact) — .github/workflows/publish-pypi.yml:101unpinned-action(pinact) — .github/workflows/publish-pypi.yml:120unpinned-action(pinact) — .github/workflows/publish-pypi.yml:139unpinned-action(pinact) — .github/workflows/publish-pypi.yml:172unpinned-action(pinact) — .github/workflows/publish-testpypi.yml:34unpinned-action(pinact) — .github/workflows/publish-testpypi.yml:39unpinned-action(pinact) — .github/workflows/publish-testpypi.yml:116unpinned-action(pinact) — .github/workflows/publish-testpypi.yml:135This does not fix everything. 2 further finding(s) (2 high) need a decision this bot should not make for you. They are in the security channel with their locations — deliberately not repeated here, since this repository may be public and they are not fixed yet.
Pinning changes come from
pinactand are mechanical. Any other change was generated by Claude — read it before merging.Note
Low Risk
Mechanical action pinning only; no application or publish logic changes, though release pipelines should be smoke-tested after merge.
Overview
Pins third-party GitHub Actions to immutable commit SHAs in the PyPI and TestPyPI publish workflows, replacing floating tags like
@v7with full hashes (with version comments) foractions/checkout,actions/setup-python,actions/upload-artifact, andactions/download-artifact.This is supply-chain hardening so release jobs do not silently pick up a changed action ref. Build, publish, and post-release steps are unchanged aside from these
uses:lines;pypa/gh-action-pypi-publish@release/v1is still on a branch ref and was not part of this diff.Reviewed by Cursor Bugbot for commit d5d896c. Bugbot is set up for automated code reviews on this repo. Configure here.