Skip to content

fix(ci): harden GitHub Actions workflows (#2119) - #2421

Merged
paulinebm merged 1 commit into
feat/train_encode_splitfrom
security/workflow-hardening/pr-2119
Sep 18, 2026
Merged

paulinebm merged 1 commit into
feat/train_encode_splitfrom
security/workflow-hardening/pr-2119

Conversation

@hf-security-analysis

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

Copy link
Copy Markdown
Contributor

Automated hardening of the workflow files flagged on #2119.

Warning

This narrows what the workflow can reach. Job permissions were declared in .github/workflows/bitsplit.yml, .github/workflows/docs-check.yml, .github/workflows/node.yml, .github/workflows/rust-release.yml, .github/workflows/rust.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 feat/train_encode_split. Files changed:

  • .github/workflows/CI.yml
  • .github/workflows/bitsplit.yml
  • .github/workflows/docs-check.yml
  • .github/workflows/node.yml
  • .github/workflows/python.yml
  • .github/workflows/rust-release.yml
  • .github/workflows/rust.yml

Fixed by this PR:

  • HIGH unpinned-action (pinact) — .github/workflows/CI.yml:200
  • HIGH unpinned-action (pinact) — .github/workflows/bitsplit.yml:18
  • HIGH unpinned-action (pinact) — .github/workflows/bitsplit.yml:32
  • HIGH unpinned-action (pinact) — .github/workflows/bitsplit.yml:53
  • HIGH unpinned-action (pinact) — .github/workflows/bitsplit.yml:56
  • HIGH unpinned-action (pinact) — .github/workflows/node.yml:33
  • HIGH unpinned-action (pinact) — .github/workflows/node.yml:46
  • HIGH unpinned-action (pinact) — .github/workflows/node.yml:55
  • HIGH unpinned-action (pinact) — .github/workflows/node.yml:90
  • HIGH unpinned-action (pinact) — .github/workflows/python.yml:76
  • HIGH unpinned-action (pinact) — .github/workflows/python.yml:86
  • HIGH unpinned-action (pinact) — .github/workflows/python.yml:128
  • HIGH unpinned-action (pinact) — .github/workflows/rust.yml:47
  • HIGH unpinned-action (pinact) — .github/workflows/rust.yml:56
  • HIGH unpinned-action (pinact) — .github/workflows/rust.yml:258
  • HIGH unpinned-action (pinact) — .github/workflows/rust.yml:267
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/bitsplit.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/bitsplit.yml:15
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/bitsplit.yml:29
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/bitsplit.yml:50
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/docs-check.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/docs-check.yml:16
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/node.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/node.yml:13
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/node.yml:62
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/node.yml:100
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust-release.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust-release.yml:12
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:1
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:10
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:101
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:128
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:145
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:176
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:200
  • MEDIUM excessive-permissions (zizmor) — .github/workflows/rust.yml:233

This does not fix everything. 22 further finding(s) (16 critical, 4 high, 2 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/bitsplit.yml

job granted why
native contents: read Only actions/checkout needs the token; the remaining steps run cargo fmt/clippy/test and a local git diff --exit-code against the working tree, which never pushes or calls the API.
avx512-sde contents: read actions/checkout drives contents: read; the Intel SDE install is a plain curl to downloadmirror.intel.com and the SDE test run uses no GitHub API.
wasm contents: read actions/checkout drives contents: read; bytecodealliance/actions/wasmtime/setup fetches a wasmtime release (read-only at most) and the cargo test step only builds and runs locally.

.github/workflows/build_pr_documentation.yml

build was left as it is — This job only declares uses: to call 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 cannot be determined here.

.github/workflows/docs-check.yml

job granted why
build contents: read Only actions/checkout needs the token (contents: read); the doc build, pip installs and actions/upload-artifact within the same run require no additional scopes.

.github/workflows/node.yml

job granted why
build_and_test contents: read Only actions/checkout needs the token; the build, cache and make test steps talk to the Hugging Face Hub using HF_TOKEN (a secret, not the GITHUB_TOKEN), so no extra scopes are required.
quality contents: read Checkout is the only token-consuming step; cargo fmt/clippy and yarn lint run entirely locally and report via the job status, not the API.
audit contents: read Checkout needs contents: read; cargo install cargo-audit and cargo audit fetch from crates.io and the RustSec advisory DB, not the GitHub API, so no vulnerability-alerts or security-events scope is needed.

.github/workflows/rust-release.yml

job granted why
rust_publish contents: read Only actions/checkout needs the token (contents: read); the cache, bitmap_gen regeneration/git diff, and cargo publish authenticate to crates.io with CRATES_TOKEN, which is a secret and grants no GITHUB_TOKEN scopes.

.github/workflows/rust.yml

job granted why
build_and_test contents: read Only actions/checkout needs the token (contents: read); the rest is cargo build/test, caching and Hub downloads authenticated by secrets.HF_TOKEN, which grants no scope — note make test/make oracle invoke a Makefile not present in this file, so a reviewer should confirm those targets make no GitHub API calls.
clippy contents: read actions/checkout is the only token-using step; cargo clippy and rust-cache need no scopes.
format contents: read actions/checkout drives contents: read; cargo fmt --check needs nothing.
readme contents: read actions/checkout drives contents: read; cargo-readme only diffs files locally and never writes back to the repo.
audit contents: read actions/checkout drives contents: read; cargo-audit reads the advisory DB over plain git/HTTPS and does not upload results, so no security-events scope is needed.
semver contents: read actions/checkout drives contents: read; cargo-semver-checks fetches the baseline from crates.io, not the GitHub API.
feature_matrix contents: read actions/checkout drives contents: read; taiki-e/install-action@cargo-hack is the step I was least sure about since it fetches a prebuilt binary from GitHub releases, which contents: read already covers.

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 4160add into feat/train_encode_split Sep 18, 2026
28 of 30 checks passed
@paulinebm
paulinebm deleted the security/workflow-hardening/pr-2119 branch September 18, 2026 07:47
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