Reviews GitHub Actions workflows for supply chain risks: enforces SHA pinning, rates third-party actions, scopes permissions, checks triggers and inputs, and recommends updates.
npx claudepluginhub habitat-thinking/ai-literacy-superpowers --plugin ai-literacy-superpowersThis skill uses the workspace's default tool permissions.
GitHub Actions workflows run arbitrary code with access to repository secrets and a `GITHUB_TOKEN`. A compromised or repointed action is indistinguishable from a legitimate one — the attack lands silently in your CI logs. This skill provides a structured checklist for assessing and hardening Actions supply chain risk.
Hardens GitHub Actions workflows against supply chain attacks, credential theft, and privilege escalation by pinning actions to SHA digests, minimizing GITHUB_TOKEN permissions, preventing script injection, and adding reviewer gates.
Hardens GitHub Actions workflows against supply chain attacks, credential theft, and privilege escalation by pinning actions to SHAs, minimizing GITHUB_TOKEN permissions, preventing script injection, and requiring reviewers.
Reviews GitHub Actions workflows for external attacker vulnerabilities like pwn requests, expression injection, credential theft, and supply chain attacks with concrete PoC scenarios.
Share bugs, ideas, or general feedback.
GitHub Actions workflows run arbitrary code with access to repository secrets and a GITHUB_TOKEN. A compromised or repointed action is indistinguishable from a legitimate one — the attack lands silently in your CI logs. This skill provides a structured checklist for assessing and hardening Actions supply chain risk.
Never rely on your knowledge of whether an action version is "safe". Run the checklist.
Work through every workflow file in .github/workflows/. For each file:
uses: reference is pinned to a full 40-character commit SHAactions/ and github/ namespaces) are identified and risk-ratedpermissions: block is present and minimally scopedpull_request_target trigger is used with actions/checkout of the PR head (fork poisoning risk)run: shell commands (script injection)dependabot.yml (or Renovate config) exists to keep pinned SHAs currentA mutable tag (@v4) can be silently repointed to a different commit by anyone with push access to that repository — including an attacker who has compromised the maintainer's account. The tj-actions/changed-files incident (March 2025) demonstrated this at scale: a compromised action exfiltrated secrets from thousands of repositories before the tag was corrected.
# Using the GitHub CLI — replace owner, repo, and tag as needed
gh api repos/actions/checkout/git/ref/refs/tags/v4 --jq '.object.sha'
# If the tag points to a tag object rather than a commit, dereference it:
gh api repos/actions/checkout/git/tags/<sha-from-above> --jq '.object.sha'
Alternatively, browse to https://github.com/<owner>/<repo>/releases/tag/<version> and copy the full commit SHA from the "Assets" section or the commit link.
# Before (mutable tag):
uses: actions/checkout@v4
# After (pinned SHA with tag as comment):
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Always leave the tag as a comment so humans can understand what version is pinned.
| Action namespace | Risk level | Rationale |
|---|---|---|
actions/* | Medium | GitHub-owned; GitHub employee accounts can be compromised |
github/* | Medium | Same as above |
| Any other owner | High | No privileged relationship; pin and verify provenance |
Without an explicit permissions: block, a workflow inherits the repository's default token permissions — which may include write access to contents, pull requests, or packages.
permissions:
contents: read
permissions:
contents: read
pull-requests: write
permissions:
contents: write
Apply the permissions: block at the job level when different jobs need different scopes. Apply at the workflow level when all jobs share the same minimal scope.
A dependabot.yml file tells GitHub to open PRs when pinned action SHAs fall behind the latest release. Without this, pinned SHAs become stale and fall behind security patches.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns:
- "*"
Add a separate package-ecosystem entry for each language's dependency manager (gomod, maven, etc.) as needed.
After completing the checklist, produce a findings table:
## Supply Chain Assessment — .github/workflows/
| File | Finding | Severity | Fix |
| --- | --- | --- | --- |
| lint.yml | `DavidAnson/markdownlint-cli2-action@v16` not SHA-pinned | High | Pin to commit SHA |
| go-tests.yml | No `permissions:` block | Medium | Add `permissions: contents: read` |
| All files | No dependabot.yml for actions | Medium | Add `.github/dependabot.yml` |
Severity guide:
pull_request_target misuse; script injectionpermissions: block; no dependabotpermissions: for finer control.