securing-github-actions-workflows
Hardens GitHub Actions workflows against attacks. Protects secrets and restricts permissions to prevent security risks.
What it does
This feature helps protect your automated workflows (called GitHub Actions) from attacks. It ensures that the tools used are always the same specific versions and that the permissions given to them are the minimum necessary to function, preventing malicious code from being executed.
When to use it
- ✓When your workflows handle sensitive information (secrets).
- ✓When your workflows deploy code to production.
- ✓When you want to prevent changes in branch names or Pull Request titles from causing security issues.
Example of what to ask your AI
“How can I secure my GitHub Actions workflows against attacks?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
It works by verifying that external tools used in your workflows are pinned to specific versions (using a unique code called SHA) and by limiting the permissions the main GitHub Actions token has. It also prevents information from outside (like PR titles) from being used insecurely in commands.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill securing-github-actions-workflowsOr download just the file:
curl -L https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/main/skills/securing-github-actions-workflows/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Securing GitHub Actions Workflows
When to Use
- When GitHub Actions is the CI/CD platform and workflows need hardening against supply chain attacks
- When workflows handle secrets, deploy to production, or have elevated permissions
- When preventing script injection via untrusted PR titles, branch names, or commit messages
- When requiring audit trails and approval gates for workflow modifications
- When third-party actions pose supply chain risk through mutable version tags
Do not use for securing other CI/CD platforms (see platform-specific hardening guides), for application vulnerability scanning (use SAST/DAST), or for secret detection in code (use Gitleaks).
Prerequisites
- GitHub repository with GitHub Actions enabled
- GitHub organization admin access for organization-level settings
- Understanding of GitHub Actions workflow syntax and events
Workflow
Step 1: Pin Actions to SHA Digests
# INSECURE: Mutable tag can be overwritten by attacker
- uses: actions/checkout@v4
# SECURE: Pinned to immutable SHA digest
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Use Dependabot to auto-update pinned SHAs
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
Step 2: Minimize GITHUB_TOKEN Permissions
# Set restrictive default permissions at workflow level
name: CI Pipeline
permissions: {} # Start with no permissions
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read # Only what's needed
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
permissions:
contents: read
deployments: write
id-token: write # For OIDC-based cloud auth
steps:
- name: Deploy
run: echo "deploying"
Step 3: Prevent Script Injection
# VULNERABLE: User-controlled input in run step
- run: echo "PR title is ${{ github.event.pull_request.title }}"
# SECURE: Use environment variable (properly escaped by shell)
- name: Process PR
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
echo "PR title is ${PR_TITLE}"
echo "PR body is ${PR_BODY}"
# SECURE: Use actions/github-script for complex operations
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
with:
script: |
const title = context.payload.pull_request.title;
console.log(`PR title: ${title}`);
Step 4: Secure Fork Pull Request Handling
# DANGEROUS: pull_request_target runs with base repo permissions
# on: pull_request_target # AVOID unless absolutely necessary
# SAFE: pull_request runs in fork context with limited permissions
on:
pull_request:
branches: [main]
# If pull_request_target is required, never checkout PR code:
on:
pull_request_target:
types: [labeled]
jobs:
safe-job:
if: contains(github.event.pull_request.labels.*.name, 'safe-to-test')
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# NEVER do: actions/checkout with ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# This checks out the BASE branch, not the PR
Step 5: Protect Secrets and Environment Variables
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Requires approval
steps:
- name: Deploy with secret
env:
# Secrets are masked in logs automatically
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
# Never echo secrets
# echo "$DEPLOY_KEY" # BAD
deploy-tool --key-file <(echo "$DEPLOY_KEY")
- name: Audit secret access
run: |
# Log that secret was used without exposing it
echo "::notice::Deploy key accessed for production deployment"
Step 6: Implement Workflow Change Controls
# Require CODEOWNERS approval for workflow changes
# .github/CODEOWNERS
.github/workflows/ @security-team @platform-team
.github/actions/ @security-team @platform-team
# Organization settings:
# 1. Settings > Actions > General > Fork PR policies
…
FAQ
What is 'pinning actions to SHA digests'?
It means using a unique, unchangeable code (SHA) to identify a specific version of an external tool, instead of using a version name that could be altered by an attacker.
Why is it important to limit GITHUB_TOKEN permissions?
The GITHUB_TOKEN is an access key that GitHub Actions uses. Limiting its permissions means that even if an attacker gains access to it, the damage they can cause will be smaller, as they will only be able to do what is strictly necessary.
What is 'script injection' and how is it prevented?
It's an attack where untrusted information (like a Pull Request title) is inserted into a command. This is prevented by ensuring this information is treated as text, not executable code, or by using secure tools to process it.
Details
Original description by the author
Hardens GitHub Actions workflows against supply chain attacks, credential theft, and privilege escalation: pinning actions to SHA digests, minimizing GITHUB_TOKEN permissions, protecting secrets, preventing script injection in workflow expressions, and requiring reviewers for workflow changes. Use when hardening GitHub Actions workflows that handle secrets, deploy to production, or run with elevat
Popularity
- GitHub stars
- 35k
- Ranking position
- #6207
- License
- Apache-2.0
- Updated
- 8/31/2026
Comments
- …
More skills from this repository
abusing-dpapi-for-credential-access
Gives your AI agent ready-made instructions for a specific task, so it does it better and faster.
mukul975/Anthropic-Cybersecurity-Skills
abusing-shadow-credentials-for-privesc
Teaches your AI agent to write clear, well-structured text.
mukul975/Anthropic-Cybersecurity-Skills
achieving-cmmc-level-2-compliance
Helps your agent prepare an environment for CMMC Level 2 compliance. It implements security requirements and manages necessary documentation.
mukul975/Anthropic-Cybersecurity-Skills
acquiring-disk-image-with-dd-and-dcfldd
Helps your agent create exact copies of hard drives. This is useful for ensuring no information is lost or altered during investigations.
mukul975/Anthropic-Cybersecurity-Skills
Similar skills
dashboard-builder
Helps your agent create useful monitoring dashboards. It turns data into charts that answer important system questions.
affaan-m/ECC
dev-team
Simulates a collaborative development team where different roles respond to a problem together. It's useful for getting multiple perspectives without manually switching agents.
affaan-m/ECC
ecc-council
Has your agent convene a four-voice council for difficult decisions. It's useful when there are multiple good options and debate is needed before choosing.
affaan-m/ECC