Skip to content

Harden workflow permissions and credentials - #2648

Open
somewhatabstract wants to merge 5 commits into
mainfrom
claude/jolly-galileo-72zesp-harden-workflows
Open

somewhatabstract wants to merge 5 commits into
mainfrom
claude/jolly-galileo-72zesp-harden-workflows

Conversation

@somewhatabstract

Copy link
Copy Markdown
Owner

Summary
Fixes the workflow findings zizmor reported, apart from those in the Dependabot workflow, which #2646 handles:

  • Default token permissions: Node CI and Rust CI didn't set permissions:, so their token got the repository's default access. They're now read-only.
  • Credentials left by actions/checkout: it no longer leaves the token in .git/config, where any later step could read it.
  • Unpinned npm install: the release workflow no longer installs npm@latest.

Stack

Issues
Part of #2642's supply-chain hardening, alongside #2643.

Details

  • excessive-permissions:
    • nodejs.yml and rust.yml now have a top-level permissions: contents: read.
    • The lint job also gets pull-requests: read, because the changesets check (Khan/actions → get-changed-files) looks up the pull request for a commit through the API.
    • codeql-analysis.yml and release.yml already set their own permissions.
  • artipacked: persist-credentials: false is set on every actions/checkout that lacked it: 4 in nodejs.yml, 2 in rust.yml and 1 in codeql-analysis.yml. None of these jobs pushes with git. The changesets check reads the changed files from the API, not git (I checked its source at the pinned commit), and release.yml already sets it.
  • adhoc-packages: release.yml ran npm install -g npm@latest whenever npm was older than 11.5.1, the minimum for trusted publishing.
    • According to the Node.js release index, every Node.js 24 release since 24.5.0 bundles npm 11.5.1 or later, and setup-node with 24.x currently installs 24.22.2, which bundles npm 11.19.1. So the upgrade never ran.
    • If it had, it would have installed an unpinned npm in the job that publishes to npm.
    • The step is now a check that fails the release with a clear error instead. I tested it with npm 11.19.1 and 11.5.1, which pass, and with 11.5.0 and 10.9.2, which fail.
  • An empty changeset, since the published package doesn't change.

Review notes


Generated by Claude Code

Tags can be moved to point at different code, so a compromised action
repository could run malicious code in every workflow that references it
by tag, including the release workflow, which holds publishing
credentials. A full commit SHA can't be moved.

Each SHA was resolved from the tag it replaces and checked again against
the tag in its version comment. changesets/action@v1 was a branch, not a
tag; it's pinned to v1.9.0, which is the branch's current commit.
Dependabot's github-actions updates keep the pins and comments current.

Closes #2643.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QjLhVH1NnUc7MzCSYLd8Yn
- Give the default GITHUB_TOKEN read-only access in Node CI and Rust CI,
  which set no permissions and so got the repository default. The lint
  job also gets pull-requests: read for the changesets check.
- Stop actions/checkout leaving the token in .git/config, where any later
  step could read it. No job pushes with git.
- Replace the release workflow's `npm install -g npm@latest` with a check.
  Every Node.js 24 release since 24.5.0 bundles npm 11.5.1 or later, so
  the upgrade never ran; if it ever did, it would install an unpinned
  npm in the job that publishes to npm.

Found by zizmor (excessive-permissions, artipacked, adhoc-packages).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QjLhVH1NnUc7MzCSYLd8Yn
…72zesp-harden-workflows

# Conflicts:
#	.github/workflows/codeql-analysis.yml
#	.github/workflows/nodejs.yml
#	.github/workflows/rust.yml
@changeset-bot

changeset-bot Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f896d9c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (8cc6fce) to head (f896d9c).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##              main     #2648   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           51        51           
  Lines          959       959           
  Branches       232       231    -1     
=========================================
  Hits           959       959           

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 68440c9...f896d9c. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codecov

codecov Bot commented Oct 30, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

Dependabot rejects semver-major-days for the github-actions ecosystem,
which made the whole dependabot.yml invalid and stopped version updates.
The JSON schema the config was checked against didn't know about that
restriction. GitHub Actions keeps the 7-day default cooldown.

Fixes the config added in #2645.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QjLhVH1NnUc7MzCSYLd8Yn
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.

2 participants