github-actions-hardening
Helps your agent review the security of code automation workflows. It identifies risks that common tools miss, like malicious code injection.
What it does
This tool reviews the security of GitHub Actions automation files. It checks for specific risks that common security tools miss, like code injection and the use of dangerous permissions.
When to use it
- ✓When asked to review the security of a GitHub Actions automation file.
- ✓When creating a new automation and wanting to ensure it's secure from the start.
- ✓When an automation uses triggers that can be activated by external code.
Example of what to ask your AI
“Review the security of this GitHub Actions workflow file: [paste code here]”
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
The tool analyzes the automation's triggers to understand who can start it and with what permissions. It then looks for places where external data could be inserted directly into commands, which can be dangerous.
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 github/awesome-copilot --skill github-actions-hardeningOr download just the file:
curl -L https://raw.githubusercontent.com/github/awesome-copilot/main/skills/github-actions-hardening/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
GitHub Actions Hardening
A focused security reviewer for GitHub Actions workflows. It reasons about the Actions-specific
threat model — where trust boundaries live in trigger types, token scopes, and string
interpolation — rather than the application-code vulnerabilities a general security scanner looks
for. Most workflow risks are invisible to language linters because the dangerous code is the YAML
itself and the way GitHub expands ${{ }} expressions into a shell before your script runs.
When to Use This Skill
Use this skill when the request involves:
- Reviewing, auditing, or hardening any file under
.github/workflows/ - Authoring a new workflow and wanting it secure by default
- A workflow that uses
pull_request_target,workflow_run, orissue_commenttriggers - Questions about
GITHUB_TOKENpermissions or thepermissions:key - Pinning actions to commit SHAs vs tags vs branches
- Handling untrusted input (issue titles, PR bodies, branch names, commit messages) in
run:steps - OIDC / cloud authentication from Actions, or secret handling in CI
- Self-hosted runners on public repositories
- Any request like "is this workflow safe?", "secure my CI", or "review this GitHub Action"
The Core Insight
In a workflow, ${{ <expr> }} is expanded by the runner into the script before the shell
executes it. So a step like:
- run: echo "Title: ${{ github.event.issue.title }}"
is not passing a variable — it is pasting attacker-controlled text directly into your shell
command. An issue titled "; <attacker-command> # is concatenated into the script and executed.
This single mechanism is the most common real-world Actions vulnerability, and models routinely
generate it. Treat every
${{ }} that contains data an outside contributor can influence as a code-injection sink.
Execution Workflow
Follow these steps in order for every workflow reviewed.
Step 1 — Map the Triggers and Trust Level
Read every on: trigger and classify the workflow's privilege:
push,pull_request(from same repo) → runs with the contributor's own trustpull_requestfrom a fork → runs with a read-only token, no secrets (safe by design)pull_request_target,workflow_run,issue_comment,issues→ run in the context of the base repository with a read/write token and full access to secrets, but can be triggered by outside contributors. These are the dangerous triggers.
Read references/triggers-and-privilege.md for the full trust matrix.
Step 2 — Hunt for Script Injection
For every run: block, every script: in actions/github-script, and every input to a custom
action, list the ${{ }} expressions and check whether any resolve to attacker-controllable data.
High-risk contexts include:
github.event.issue.title,github.event.issue.bodygithub.event.pull_request.title,github.event.pull_request.body,.head.ref,.head.labelgithub.event.comment.body,github.event.review.bodygithub.event.pages.*.page_name,github.event.commits.*.message,github.event.head_commit.*github.head_refand anygithub.event.*field a fork author can set
Read references/injection.md for the complete sink list and the safe-pattern fixes.
Step 3 — Check Privileged Triggers Don't Execute Untrusted Code
If a pull_request_target or workflow_run workflow checks out PR/fork code
(ref: ${{ github.event.pull_request.head.sha }}) and then runs it (build, test, install
scripts, npm install with lifecycle scripts, etc.), that is remote code execution against a
privileged token. Flag it as CRITICAL. The safe pattern is to split into two workflows: an
unprivileged pull_request workflow that runs the untrusted code, and a privileged
workflow_run workflow that only consumes its results.
Step 4 — Audit permissions:
- If there is no
permissions:block, the workflow inherits the repository default, which may be read/write to everything. Flag it. - Recommend a top-level
permissions: {}(deny-all) orcontents: read, then grant the minimum per job (e.g.pull-requests: writeonly on the job that comments). - Flag any
permissions: write-allor broadwritescopes that the steps don't actually need.
Read references/permissions-and-tokens.md for the per-scope guidance and OIDC setup.
Step 5 — Audit Action References (Supply Chain)
For every uses::
…
FAQ
What are 'privileged triggers'?
These are events that start the automation and can be triggered by people outside your project, like in 'pull requests' from projects you don't control. They might have access to sensitive information.
What is 'script injection' in this context?
It's when malicious code is inserted into a field the automation uses, like a 'pull request' title, and that code is executed as if it were part of your automation.
Why use a 'commit SHA' instead of a 'tag' or 'branch' to reference actions?
Tags and branches can be changed after they are created. Using a 'commit SHA' (a unique, fixed identifier) ensures you always use the exact version of the action that was reviewed, preventing it from being replaced with a malicious version.
Details
Original description by the author
Security hardening reviewer for GitHub Actions workflow files (.github/workflows/*.yml). Reasons about the Actions threat model that pattern matchers and general code linters miss — untrusted-input script injection, privileged triggers running fork code, mutable action references, and over-scoped tokens. Use this skill when asked to review, audit, harden, or secure a GitHub Actions workflow, when
repo: github/awesome-copilot
Popularity
- GitHub stars
- 40k
- Ranking position
- #5168
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
acquire-codebase-knowledge
Helps your agent understand and document an existing code project. It's useful for onboarding new people or getting an overview of the architecture.
github/awesome-copilot
acreadiness-assess
Enables your agent to assess a project's readiness for AI and generate a report. It's useful for understanding how well a project is prepared to use AI tools.
github/awesome-copilot
acreadiness-generate-instructions
Helps your agent create instructions for AI tools based on an assessment. It's useful for improving how AI interacts with code and closing identified gaps.
github/awesome-copilot
acreadiness-policy
Enables your agent to help define or apply policies for AI project assessment. It's useful for standardizing how projects are evaluated and ensuring compliance.
github/awesome-copilot
Similar skills
django-security
Helps your agent implement security practices in Django applications. It focuses on authentication, authorization, and prevention against common attacks, ensuring more secure code.
affaan-m/ECC
laravel-security
Helps your agent secure Laravel applications against threats. Implements security practices for authentication, authorization, and common attack prevention.
affaan-m/ECC
module-regression
Helps your agent manage changes in large projects. Ensures code changes in one part don't break other parts.
affaan-m/ECC