{
  "markdown": "# GitHub Actions Security Audit\n\n> MCP server that audits `.github/workflows/*.yml` files for supply-chain risks. Catches script injection, leaked tokens, unpinned actions, broad permissions, and `pull_request_target` foot-guns — the patterns behind several 2024–2025 supply-chain incidents.\n\n**Built by [Unbearable Labs](https://github.com/UnbearableDev).** Pay-per-event — only billed when a tool is actually called.\n\n---\n\n## Available on\n\n- [Apify Actor Store](https://apify.com/unbearable_dev/github-actions-audit) — primary, metered usage (PPE)\n- MCPize — *pending submission*\n- MCP.so — *pending submission*\n- PulseMCP — *pending submission*\n- Smithery — *pending submission*\n- Glama — *pending submission*\n\n**Newsletter:** [Unbearable TechTips Weekly](https://unbearabletechtips.com) · **All Actors:** [github.com/UnbearableDev](https://github.com/UnbearableDev)\n\n## What it does\n\nPoint any MCP-capable client (Claude Desktop, Cursor, n8n, Make, Zapier, custom agents) at this server, hand it a workflow YAML, and get back structured findings with:\n\n- **Severity** — critical / high / medium / low / info\n- **Affected job and step** — exact location of the problem\n- **Description** — why it matters, with the actual attack vector\n- **Remediation** — what to do about it\n- **Fix snippet** — YAML you can paste directly\n\n## Tools\n\n| Tool | Purpose |\n|------|---------|\n| `audit_workflow(workflow_yaml? \\| workflow_url?, min_severity='low')` | Run all checks |\n| `check_secrets(...)` | Secret-leakage paths only |\n| `check_permissions(...)` | `GITHUB_TOKEN` scope issues only |\n| `check_action_pinning(...)` | Action version-pinning only |\n| `check_runner_security(...)` | Self-hosted runner + script injection |\n| `check_workflow_config(...)` | Timeout / config hygiene |\n| `check_supply_chain_advanced(...)` | TeamPCP-class supply-chain patterns (GHA-201..208) |\n| `list_checks(category?)` | Browse the catalog |\n\nProvide exactly one of `workflow_yaml` (paste the content) or `workflow_url` (HTTPS URL — typically a GitHub raw URL to a specific workflow file).\n\n## Check catalog (v2: 21 checks)\n\n| ID | Category | Severity | Title |\n|----|----------|----------|-------|\n| GHA-001 | secrets | high | Secret interpolated directly into `run:` script |\n| GHA-002 | secrets | high | Secret printed via echo / set-output |\n| GHA-003 | secrets | medium | Secret used in `if:` condition |\n| GHA-004 | secrets | high | Hardcoded credential pattern in `env:` |\n| GHA-010 | permissions | high | `permissions: write-all` granted |\n| GHA-011 | permissions | medium | No top-level `permissions:` (inherits broad default) |\n| GHA-013 | permissions | high | `pull_request_target` + checkout PR head = PWNing pattern |\n| GHA-020 | action_pinning | high | Third-party action pinned to mutable tag |\n| GHA-021 | action_pinning | high | Third-party action pinned to mutable branch |\n| GHA-022 | action_pinning | medium | First-party action not SHA-pinned |\n| GHA-030 | runner_security | medium | Self-hosted runner used on `pull_request` from forks |\n| GHA-032 | runner_security | high | Script injection via untrusted `github.event.*` interpolation |\n| GHA-040 | workflow_config | low | No `timeout-minutes` on job |\n| GHA-201 | supply_chain_advanced | high | Action pinned to unpinned branch ref (TeamPCP-class: @main/@master) |\n| GHA-202 | supply_chain_advanced | high | Action pinned to mutable tag — SHA pin recommended |\n| GHA-203 | supply_chain_advanced | critical | `pull_request_target` + checkout of PR head SHA/ref (codecov/tj-actions exploitation path) |\n| GHA-204 | supply_chain_advanced | high | Script injection via `github.event.*` user-controlled field in `run:` |\n| GHA-205 | supply_chain_advanced | medium | Action from non-allowlisted owner (untrusted 3rd-party) |\n| GHA-206 | supply_chain_advanced | high | Top-level `permissions: write-all` or `contents: write` without per-job scoping |\n| GHA-207 | supply_chain_advanced | medium | Secret logged via `echo` / `cat` in `run:` block |\n| GHA-208 | supply_chain_advanced | low | Action uses a known-retired tag |\n\n## Pricing\n\n| Event | USD |\n|-------|-----|\n| Any audit / check_* tool call | $0.02 |\n| `list_checks` discovery | $0.005 |\n\n## Connecting from Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"gha-audit\": {\n      \"transport\": \"streamable-http\",\n      \"url\": \"https://YOUR-ACTOR-URL.apify.actor/mcp\"\n    }\n  }\n}\n```\n\n## Sibling MCPs from Unbearable Labs\n\n- **[`docker-compose-audit`](https://apify.com/unbearable_dev/docker-compose-audit)** — `docker-compose.yml` security audit\n- **[`dockerfile-audit`](https://apify.com/unbearable_dev/dockerfile-audit)** — Dockerfile security & quality\n- **[`hu-postcode-validator`](https://apify.com/unbearable_dev/hu-postcode-validator)** — Hungarian postcode lookup\n\n## What's NOT covered (yet)\n\n- Reusable workflow auditing (multi-file resolution)\n- CodeQL-grade dataflow tracking\n- Marketplace-listed action reputation scoring\n\n## Source / contact\n\nSource: [github.com/UnbearableDev/github-actions-audit](https://github.com/UnbearableDev/github-actions-audit).\nIssues + ideas: `unbearabledev@gmail.com`.\n\n---\n📬 Built by Noel @ Unbearable Labs. More MCP servers + audit tips in the newsletter: https://unbearabletechtips.beehiiv.com\n",
  "bytes": 5242,
  "sha": "d1149ad52d27731e23888d38fe06b66d4446a2f9365ea9f1184ce7517cdd5c01",
  "repo_slug": "unbearabledev/github-actions-audit",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_unbearabledev_github_actions_a_3647e320/readme"
}