Skip to content

fix(ci): harden GitHub Actions workflows (#1221) - #1227

Closed
hf-security-analysis[bot] wants to merge 1 commit into
dependabot/github_actions/actions/upload-artifact-7.0.1from
security/workflow-hardening/pr-1221
Closed

hf-security-analysis[bot] wants to merge 1 commit into
dependabot/github_actions/actions/upload-artifact-7.0.1from
security/workflow-hardening/pr-1221

Conversation

@hf-security-analysis

@hf-security-analysis hf-security-analysis Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

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 pins

Fixed by this PR:

  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:31
  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:69
  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:101
  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:120
  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:139
  • HIGH unpinned-action (pinact) — .github/workflows/publish-pypi.yml:172
  • HIGH unpinned-action (pinact) — .github/workflows/publish-testpypi.yml:34
  • HIGH unpinned-action (pinact) — .github/workflows/publish-testpypi.yml:39
  • HIGH unpinned-action (pinact) — .github/workflows/publish-testpypi.yml:116
  • HIGH unpinned-action (pinact) — .github/workflows/publish-testpypi.yml:135

This 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 pinact and 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 @v7 with full hashes (with version comments) for actions/checkout, actions/setup-python, actions/upload-artifact, and actions/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/v1 is 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.

@burtenshaw burtenshaw added enhancement New feature or request size: small Small pull request labels Sep 22, 2026 — with Cursor
@bot-ci-comment

Copy link
Copy Markdown

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.

@dependabot
dependabot Bot deleted the branch dependabot/github_actions/actions/upload-artifact-7.0.1 September 22, 2026 06:18
@dependabot dependabot Bot closed this Sep 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.sh is a Python-only hook (usort/ruff over src/ tests/ envs/) and this PR changes zero .py files. Both changed YAML files parse cleanly (yaml.safe_load).
  • Debug code: CLEAN for this PR. check-debug.sh scans src/ 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 moving release/v1 branch 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.
Open in Web View Automation 

Sent by Cursor Automation: Pre-review

steps:
- name: Checkout code
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size: small Small pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant