Best Practices for Securing GitHub Actions Workflows
GitHub Actions is a powerful automation tool for CI/CD, but without proper security measures, it can become a serious risk. Attackers can exploit misconfigured workflows, leak secrets, or introduce supply chain vulnerabilities. In this guide, we’ll walk through the best practices to secure your GitHub Actions workflows and prevent security threats.
1. Protect Your Secrets
Secrets such as API keys, cloud credentials, and tokens should never be exposed in your workflow logs. Instead, use GitHub’s built-in Secrets Management:
- Store secrets in GitHub Secrets (
Settings → Secrets and Variables → Actions
). - Never echo secrets in logs or print them in your workflow.
- Use
secrets.GITHUB_TOKEN
with minimal permissions. - Use environment variables to prevent hardcoding secrets.
Example:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
run: some-deploy-command
env:
API_KEY: ${{ secrets.API_KEY }}
2. Limit Permissions for Workflows
By default, GitHub Actions runs with broad repository permissions. You should restrict permissions at the workflow or job level to enforce the principle of least privilege.
Restricting workflow permissions
permissions:
contents: read
id-token: write # Required for OpenID Connect authentication
Limiting job-specific permissions
jobs:
deploy:
permissions:
contents: read
packages: write
Why This Matters
Limiting permissions prevents unauthorized modifications to repository contents, releases, and workflow files, reducing the risk of repository takeovers.
3. Use OpenID Connect (OIDC) for Authentication
Instead of storing long-lived cloud credentials in GitHub Secrets, use OIDC to securely authenticate with AWS, Azure, or Google Cloud.
Benefits of OIDC
- No need to store static secrets.
- Works with identity providers for federated authentication.
- Reduces the risk of credential leaks.
Example for AWS OIDC Authentication:
permissions:
id-token: write
contents: read
Then, configure AWS IAM roles to trust GitHub’s OIDC provider.
4. Pin Actions to a Specific Commit SHA
Many workflows reference actions using tags like @v1
, which can be updated unexpectedly. Instead, pin actions to a commit SHA to prevent supply chain attacks.
Less secure:
uses: actions/checkout@v4
More secure:
uses: actions/checkout@d3f4b9e6a12345b6c7890123def56789abcdef01
Pinning actions ensures that your workflows use a verified and tested version, protecting against malicious updates.
5. Validate Pull Requests
GitHub Actions workflows triggered by pull_request_target
can be exploited if an attacker modifies the workflow in a forked PR.
Best Practices to Secure PR Workflows:
- Run workflows only for trusted repository contributors.
- Require code reviews before running PR-triggered workflows.
- Ensure PRs from forks have limited access.
Example Security Check:
jobs:
check:
if: github.event.pull_request.head.repo.fork == false
This ensures that workflows run only for trusted repository contributors.
6. Scan Dependencies for Vulnerabilities
Third-party dependencies can introduce security risks. Enable GitHub Dependabot for automatic security alerts and updates. Additionally, integrate third-party scanners to detect vulnerabilities.
Example using Trivy:
uses: aquasecurity/trivy-action@master
Recommended Security Tools:
- Dependabot – Automatically updates dependencies.
- Trivy – Scans container images and dependencies for vulnerabilities.
- Snyk – Monitors and fixes security issues in dependencies.
- GitHub CodeQL – Performs deep security analysis on code.
7. Secure Self-Hosted Runners
Self-hosted runners provide more flexibility but introduce security risks if not properly configured.
Security Best Practices for Self-Hosted Runners:
- Run them in an isolated environment (e.g., dedicated VM or container).
- Ensure ephemeral runners to avoid long-lived access.
- Restrict repository access.
- Regularly update the runner software.
- Use firewall rules to limit network exposure.
8. Restrict Workflow Triggers
Avoid running workflows automatically for arbitrary user inputs, which can lead to event injection attacks.
Instead of triggering on every push, limit workflow execution to specific branches and trusted actors:
on:
push:
branches:
- main
Additional Security Steps:
- Use
workflow_dispatch
for manual approvals. - Require specific labels for PR-triggered workflows.
- Implement branch protection rules.
9. Monitor and Audit Logs
GitHub provides audit logs to track workflow execution and changes. Regularly review them to detect suspicious activity.
Enable CodeQL for security analysis:
uses: github/codeql-action/analyze@v2
Additional Recommendations:
- Use GitHub Security Dashboard to track vulnerabilities.
- Integrate security logging with SIEM tools.
- Enable GitHub Advanced Security for deeper insights.
10. Limit Artifact Exposure
Artifacts contain sensitive build outputs, so they should be properly managed to prevent unauthorized access.
Secure Artifact Storage:
steps:
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: build-output
retention-days: 7 # Limits exposure
Additional Measures:
- Encrypt sensitive artifacts before uploading.
- Restrict artifact access using GitHub’s permissions settings.
- Use self-hosted storage for highly sensitive builds.
Conclusion
Securing GitHub Actions requires a combination of least privilege access, secret management, and dependency security. By following these best practices, you can significantly reduce the risk of supply chain attacks and unauthorized access.
Key Takeaways:
✔ Store secrets securely in GitHub Secrets. ✔ Restrict permissions at workflow and job levels. ✔ Use OIDC instead of long-lived credentials. ✔ Pin dependencies and actions to commit SHAs. ✔ Validate pull requests to prevent malicious code execution. ✔ Use security tools like Dependabot, Trivy, and CodeQL. ✔ Restrict workflow triggers to trusted sources. ✔ Monitor audit logs and integrate with SIEM tools. ✔ Limit artifact exposure with short retention periods.
By implementing these security best practices, you can safeguard your GitHub Actions workflows from threats and ensure secure CI/CD pipelines.