|
1 | 1 | --- |
2 | 2 | # SPDX-FileCopyrightText: GitHub and The Project Authors |
3 | 3 | # SPDX-License-Identifier: MIT |
4 | | -draft: false # Set to false when ready to publish |
| 4 | +draft: true # Set to false when ready to publish |
5 | 5 | title: 'Securing GitHub Actions Workflows' |
6 | 6 | publishDate: 2024-08-16 |
7 | 7 | params: |
8 | | - authors: [{ name: 'Greg Mohler', handle: 'callmegreg' }, { name: 'Kitty Chiu', handle: 'kittychiu' }] |
| 8 | + authors: [{ name: 'Greg Mohler', handle: 'callmegreg' }, { name: 'Kitty Chiu', handle: 'kittychiu' }, { name: 'Thomas Sjögren', handle: 'konstruktoid' }] |
9 | 9 |
|
10 | 10 | # Classifications of the framework to drive key concepts, design principles, and architectural best practices |
11 | 11 | pillars: |
@@ -90,6 +90,7 @@ To secure GitHub Actions workflows, consider the following strategies: |
90 | 90 | 10. **Use `head.sha` instead of `head.ref`**: Where possible, reference by commit SHA instead of a user-provided branch name or tag (ref), especially in sensitive contexts (such as `run` steps). If require, use environment variable to store `head.ref` and reference it to prevent injection attack. |
91 | 91 | 11. **Use caution with public repositories**: Anyone can suggest changes to public repositories. Review workflow triggers, and never use self-hosted runners with public repositories. |
92 | 92 | 12. **Restrict allowed actions**: Use the [*Allow enterprise, and select non-enterprise, actions and reusable workflows*](https://docs.github.com/en/enterprise-cloud@latest/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#controlling-access-to-public-actions-and-reusable-workflows) setting to control which actions can run. |
| 93 | +13. **Segregate runners**: Use runner groups and labels to separate high-privilege runners (with access to secrets, sensitive resources or host access) from low-privilege runners. |
93 | 94 |
|
94 | 95 | ## Assumptions and preconditions |
95 | 96 |
|
@@ -126,6 +127,7 @@ Repository rulesets provide a strong defensive layer that complements workflow-l |
126 | 127 | - [Require status checks to pass before merging](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-status-checks-to-pass-before-merging): Ensure automated validation checks pass before merging. |
127 | 128 | - [Require code scanning results](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-code-scanning-results): Identify security vulnerabilities before merge. |
128 | 129 | - [Require signed commits](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-signed-commits): Ensure all commits are signed to prove who authored them and that they haven't been modified. |
| 130 | +- [Require workflows to pass before merging](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-workflows-to-pass-before-merging): Ensure organizational or enterprise-level requirements for workflows are met before merging. This could be a workflow that checks for required labels, validates commit messages, or performs other organizational policy checks. |
129 | 131 | - Restrict bypass permissions: Limit bypass capabilities to emergencies and monitor via audit logs. |
130 | 132 |
|
131 | 133 | ### Implement least privilege for workflow permissions |
@@ -257,6 +259,18 @@ The [allowed actions and reusable workflows setting](https://docs.github.com/en/ |
257 | 259 |
|
258 | 260 | Consider defining the list of allowed actions using policy as code (e.g., via Terraform or the REST API) to establish a request/approval process, track changes for audit purposes, and improve visibility into which actions are allowed. |
259 | 261 |
|
| 262 | +### Segregate runners |
| 263 | + |
| 264 | +Use [runner groups](https://docs.github.com/en/actions/concepts/runners/runner-groups) and [labels](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/apply-labels) to separate high-privilege runners from low-privilege runners. High-privilege runners may have access to sensitive resources or direct host access, while low-privilege runners should not. |
| 265 | + |
| 266 | +This separation provides more granular control over [which repositories can access different runners](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/manage-access#changing-which-repositories-can-access-a-runner-group) and which [jobs can access specific runners](https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job). It also reduces the risk that a compromised or misconfigured workflow could gain access to sensitive resources. |
| 267 | + |
| 268 | +For example, you could create: |
| 269 | + |
| 270 | +- A runner group for container image build runners, limited to only the repositories that require those privileges. |
| 271 | +- A runner group for runners with access to restricted networks. |
| 272 | +- A separate low-privilege runner group for tasks such as linting and static analysis, with no access to secrets or sensitive resources. |
| 273 | + |
260 | 274 | ## Additional solution detail and trade-offs to consider |
261 | 275 |
|
262 | 276 | ### Pinning actions based on a version tag |
|
0 commit comments