Skip to content

fix(ci): harden GitHub Actions workflows (#377) - #378

Merged
paulinebm merged 1 commit into
dependabot/github_actions/actions-9eef8402e4from
security/workflow-hardening/pr-377
Sep 17, 2026
Merged

paulinebm merged 1 commit into
dependabot/github_actions/actions-9eef8402e4from
security/workflow-hardening/pr-377

Conversation

@hf-security-analysis

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

Copy link
Copy Markdown
Contributor

Automated hardening of the workflow files flagged on #377.

Warning

This narrows what the workflow can reach. Job permissions were declared in .github/workflows/build-push-unity.yml, .github/workflows/pip.yml, .github/workflows/quality.yml, .github/workflows/tests-no-deps.yml, .github/workflows/tests.yml, .github/workflows/wheels.yml. Each job now gets only the scopes its steps were read to need — if one of them does something this could not see, it will fail on the next run. The table below says which step drove each scope.

Targets dependabot/github_actions/actions-9eef8402e4. Files changed:

  • .github/workflows/build-push-unity.yml
  • .github/workflows/pip.yml
  • .github/workflows/quality.yml
  • .github/workflows/tests-no-deps.yml
  • .github/workflows/tests.yml
  • .github/workflows/wheels.yml

Fixed by this PR:

  • HIGH broken_auth_gate (claude) — .github/workflows/build-push-unity.yml
  • HIGH unpinned-action (pinact) — .github/workflows/pip.yml:25
  • HIGH unpinned-action (pinact) — .github/workflows/pip.yml:27
  • HIGH unpinned-action (pinact) — .github/workflows/quality.yml:9
  • HIGH unpinned-action (pinact) — .github/workflows/quality.yml:11
  • HIGH unpinned-action (pinact) — .github/workflows/tests.yml:24
  • HIGH unpinned-action (pinact) — .github/workflows/tests.yml:27
  • HIGH unpinned-action (pinact) — .github/workflows/tests.yml:31
  • HIGH unpinned-action (pinact) — .github/workflows/wheels.yml:46
  • HIGH unpinned-action (pinact) — .github/workflows/wheels.yml:78
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/build-push-unity.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/build-push-unity.yml:18
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/build-push-unity.yml:86
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/pip.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/pip.yml:15
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/quality.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/quality.yml:6
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/tests-no-deps.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/tests-no-deps.yml:9
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/tests.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/tests.yml:9
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/wheels.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/wheels.yml:18
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/wheels.yml:35
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/wheels.yml:62

This does not fix everything. 6 further finding(s) (6 medium) 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.

Permissions

.github/workflows/build-push-unity.yml

job granted why
buildForAllSupportedPlatforms contents: read Only actions/checkout (with LFS) needs the token for repository read; the cache, game-ci/unity-builder (uses a Unity license secret, not the GITHUB_TOKEN) and upload-artifact steps need no scopes.
PushToHub {} — nothing setup-python and download-artifact (same-run artifacts) need no token scopes, and the git push targets huggingface.co using the HF_TOKEN secret rather than the repository, so no GITHUB_TOKEN permissions are required.

.github/workflows/build_documentation.yml

build was left as it is — This job only calls the external reusable workflow huggingface/doc-builder/.github/workflows/build_main_documentation.yml, whose jobs and their token usage are not visible in this file, so the required scopes cannot be determined here.

.github/workflows/build_pr_documentation.yml

build was left as it is — This job only calls the external reusable workflow huggingface/doc-builder/.github/workflows/build_pr_documentation.yml, whose jobs and their token usage are not visible in this file, so the required scopes are inherited from that workflow and cannot be determined here.

.github/workflows/delete_doc_comment.yml

delete was left as it is — This job only delegates to the external reusable workflow huggingface/doc-builder/.github/workflows/delete_doc_comment.yml, whose jobs and steps are not visible in this file, so the required scopes (likely pull-request or comment related) cannot be verified here.

.github/workflows/pip.yml

job granted why
build contents: read Only actions/checkout needs the token (contents: read); the remaining steps just set up Python, pip install the package and run an import smoke test, which use no API access.

.github/workflows/quality.yml

job granted why
quality contents: read Only actions/checkout needs the token (contents: read); the remaining steps install dependencies and run make quality locally — the Makefile target isn't in this file, but a lint/format check needs no API access.

.github/workflows/tests-no-deps.yml

job granted why
run-tests contents: read Only actions/checkout needs the token (contents: read); the remaining steps set up Python, restore a pip cache, install the package and run a local import test, none of which touch the GitHub API.

.github/workflows/tests.yml

job granted why
run-tests contents: read Only actions/checkout needs the token (contents: read); the remaining steps install Python/VTK, cache pip, and run make test locally without any API access.

.github/workflows/wheels.yml

job granted why
build_sdist contents: read Only actions/checkout needs the token; the upload-artifact step publishes within the same run and needs no scope.
build_wheels contents: read actions/checkout drives contents: read; cibuildwheel and upload-artifact (same run) use no repository token.
upload_all {} — nothing Downloads artifacts from the same run and publishes to PyPI with a username/password secret rather than OIDC, so no GITHUB_TOKEN scope is required; if the publish step is ever switched to trusted publishing it will need id-token: write.

Anything not listed above keeps the permissions it had. To measure a job this could not read, add GitHubSecurityLab/actions-permissions/monitor to it and run the workflow — it reports the minimum the run actually used.

Pinning changes come from pinact and are mechanical. Any other change was generated by Claude — read it before merging.

@paulinebm
paulinebm merged commit bc535ec into dependabot/github_actions/actions-9eef8402e4 Sep 17, 2026
8 of 21 checks passed
@paulinebm
paulinebm deleted the security/workflow-hardening/pr-377 branch September 17, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant