Skip to content
Skillpedia
Security40k · #5168

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

https://github.com/github/awesome-copilot/blob/main/skills/github-actions-hardening/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/github/awesome-copilot/blob/main/skills/github-actions-hardening/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
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-hardening

Or download just the file:

curl -L https://raw.githubusercontent.com/github/awesome-copilot/main/skills/github-actions-hardening/SKILL.md -o SKILL.md
Technical 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, or issue_comment triggers
  • Questions about GITHUB_TOKEN permissions or the permissions: 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 trust
  • pull_request from 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.body
  • github.event.pull_request.title, github.event.pull_request.body, .head.ref, .head.label
  • github.event.comment.body, github.event.review.body
  • github.event.pages.*.page_name, github.event.commits.*.message, github.event.head_commit.*
  • github.head_ref and any github.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) or contents: read, then grant the minimum per job (e.g. pull-requests: write only on the job that comments).
  • Flag any permissions: write-all or broad write scopes 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

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills