Skip to main content

gha-hashpinner

Finds mutable pins in GitHub Actions config and replaces them with immutable commit SHAs.

This is a security best practice that protects against supply chain attacks.

The immutable hashpins generated by this tool include version comments which are Dependabot-compatible.

⚠️ SHA pinning isn't a perfect solution and GitHub should be ashamed. If someone opens a PR to update a SHA pin, close it and let Dependabot do it instead (or manually verify the SHA is a member of the correct repo).

Example

❌ Mutable pins are a bad practice (you might get pwned!):

jobs:
  my-job:
    steps:
      - name: "Checkout"
        uses: "actions/checkout@v4"

✅ This tool will convert them to immutable pins:

jobs:
  my-job:
    steps:
      - name: "Checkout"
        uses: "actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5"  # v4

Install

uv tool install gha-hashpinner

Usage

From a GitHub repository containing GitHub Actions workflows in .github/workflows:

gha-hashpinner .

Or, update a specific workflow file:

gha-hashpinner .github/workflows/my-workflow.yml

GitHub API rate limiting

The GitHub API rate-limits unauthenticated requests to 60/hour. You may want to provide a token with the --token= argument to avoid rate limits. This tool only needs read access.

It's very important to minimize access granted to any tool to only what's required. Only use fine-grained personal access tokens (PATs) with no extra permissions. Never click the "Add permissions" button.

In other words, keep everything default. The only thing selected in the fine-grained PAT UI should be "Public repositories (Read-only access to public repositories)". If you need to run this tool against private repositories, select "All repositories" or "Only select repositories".

With GitHub Actions

TODO

With pre-commit / prek

TODO

Alternatives

Why?

I deeply distrust the NPM ecosystem. The Go package above is not user-friendly to install.

I wanted something I could install with uv tool install.

LLMs plus a dash of review and engineering judgement make it fast and easy to build tools like this.

Limitations

  • Does not update your actions -- only pins them immutably to the same version they're already pinned to. I recommend using Dependabot (with a cooldown) to upgrade your actions after pinning with this tool.
  • This tool detects mutable refs with regex, i.e. a 40-character hexadecimal string is considered to be an immutable ref. There's no way to be sure without making API calls. See the relevant issue (#13) for details.
  • When not given an explicit file path, only checks workflow files in .github/workflows.

Metadata

Release files for gha-hashpinner 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gha-hashpinner 0.0.3
File Size Uploaded
gha_hashpinner-0.0.3.tar.gz 63.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gha-hashpinner 0.0.3
File Interpreter ABI Platform
gha_hashpinner-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 79.1 kB

Release files / gha_hashpinner-0.0.3.tar.gz

Download URL gha_hashpinner-0.0.3.tar.gz
Size 63.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d41e7b5cefdaa0665508af58eb900d397f27c1449f2f621b53cc4e6d3e7949ec
BLAKE2b-256 checksum
How to use checksums
4fa61d387293146b1ce3a03f5fa155b0d227e4a4aad68e2d89ea9c6a61f2372d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 30, 2026.

Transparency log

Release files / gha_hashpinner-0.0.3-py3-none-any.whl

Download URL gha_hashpinner-0.0.3-py3-none-any.whl
Size 15.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17fc5570dd76e1f5e376147f7fbc6d0d668bdb8d67c74b469f91d8151dd96d7b
BLAKE2b-256 checksum
How to use checksums
9a61a4a412cf2bfaf8c970b9c2d0b061dd00f4f463b692439b297301a2aa9e32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page