{"id":28475223,"url":"https://github.com/mccutchen/ghavm","last_synced_at":"2026-05-16T17:07:33.546Z","repository":{"id":295733129,"uuid":"990758160","full_name":"mccutchen/ghavm","owner":"mccutchen","description":"ghavm manages version pinning and upgrades for GitHub Actions workflows.","archived":false,"fork":false,"pushed_at":"2025-07-21T02:45:35.000Z","size":96,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-21T04:21:28.670Z","etag":null,"topics":["ci","continuous-integration","github-actions","supply-chain"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mccutchen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T15:32:15.000Z","updated_at":"2025-07-21T02:42:41.000Z","dependencies_parsed_at":"2025-07-21T04:22:24.715Z","dependency_job_id":null,"html_url":"https://github.com/mccutchen/ghavm","commit_stats":null,"previous_names":["mccutchen/ghavm"],"tags_count":12,"template":false,"template_full_name":"mccutchen/go-pkg-template","purl":"pkg:github/mccutchen/ghavm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mccutchen%2Fghavm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mccutchen%2Fghavm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mccutchen%2Fghavm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mccutchen%2Fghavm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mccutchen","download_url":"https://codeload.github.com/mccutchen/ghavm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mccutchen%2Fghavm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266689583,"owners_count":23969143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci","continuous-integration","github-actions","supply-chain"],"created_at":"2025-06-07T14:05:44.710Z","updated_at":"2025-10-24T19:53:24.198Z","avatar_url":"https://github.com/mccutchen.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `ghavm`: the GitHub Actions Version Manager\n\n[![Build status](https://github.com/mccutchen/ghavm/actions/workflows/test.yaml/badge.svg)](https://github.com/mccutchen/ghavm/actions/workflows/test.yaml)\n[![Code coverage](https://codecov.io/gh/mccutchen/ghavm/branch/main/graph/badge.svg)](https://codecov.io/gh/mccutchen/ghavm)\n[![Go report card](http://goreportcard.com/badge/github.com/mccutchen/ghavm)](https://goreportcard.com/report/github.com/mccutchen/ghavm)\n\n`ghavm` is a tool that manages strict SHA hash version pinning and upgrades for\nGitHub Actions workflows, to ease the burden of following a key security best\npractice [as suggested by GitHub][gh-sec-3p]:\n\n\u003e _Pinning an action to a full length commit SHA is currently the only way to\n\u003e use an action as an immutable release. Pinning to a particular SHA helps\n\u003e mitigate the risk of a bad actor adding a backdoor to the action's\n\u003e repository_\n\nSee [Motivations](#motivations) below for more information on the specific\nproblem `ghavm` helps solve, and further reading on properly securing GitHub\nActions workflows.\n\n\n## Installation\n\nThere are a number of ways to install and/or run `ghavm`:\n\n- Install the [latest release][release] from GitHub\n\n- Run as a Docker/OCI image:\n  ```\n  docker run --rm -e GITHUB_TOKEN -v $(PWD):/src ghcr.io/mccutchen/ghavm pin\n  ```\n\n- Run from source using a local Go toolchain:\n  ```\n  go run github.com/mccutchen/ghavm@latest pin\n  ```\n\n\n## Getting started\n\nFirst, you might use `ghavm pin` to **pin your actions to immutable commit\nhashes**, ensuring that they'll run the exact same code every time:\n\n```bash\n$ go run github.com/mccutchen/ghavm@latest pin\n```\n```diff\n--- example.before.yaml\n+++ example.pinned.yaml\n@@ -6,22 +6,22 @@\n   test:\n     runs-on: ubuntu-latest\n     steps:\n-      - uses: actions/setup-go@v3.5.0\n+      - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0\n         with:\n           version: stable\n\n-      - uses: actions/checkout@v4.1.0\n+      - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0\n         with:\n           fetch-depth: 1\n\n-      - uses: golangci/golangci-lint-action@v6.5.0\n+      - uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0\n         with:\n           version: latest\n\n       - name: test\n         run: make testci\n\n-      - uses: codecov/codecov-action@v4.2.0\n+      - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0\n         with:\n           token: ${{ secrets.CODECOV_TOKEN }}\n           fail_ci_if_error: true\n```\n\nEventually, you may need to upgrade your actions to newer releases, which\ncan be a labor-intensive and potentially error-prone process when manually\njuggling long commit hashes.\n\nThe `ghavm upgrade` makes it easy to **upgrade a workflow's actions** to their\nlatest \"compatible\" release or latest available release:\n\n```bash\n$ go run github.com/mccutchen/ghavm@latest upgrade --mode=latest\n```\n```diff\n--- example.pinned.yaml\n+++ example.upgraded.yaml\n@@ -6,22 +6,22 @@\n   test:\n     runs-on: ubuntu-latest\n     steps:\n-      - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0\n+      - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0\n         with:\n           version: stable\n\n-      - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0\n+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n         with:\n           fetch-depth: 1\n\n-      - uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0\n+      - uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0\n         with:\n           version: latest\n\n       - name: test\n         run: make testci\n\n-      - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0\n+      - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3\n         with:\n           token: ${{ secrets.CODECOV_TOKEN }}\n           fail_ci_if_error: true\n```\n\n\u003e [!TIP]\n\u003e The `--exclude` and `--select` flags allow you to limit pinning or upgrading\n\u003e to a subset of the actions in your workflows.\n\u003e\n\u003e **Example:** Pass `--exclude \"actions/*\"` to leave official first-party\n\u003e actions owned by GitHub unpinned.\n\n\n## Usage\n\n```\n$ ghavm --help\n```\n```\nghavm manages version pinning and upgrades for GitHub Actions workflows.\n\nUsage:\n  ghavm [command]\n\nAvailable Commands:\n  list        List current action versions and available upgrades\n  pin         Pin current action versions to immutable commit hashes\n  upgrade     Upgrade and re-pin action versions according to --mode\n\nFlags:\n  -h, --help   help for ghavm\n\nUse \"ghavm [command] --help\" for more information about a command.\n```\n\n\n## Motivations\n\n### Background\n\n- Per the [Using third-party actions][gh-sec-3p] section of GitHub's own\n  [Security Hardening for GitHub Actions][gh-sec] doc:\n\n  \u003e The individual jobs in a workflow can interact with (and compromise) other\n  \u003e jobs. For example, a job querying the environment variables used by a later\n  \u003e job, writing files to a shared directory that a later job processes, or\n  \u003e even more directly by interacting with the Docker socket and inspecting\n  \u003e other running containers and executing commands in them.\n  \u003e\n  \u003e This means that a compromise of a single action within a workflow can be\n  \u003e very significant, as that compromised action would have access to all\n  \u003e secrets configured on your repository, and may be able to use the\n  \u003e GITHUB_TOKEN to write to the repository. Consequently, there is significant\n  \u003e risk in sourcing actions from third-party repositories on GitHub.\n\n  and\n\n  \u003e **Pinning an action to a full length commit SHA is currently the only way\n  \u003e to use an action as an immutable release. Pinning to a particular SHA helps\n  \u003e mitigate the risk of a bad actor adding a backdoor to the action's\n  \u003e repository**, as they would need to generate a SHA-1 collision for a valid\n  \u003e Git object payload. When selecting a SHA, you should verify it is from the\n  \u003e action's repository and not a repository fork.\n\n- See [Pinning GitHub Actions for Enhanced Security: Everything You Should\n  Know][step-sec] from StepSecurity for a good overview of potential attacks\n  enabled by unpinned action versions, plus an walkthrough of various other\n  ways to manage pinned action versions.\n\n- See Wiz's [guide to GitHub Actions security hardening][wiz-sec] for recent\n  concrete examples of high-profile GitHub Actions-based supply chain attacks,\n  some of which may have been mitigated by strictly pinned action versions.\n\n### Strict version pinning is not a panacea\n\nWhile strictly pinning the action versions to immutable commit hashes is a\ncritical step in securing GitHub Actions workflows, it does not perfectly\nmitigate the risks.\n\nIn particular, per [the Wiz hardening guide][wiz-sec]:\n\n\u003e It is important to consider **transitive risk**: even if you hash pin an\n\u003e Action, if it relies on another Action with weaker pinning, you're still\n\u003e exposed.\n\nSo, even when pinning your action versions with `ghavm` or any other tool, it\nis important to continue following best practices, _especially_ when using 3rd\nparty actions not owned by GitHub itself.\n\n### Further reading on security best practices\n\n- GitHub's own [Security hardening for GitHub Actions][gh-sec] guide\n- StepSecurity's [7 GitHub Actions Security Best Practices][step-sec] guide\n- GitGuardian's [GitHub Actions Security Best Practices][gg-sec] guide\n\n\n## Prior art and other tools\n\nThere are a number of other tools offering similar functionality:\n\n- [mheap/pin-github-action][] inspired this project! It offers the same\n  functionality as the `ghavm pin` command, but does not seem to offer the\n  ability to then upgrade pinned versions over time.\n\n- [dependabot][] has native support for managing GitHub Actions versions with\n  the same kind of pinning that this project provides, and can be configured to\n  automatically open pull requests to update those versions over time.\n\n  **Most users should probably consider dependabot instead of `ghavm` to\n  actually automate version-pinned security updates!**\n\n\n## License\n\nMIT\n\n[gh-sec]: https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions\n[gh-sec-3p]: https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions\n[wiz-sec]: https://www.wiz.io/blog/github-actions-security-guide\n[step-sec]: https://www.stepsecurity.io/blog/pinning-github-actions-for-enhanced-security-a-complete-guide\n[gg-sec]: https://blog.gitguardian.com/github-actions-security-cheat-sheet/\n[release]: https://github.com/mccutchen/ghavm/releases/latest\n[mheap/pin-github-action]: https://github.com/mheap/pin-github-action\n[dependabot]: https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories#github-actions\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmccutchen%2Fghavm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmccutchen%2Fghavm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmccutchen%2Fghavm/lists"}