fix(ci): harden GitHub Actions workflows (#1221) - #1224
hf-security-analysis[bot] wants to merge 0 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
Scope: 2 files — .github/workflows/publish-pypi.yml and .github/workflows/publish-testpypi.yml. The PR pins four actions/* steps from mutable tags to full-length commit SHAs (with version comments). No Python / library code is touched.
Automated Checks
- Lint: PASS for this PR's scope.
ruff format --check→ 337 files already formatted;ruff check→ all checks passed.usort checkflags only two pre-existing files (tests/envs/test_grid_world.py,tests/envs/test_julia_env.py) that are known-flagged on a clean tree and unrelated to this PR (which changes no Python). - Debug code: CLEAN. The debug-scan hits are all pre-existing docstring / CLI / manual-test code under
src/; none are in the files this PR touches.
Independent SHA verification
Because this PR is from an automated author and pins to opaque SHAs, I resolved each claimed tag against the official upstream repo (GET /repos/<action>/commits/<tag>). All four match exactly, and each also equals what the mutable tag it replaced currently points to — so this is a faithful pin with no version drift:
| Action | Pinned SHA | Comment | Upstream resolves to | Match |
|---|---|---|---|---|
actions/checkout |
3d3c42e5aac5ba805825da76410c181273ba90b1 |
v7.0.1 | v7.0.1 / v7 | ✅ |
actions/setup-python |
5fda3b95a4ea91299a34e894583c3862153e4b97 |
v7.0.0 | v7.0.0 / v7 | ✅ |
actions/upload-artifact |
043fb46d1a93c77aae656e7c1c64a875d1fc6a0a |
v7.0.1 | v7.0.1 | ✅ |
actions/download-artifact |
3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c |
v8.0.1 | v8.0.1 / v8 | ✅ |
The surrounding hardening in these workflows is already solid (permissions: contents: read by default, least-privilege per-job perms, persist-credentials: false, PyPI Trusted Publisher via OIDC, tag/version validation).
Open RFCs Context
No RFC covers CI / GitHub Actions / release workflows, so none are in conflict. (In Review: 000, 001, 002, 003, 005, 008, 012; Draft: 010, 011.)
Tier 1: Fixes Required
None. The change is mechanically correct and the SHAs + version comments are accurate.
Tier 2: Alignment Discussion
Principle Conflicts — None identified. OpenEnv's principles/invariants govern the env/client/server architecture (Gym API, MCP agent boundary, rewards-in-environment, client-server separation); this CI-only change doesn't touch any of them.
RFC Conflicts — None identified.
Non-blocking observations
- Scope vs. title. The title says "harden GitHub Actions workflows (#1221)" but only the two publish workflows are pinned. Several others still use mutable tags:
docker-build.yml,openspiel_base_build.yml,deploy-hf-env.yml,package-ci.yml,manage-hf-collection.yml,test.yml(e.g.actions/checkout@v7,docker/*@v4/v6/v7,astral-sh/setup-uv@v7). Prioritizing the publish workflows first is reasonable — they hold the most sensitive permissions (PyPI OIDCid-token: write,contents: write,pull-requests: write) — but consider a follow-up to cover the rest for a consistent posture, and confirm the reduced scope matches the intent of #1221. pypa/gh-action-pypi-publish@release/v1is intentionally left as a branch ref (PyPA's recommended usage for the trusted-publisher flow). Fine to leave as-is; a strict pin-everything policy would also pin it to a SHA.
Summary
- 0 mechanical issues to fix
- 0 alignment points for human review
- 0 RFC conflicts to discuss
- Verdict: clean, correct security hardening — all four pinned SHAs independently verified against upstream. Only a non-blocking scope/completeness note for follow-up.
Sent by Cursor Automation: Pre-review
f0ca9a5 to
48a767d
Compare
There was a problem hiding this comment.
This PR was auto-closed as collateral when I merged its base, and it should be restored.
It targeted dependabot/github_actions/actions/upload-artifact-7.0.1 rather than main. When #1221 merged as ca4219d2, GitHub deleted that base branch and closed this PR instead of retargeting it. That was my merge, not an author decision, and it is not a verdict on the change.
The head branch survives: security/workflow-hardening/pr-1221 at d21c2734. Reopening it and retargeting to main restores the PR with full history; both reopenPullRequest and updatePullRequest are 403 for this token, so I cannot do it myself. Retargeting to main also has a real benefit: this PR never ran the repository Tests, Package CI, or lint workflows, because those only trigger on PRs whose base is main. Only Build PR Documentation, Bugbot, and the automation checks ran here.
What I verified in the content (all still valid)
Every pin resolves to the official tag it claims:
| Action | Pinned SHA | Tag |
|---|---|---|
actions/checkout |
3d3c42e5aac5ba805825da76410c181273ba90b1 |
v7.0.1 |
actions/setup-python |
5fda3b95a4ea91299a34e894583c3862153e4b97 |
v7.0.0 |
actions/upload-artifact |
043fb46d1a93c77aae656e7c1c64a875d1fc6a0a |
v7.0.1 |
actions/download-artifact |
3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c |
v8.0.1 |
The diff is mechanical: it only replaces mutable major-version tags with those immutable SHAs in publish-pypi.yml and publish-testpypi.yml. No job, permission, trigger, or environment binding changes.
What still needs a human decision
Both pypa/gh-action-pypi-publish@release/v1 invocations stay on a mutable branch ref. Those are exactly the jobs that hold id-token: write against the PyPI and TestPyPI Trusted Publishers, so they are the highest-value refs in the repository to pin and the two the security bot still reports as HIGH. Pinning them is a release-credential boundary decision, so I am not making it: it needs the release owner, and it needs a reviewed commit rather than the moving release/v1 branch.
Recommendation on timing. Restore the PR now, but land it after Thursday's v0.6.0 publish rather than before. The 0.6.0 candidate has already been validated end-to-end through publish-testpypi.yml as it stands today, including the upload-artifact@v7.0.1 pin from #1221. Landing this immediately would change the publish path again after that validation, with no time to re-exercise it. Merging right after the release gives the pins a full TestPyPI cycle before they matter.
Sent by Cursor Automation: Release


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
Changes are limited to CI workflow action pins with no application or release-logic edits.
Overview
Hardens PyPI release CI by pinning third-party GitHub Actions in
publish-pypi.ymlandpublish-testpypi.yml, addressing pinactunpinned-actionfindings on the checkout, setup-python, upload-artifact, and download-artifact steps (includingactions/upload-artifact@v7.0.1on the artifact upload steps).Pin updates are mechanical from pinact; behavior of the publish/TestPyPI pipelines should stay the same while reducing supply-chain risk from floating action refs. Two high-severity workflow findings called out in #1221 are still open and are not part of this diff.
Reviewed by Cursor Bugbot for commit 48a767d. Bugbot is set up for automated code reviews on this repo. Configure here.