Skip to main content

Update GitHub Actions configurations to use hashpins, instead of mutable pins, in a Dependabot-compatible way

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gha_hashpinner-0.0.3.tar.gz (63.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gha_hashpinner-0.0.3-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file gha_hashpinner-0.0.3.tar.gz.

File metadata

  • Download URL: gha_hashpinner-0.0.3.tar.gz
  • Upload date:
  • Size: 63.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gha_hashpinner-0.0.3.tar.gz
Algorithm Hash digest
SHA256 d41e7b5cefdaa0665508af58eb900d397f27c1449f2f621b53cc4e6d3e7949ec
MD5 32ace00b2c3064d7f18c03306e7a46db
BLAKE2b-256 4fa61d387293146b1ce3a03f5fa155b0d227e4a4aad68e2d89ea9c6a61f2372d

See more details on using hashes here.

Provenance

The following attestation bundles were made for gha_hashpinner-0.0.3.tar.gz:

Publisher: publish.yml on mfisher87/gha-hashpinner

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gha_hashpinner-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: gha_hashpinner-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gha_hashpinner-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 17fc5570dd76e1f5e376147f7fbc6d0d668bdb8d67c74b469f91d8151dd96d7b
MD5 0cba64624f7ee1bdc17a8e67d4af0b7d
BLAKE2b-256 9a61a4a412cf2bfaf8c970b9c2d0b061dd00f4f463b692439b297301a2aa9e32

See more details on using hashes here.

Provenance

The following attestation bundles were made for gha_hashpinner-0.0.3-py3-none-any.whl:

Publisher: publish.yml on mfisher87/gha-hashpinner

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page