The Pin Bar 2026
Pinning third-party Actions to a 40-character commit SHA - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
rather than uses: actions/checkout@v4 - is the
single
most-recommended hardening in GitHub's own security guide.
It's why pinned-action-sha
is a warn-level rule in ci-doctor.
How often is the recommendation actually followed in famous OSS? We have the data lying around because the depmedic leaderboard already pulls every workflow from 20 popular repos every day. Here are the numbers from the latest snapshot.
Headline numbers
| Repos audited | 20 |
|---|---|
Total uses: references | 1,461 |
| Pinned to a 40-char SHA | 868 (59.4%) |
Pinned to a tag (@v4, @main...) | 592 (40.5%) |
Unpinned (no @) | 1 |
| Repos at 100% | 6 (deno, axios, express, jest, webpack, rollup) |
| Repos at 0% | 4 (parcel, preact, react-router, got) |
Per-repo board
| Repo | Pin % | Pinned | Total | Bar |
|---|---|---|---|---|
| denoland/deno | 100% | 368 | 368 | |
| axios/axios | 100% | 60 | 60 | |
| expressjs/express | 100% | 22 | 22 | |
| jestjs/jest | 100% | 35 | 35 | |
| webpack/webpack | 100% | 48 | 48 | |
| rollup/rollup | 100% | 50 | 50 | |
| prettier/prettier | 98.0% | 50 | 51 | |
| microsoft/TypeScript | 93.2% | 68 | 73 | |
| storybookjs/storybook | 74.3% | 81 | 109 | |
| vitejs/vite | 37.5% | 15 | 40 | |
| vercel/next.js | 34.0% | 48 | 141 | |
| sveltejs/svelte | 23.1% | 9 | 39 | |
| tannerlinsley/react-query | 20.0% | 4 | 20 | |
| eslint/eslint | 6.5% | 3 | 46 | |
| facebook/react | 3.3% | 6 | 180 | |
| vuejs/core | 2.4% | 1 | 42 | |
| sindresorhus/got | 0% | 0 | 2 | |
| remix-run/react-router | 0% | 0 | 52 | |
| preactjs/preact | 0% | 0 | 32 | |
| parcel-bundler/parcel | 0% | 0 | 51 |
What the headline number means
59.4% sounds bad on its face. It's not as bad as it looks - and it's not as good either.
- It is partly Dependabot. Dependabot can rewrite
actions/checkout@v4to a SHA via thepackage-ecosystem: github-actionsentry. Repos that enable it score higher essentially for free. Deno, axios, jest, rollup, webpack, prettier, and TypeScript all have Dependabot on GitHub Actions. - It is partly culture. The dropoff between "always pinned" and "never pinned" is sharper than the dropoff between "all rules followed" and "no rules followed" you'd expect from a normal distribution. Repos either care about this or they don't.
- The unpinned half is concentrated. 4 repos (parcel, preact, react-router, got) account for 137 fully unpinned references on their own. Fix those four and the OSS pin bar averages 70%+.
Why pinning matters in 30 seconds
When you write uses: tj-actions/changed-files@v45,
GitHub resolves v45 to whatever commit the maintainer
most recently tagged that way. Tags are mutable. If the maintainer's
npm or PyPI account is compromised - or, say,
if the action gets a malicious push the way tj-actions/changed-files
did in March 2025 - your CI immediately runs the attacker's payload.
Workflows then have access to GITHUB_TOKEN, your
secrets.*, and on private runners often the runner's
filesystem and AWS metadata service.
Pinning to a 40-character SHA fixes this. The SHA is content-addressed,
so it cannot be moved out from under you. You give up automatic
updates - which is why
configuring Dependabot for github-actions is the
paired move.
Fix it in your repo, in two minutes
$ npx pin-actions # rewrites every uses: in .github/workflows to a SHA $ npx pin-actions --check # CI gate: exit 1 if anything is unpinned
pin-actions
is the depmedic-built free CLI that does the rewrite, comment-preserving,
in place. Pair it with the github-actions entry in
.github/dependabot.yml and you get the security of pinning
without the maintenance tax.
Verify on your own repo
No install needed:
- Scan any public GitHub repo in the
browser. Look for the
pinned-action-shafinding count. - Or paste a single workflow for an instant report.
- Install depmedic-bot and the finding shows up as a PR comment automatically.
Score your own repo on the leaderboard
The depmedic leaderboard ranks 20+ OSS repos by CI hygiene every day. Want yours added? Email depmedicdev@gmail.com with the repo URL. No charge.
See the leaderboard Read the ruleMethodology
Source: the depmedic leaderboard's nightly scrape of all
.github/workflows/*.yml files in 20 popular OSS repos.
Counting rule: every uses: owner/repo@ref reference
(including reusable workflows). ./ local references and
docker:// step refs are excluded. A reference counts as
"pinned" iff ref matches /^[0-9a-f]{40}$/i.
No deduplication: a single action used in five jobs counts five times.
Snapshot date: 2026-04-28. Data + script: tools/analyze-pin-bar.mjs.