Skip to content
Latchkey

pinact: Pin GitHub Actions to Commit SHAs

pinact edits your workflow files so every uses: line references a full commit SHA with the tag kept as a comment, closing the mutable-tag supply-chain hole.

A uses: actions/checkout@v4 tag can be moved by the action owner to any commit. Pinning to a SHA freezes exactly what runs. pinact does the pinning and keeps it updated.

What it does

pinact resolves each uses: reference to the commit SHA behind its tag and rewrites the line as owner/repo@<sha> # vX.Y.Z. pinact run pins in place; pinact run --check verifies without editing; pinact update bumps pinned SHAs to the latest release.

Common usage

Terminal
pinact run                        # pin all uses: to SHAs, in place
pinact run --check                # exit nonzero if anything is unpinned
pinact run .github/workflows/ci.yml
pinact update                     # update pinned SHAs to latest tags

Options

FlagWhat it does
runPin uses: references to full commit SHAs
run --checkVerify only; nonzero exit if unpinned actions remain
run --verifyVerify the SHA still matches the tag
updateUpdate pinned SHAs to the newest tag
--update / -uUpdate existing pins while pinning
GITHUB_TOKEN (env)Token used to resolve tags to SHAs and avoid rate limits

In CI

Add pinact run --check as a required PR check so any newly added action must be SHA-pinned to merge. Schedule pinact update on a bot branch (Renovate or a cron workflow) so pins do not go stale.

Common errors in CI

pinact run --check fails with a diff listing lines like actions/checkout@v4 is not pinned. GET https://api.github.com/... 403 API rate limit exceeded means no GITHUB_TOKEN is set; export one. failed to parse points at malformed workflow YAML, so lint with actionlint first. command not found: pinact means the binary is not installed.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →