Skip to content

Commit 593d703

Browse files
committed
adding guidance on best practices for GitHub Actions
1 parent fc57a17 commit 593d703

File tree

2 files changed

+228
-0
lines changed

2 files changed

+228
-0
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# GitHub Actions Security Best Practices
2+
3+
## Introduction
4+
5+
GitHub Actions is a powerful automation tool that enables CI/CD workflows directly within your GitHub repository. Securing your GitHub Actions workflows is crucial to protect your code, secrets, and infrastructure from potential security threats.
6+
7+
This guide outlines best practices for securing your GitHub Actions workflows and minimizing security risks.
8+
9+
## Table of Contents
10+
- [Secrets Management](#secrets-management)
11+
- [Limiting Permissions](#limiting-permissions)
12+
- [Third-Party Actions](#third-party-actions)
13+
- [Dependency Management](#dependency-management)
14+
- [Runner Security](#runner-security)
15+
- [Pull Request Workflows](#pull-request-workflows)
16+
- [OIDC Integration](#oidc-integration)
17+
- [Audit and Monitoring](#audit-and-monitoring)
18+
19+
## Secrets Management
20+
21+
### Use GitHub Secrets
22+
23+
- Store sensitive data (API tokens, credentials, etc.) as [GitHub Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
24+
- Never hardcode sensitive values in your workflow files
25+
- Do not use structured data as a secret - this can cause GitHubs secret redaction in logs to fail
26+
- Rotate secrets regularly
27+
- Use environment-specific secrets when possible
28+
- Ensure a secret scanner is deployed as part of your workflows
29+
- Public repositories should enable GitHub Secret Scanner and Push Protection
30+
31+
### Minimize Secret Scope
32+
```yaml
33+
# Good practice - limiting secret to specific environment
34+
jobs:
35+
deploy:
36+
environment: production
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v3
40+
- name: Deploy
41+
env:
42+
API_TOKEN: ${{ secrets.API_TOKEN }}
43+
run: ./deploy.sh
44+
```
45+
46+
### Avoid Exposing Secrets in Logs
47+
48+
- Don't echo or print secrets in workflow steps
49+
- Set debug to false when using secrets
50+
- Use masking for any dynamically generated secrets
51+
52+
## Limiting Permissions
53+
54+
### Use Least Privilege Principle
55+
56+
Limit the GitHub token permissions to only what's necessary:
57+
```yaml
58+
permissions:
59+
contents: read
60+
pull-requests: write
61+
issues: write
62+
```
63+
64+
### Use Fine-Grained Tokens
65+
66+
- Create custom GitHub Apps with limited scopes when possible
67+
- Use repository-scoped tokens instead of organization-wide tokens
68+
69+
## Third-Party Actions
70+
71+
While third-party actions can significantly enhance the functionality and efficiency of your workflows, they also introduce potential security risks:
72+
73+
- *Untrusted Code*: Third-party actions are often maintained by external developers. If the code is not reviewed or vetted, it may contain vulnerabilities or malicious code that could compromise your repository or infrastructure.
74+
- *Version Drift*: Using tags like @latest or branch references (e.g., @main) can lead to unexpected changes in behavior if the action is updated. This could introduce breaking changes or vulnerabilities into your workflows.
75+
- *Dependency Vulnerabilities*: Third-party actions may rely on outdated or insecure dependencies, which could expose your workflows to known vulnerabilities.
76+
- *Lack of Maintenance*: Some third-party actions may not be actively maintained, leaving them vulnerable to security issues or compatibility problems with newer GitHub Actions features.
77+
- *Excessive Permissions*: Third-party actions may request more permissions than necessary, potentially exposing sensitive data or allowing unauthorized access to your repository.
78+
79+
To mitigate these risks, always follow best practices, such as pinning actions to specific commit SHAs, reviewing the source code of actions, and using only trusted actions from reputable sources.
80+
81+
### Pin Actions to Specific Versions
82+
83+
Always use specific commit SHAs instead of tags or branches:
84+
85+
```yaml
86+
# Not secure - can change unexpectedly
87+
- uses: actions/checkout@v3
88+
# Better - using a specific version tag
89+
- uses: actions/[email protected]
90+
# Best - using a specific commit SHA
91+
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
92+
```
93+
94+
### Verify Third-Party Actions
95+
96+
- Only use trusted actions from the GitHub Marketplace
97+
- Review the source code of third-party actions before using them
98+
- Consider forking and maintaining your own copy of critical actions
99+
100+
### Use Actions Security Best Practices
101+
102+
- Enable Dependabot alerts for GitHub Actions
103+
- Set up a workflow that regularly checks for outdated actions
104+
105+
## Dependency Management
106+
107+
### Scan Dependencies
108+
109+
- Use dependency scanning tools like GitHub's Dependabot
110+
111+
### Keep Dependencies Updated
112+
113+
- Implement automated dependency updates
114+
- Regularly review and update dependencies with security patches
115+
116+
## Runner Security
117+
118+
### Self-hosted Runner Security
119+
120+
If using self-hosted runners:
121+
122+
- Run them in isolated environments (containers/VMs)
123+
- Regularly update and patch runner machines- Implement proper network isolation- Use ephemeral runners when possible
124+
125+
```yaml
126+
jobs:
127+
build:
128+
runs-on: [self-hosted, isolated]
129+
steps:
130+
# Your workflow steps here
131+
```
132+
133+
### GitHub-hosted Runner Security
134+
135+
- Be aware that GitHub-hosted runners are reset after each job
136+
- Clean up any sensitive data before job completion
137+
- Don't store persistent sensitive data in the runner's environment
138+
139+
## Pull Request Workflows
140+
141+
### Secure Pull Request Workflows
142+
143+
- Don't expose secrets to pull request workflows from forks
144+
- Use `pull_request_target` carefully with read-only permissions
145+
146+
```yaml
147+
# Safer approach for PR workflows
148+
on:
149+
pull_request:
150+
jobs:
151+
test:
152+
runs-on: ubuntu-latest
153+
permissions:
154+
contents: read
155+
steps:
156+
- uses: actions/checkout@v3
157+
- name: Run tests
158+
run: npm test
159+
```
160+
161+
### Implement Required Reviews
162+
163+
- Enforce branch protection rules
164+
- Require code reviews before merging
165+
- Use status checks to enforce security scans
166+
167+
## OIDC Integration
168+
169+
### Use OpenID Connect for Cloud Providers
170+
171+
Instead of storing long-lived cloud credentials, use GitHub's OIDC provider:
172+
173+
```yaml
174+
jobs:
175+
deploy:
176+
runs-on: ubuntu-latest
177+
permissions:
178+
id-token: write
179+
contents: read
180+
steps:
181+
- uses: actions/checkout@v3
182+
- name: Configure AWS credentials
183+
uses: aws-actions/configure-aws-credentials@v1
184+
with:
185+
role-to-assume: arn:aws:iam::123456789012:role/github-actions
186+
aws-region: eu-west-2
187+
```
188+
189+
### Limit OIDC Token Claims
190+
191+
- Set specific subject claims in your cloud provider
192+
- Implement additional claim conditions (repository, branch, environment)
193+
194+
## Audit and Monitoring
195+
196+
### Enable Audit Logging
197+
198+
- Monitor GitHub Actions usage via audit logs
199+
- Set up alerts for suspicious activity
200+
201+
### Review Workflow Changes
202+
203+
- Enforce code reviews for workflow file changes
204+
- Use CODEOWNERS to restrict who can modify workflow files
205+
206+
```
207+
# CODEOWNERS file/.github/workflows/ @security-team
208+
```
209+
210+
### Regular Security Reviews
211+
212+
- Conduct regular reviews of all workflows
213+
- Update security practices based on emerging threats
214+
- Monitor GitHub security advisories
215+
216+
## Additional Resources
217+
218+
- [GitHub Actions Security Hardening Guide](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)
219+
- [GitHub Security Lab](https://securitylab.github.com/)
220+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
221+
- [Security for GitHub Actions](https://docs.github.com/en/actions/security-for-github-actions)
222+
223+
## Conclusion
224+
225+
Securing GitHub Actions requires a multi-layered approach focusing on secrets management, permissions, third-party action vetting, and proper configuration. By following these best practices, you can significantly reduce security risks while still enjoying the full benefits of GitHub Actions automation.
226+
227+
Remember that security is an ongoing process - regularly review and update your security practices to adapt to new threats and challenges.

practices/security.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ The remainder of this page gives more detailed and specific recommendations to b
137137
- Secure **CI/CD**
138138
- Robust authentication and minimum privileges
139139
- Prefer ambient IAM credentials over retrieving credentials from secrets management. Do not store credentials in the plain.
140+
- If using GitHub Actions follow the [Best Practices outlined here](./actions-best-practices.md)
140141
- **Enforce** infrastructure security (e.g. [Azure Policy](https://docs.microsoft.com/en-us/azure/governance/policy/overview), [AWS Config](https://aws.amazon.com/config/)) and validate it (e.g. [ScoutSuite](https://github.com/nccgroup/ScoutSuite/blob/master/README.md))
141142

142143
<details><summary>Example IAM policy fragment to prevent unencrypted RDS databases (click to expand)</summary>

0 commit comments

Comments
 (0)