Full Report
Build resilient GitHub Actions workflows with lessons from recent attacks.
Analysis Summary
# Best Practices: Securing GitHub Actions
## Overview
These practices address the security risks associated with GitHub Actions, focusing on hardening the GitHub environment, managing permissions, controlling third-party dependencies, and securing runner infrastructure to prevent supply chain attacks and unauthorized access/data leakage.
## Key Recommendations
### Immediate Actions
1. **Set Default Workflow Permissions to Read-Only:** Immediately configure organization-level settings to ensure that the default Workflow Token Permissions are set to **read-only**, restricting the ability of workflows to unintentionally or maliciously modify repositories.
2. **Audit and Restrict Third-Party Actions Usage:** Implement controls to limit Workflows to using only **verified Actions** from trusted sources (Actions created by GitHub or verified creators in the Marketplace).
### Short-term Improvements (1-3 months)
1. **Implement an Action Allowlist:** For enhanced control, enforce an organization/repository allowlist specifying exactly which Marketplace and custom Actions are permitted to run, overriding default verification status if needed.
2. **Adopt OIDC for Downstream Integration:** Transition away from long-lived secrets when connecting Workflows to downstream cloud providers or systems by implementing **OpenID Connect (OIDC)** for token-based, short-lived authentication.
3. **Harden Self-Hosted Runners:** If self-hosted runners are used, immediately treat them as sensitive production infrastructure. This includes implementing process monitoring, logging activity, and inspecting behavior for signs of compromise.
4. **Audit High-Privilege Triggers and Payloads:** Conduct a specific audit of all Workflows triggered by external events (e.g., pull requests from forks) or those that run with highly elevated privileges, as these are primary targets for Poisoned Pipeline Execution.
### Long-term Strategy (3+ months)
1. **Enforce Pinning for Workflow Dependencies (Hash Pinning):** For all necessary third-party Actions, move beyond referencing by tag (e.g., `@v1`) to referencing by specific commit SHA (hash pinning) to prevent dependency confusion or malicious substitution of dependencies.
2. **Isolate Self-Hosted Runners:** Ensure that self-hosted runners are *never* used with public repositories due to the risk of executing untrusted code from forks. For private repositories, rigorously isolate runners where possible.
3. **Minimize Runner Persistence:** Standardize on ephemeral infrastructure for runners that tears down immediately after each Job execution to minimize any opportunity for an attacker to establish persistence on the build environment.
4. **Implement Egress Control on Runners:** Configure network security around runners to strictly limit outbound connections, allowing only connections to necessary and trusted destinations.
## Implementation Guidance
### For Small Organizations
- **Prioritize Default Permissions:** Focus primarily on enforcing **Read-Only** default workflow permissions organization-wide.
- **Manual Review:** Manually review the `uses:` statements in all existing Workflows to identify and flag any unverified or low-trust third-party Actions.
- **Use Marketplace Verified Actions:** Stick to well-known, verified Actions from the GitHub Marketplace until more mature governance tooling can be adopted.
### For Medium Organizations
- **Use Policy Enforcement Tools:** Deploy a tool like OpenSSF's **Allstar** to programmatically set and enforce security policies across multiple repositories (e.g., requiring branch protection rules or restricting Action usage).
- **Pilot OIDC Adoption:** Select one critical integration (e.g., deployment to staging cloud environment) and fully migrate its secrets reliance to OIDC.
- **Runner Segmentation:** Begin segmenting self-hosted runners based on the sensitivity of the code they interact with.
### For Large Enterprises
- **Mandatory Hash Pinning:** Implement a mandatory policy leveraging repository scanning or App checks (like Allstar) to ensure all non-GitHub-owned Actions references are pinned to specific SHAs.
- **Zero Trust Runner Environment:** Treat all self-hosted runners as untrusted execution environments. Implement advanced monitoring (process inspection, deep logging) and utilize hardened, ephemeral containerized environments.
- **Automated Static Analysis:** Integrate static analysis tools like **zizmor** into pre-commit or CI checks to continuously scan Workflows for known misconfigurations before deployment.
## Configuration Examples
*Since the context provided high-level security principles but did not include specific YAML or CLI commands, the following is conceptual based on best practices cited:*
| Security Control | Actionable Configuration Focus |
| :--- | :--- |
| **Token Permissions** | Set `permissions: write-token: read-only` at the repository or organization level. |
| **Action Sourcing** | Configure organization settings to restrict actions to an 'Allowlist' containing only SHAs or verified publishers. |
| **Secret Management** | Replace environment variables holding long-lived cloud credentials (`AWS_ACCESS_KEY_ID`, etc.) with configurations relying on OIDC workflow identity federation. |
## Compliance Alignment
- **NIST SP 800-204A/B:** Aligns with recommendations for securing supply chain pipelines and runner environments.
- **ISO/IEC 27002:** Addresses controls related to secure development policies and management of technical vulnerabilities (especially the principle of least privilege in relation to token permissions).
- **CIS Benchmarks for GitHub:** Directly addresses hardening organization-level settings, particularly regarding default permissions and external dependency control.
## Common Pitfalls to Avoid
- **Granting Overly Broad Permissions:** Do not accept the default **read-write** token permissions; this is the single easiest way to allow malicious workflow modifications.
- **Using Untrusted/Unpinned Actions:** Importing actions without reviewing their source or referencing them only by major version tag (e.g., `@v1`) exposes the pipeline to dependency manipulation.
- **Running Sensitive Workflows on Public Runners:** Never allow self-hosted runners to execute code from untrusted sources like forks in public repositories.
- **Ignoring High-Privilege Triggers:** Over-relying on automatically-executing Workflows tied to sensitive events (like merges to main or PRs from non-collaborators) without verification steps.
## Resources
- **Static Analysis Tool:** [zizmor](https://github.com/woodruffw/zizmor) (for checking misconfigurations).
- **Policy Enforcement Tool:** [allstar](https://github.com/ossf/allstar) (by OpenSSF, for enforcing organizational policies).
- **Attack Analysis Tools:** [gato](https://github.com/praetorian-inc/gato) and [Gato-X](https://github.com/AdnaneKhan/Gato-X) (for enumeration and attack simulation analysis).
- **Reference Documentation:** Review GitHub’s first-party guidance on security hardening for GitHub Actions.