|
| 1 | +# ADR 1396308b-0814-47bd-b8fc-6b3965d31295: GitHub Actions - to pin or not to pin |
| 2 | + |
| 3 | +## Status |
| 4 | + |
| 5 | +Proposed <!-- [Proposed | Accepted | Deprecated] --> |
| 6 | + |
| 7 | +## Submitters |
| 8 | + |
| 9 | +- @ctcpip |
| 10 | + |
| 11 | +## Decision Owners |
| 12 | + |
| 13 | +- @expressjs/express-tc |
| 14 | + |
| 15 | +## Context |
| 16 | + |
| 17 | +GitHub Actions support referencing actions via: |
| 18 | + |
| 19 | +- Semantic versions (e.g., `actions/setup-node@v4`) |
| 20 | +- Specific commit hashes (e.g., `actions/setup-node@49933ea`) |
| 21 | +- Branch references (e.g., `actions/setup-node@main`) |
| 22 | + |
| 23 | +Tools like [OpenSSF Scorecard](https://github.com/ossf/scorecard) recommend pinning to commit hashes to guarantee supply chain integrity and reduce the risk of malicious updates. However, GitHub's own documentation states: |
| 24 | + |
| 25 | +> "All options are a tradeoff between guaranteed supply chain integrity and auto-patching of vulnerabilities in dependencies." |
| 26 | +
|
| 27 | +Therefore, there is no perfect solution; only pros and cons depending on which choice is made. |
| 28 | + |
| 29 | +A recent discussion raised valid concerns about the real-world security value of pinning, particularly: |
| 30 | + |
| 31 | +- **Pinning disables automatic updates**, including security patches, unless maintained manually. |
| 32 | +- **Commit hashes are opaque**, harder to audit, and easy to misuse (e.g., referencing a malicious fork). |
| 33 | +- **Most CI workflows in our repos don't access secrets**, minimizing risk even in the event of compromise. |
| 34 | + |
| 35 | +Additionally, human verification of pinned commits, especially across many repos, can be error-prone or inconsistent. |
| 36 | + |
| 37 | +## Decision |
| 38 | + |
| 39 | +We will **not require pinning GitHub Actions to commit hashes** across all repositories. |
| 40 | + |
| 41 | +Instead: |
| 42 | + |
| 43 | +- Use **semantic version tags** (e.g., `@v4`) by default. |
| 44 | +- Do **not use `@main` or other floating branch refs**. |
| 45 | +- Repositories should **enable Dependabot for GitHub Actions** and set `schedule/interval` to a reasonable value, such as `monthly`. |
| 46 | +- For workflows that **access secrets, publish artifacts, or have privileged scopes**, repository maintainers **may** choose to pin to commit hashes **if justified**. |
| 47 | +- Where pinning is used: |
| 48 | + - A reviewer **must manually verify** the commit hash belongs to the correct source repository. |
| 49 | + - The verification step **must be noted in the PR review** to ensure accountability. |
| 50 | + |
| 51 | +## Consequences |
| 52 | + |
| 53 | +- **Improved maintainability**: Semantic versions reduce the burden of keeping commit hashes up to date. |
| 54 | +- **Timely security updates**: Using version tags with Dependabot allows faster adoption of upstream patches. |
| 55 | +- **Acknowledged risk**: While this approach reduces supply chain guarantees, the practical risk profile of most of our workflows does not justify the burden of pinning. |
| 56 | +- **Flexibility for maintainers**: Projects/workflows with higher sensitivity can still opt into pinning where warranted. |
| 57 | + |
| 58 | +## References |
| 59 | + |
| 60 | +[Keeping your GitHub Actions and workflows secure](https://securitylab.github.com/resources/github-actions-building-blocks/) |
| 61 | +[Mitigating Attack Vectors in GitHub Workflows](https://openssf.org/blog/2024/08/12/mitigating-attack-vectors-in-github-workflows/) |
0 commit comments