Guides
Agent workflow review
Security review for GitHub Actions workflows that run coding agents — untrusted triggers with secrets, issue and PR text in prompts or shells, pull_request_target with fork code, unrestricted agent tools, broad permissions.
Running a coding agent in CI hands it your API keys and a repository token. In 2026 a pull-request title was enough to make several agent actions leak their keys, and an issue title led to stolen npm credentials. The pattern is always the same: a trigger anyone can fire, untrusted text in the prompt, broad tools, secrets in the same job.
What is checked
| Finding | Severity | Why |
|---|---|---|
An agent runs on pull_request_target, issue_comment, issues, discussion* or workflow_run with secrets and no author check | critical | anyone can steer an agent that holds your keys |
pull_request_target checks out the pull request head | critical | fork code runs with your secrets and a write token |
issue / PR / comment / review text (${{ github.event.issue.title }}, .body, github.head_ref…) inside a run: script | high | shell injection: a title like "; curl … | sh # executes |
| the same text inside the agent's prompt | high | prompt injection — the path behind the 2026 key leaks |
--dangerously-skip-permissions, --yolo, Bash allowed without a command pattern | high on untrusted triggers, else medium | any instruction becomes any command |
permissions: write-all, or no permissions: block | high / medium | the token can push code and edit workflows |
the agent action is referenced by tag (@v1), not a commit SHA | medium | a moved tag changes what runs with your keys |
secrets: inherit | medium | every repository secret is passed on |
| an agent on an untrusted trigger without secrets or author check | medium | quota and write token are still exposed |
Recognized agents: Claude Code (claude-code-action, claude -p), Gemini CLI (run-gemini-cli, gemini -p), Codex
(codex-action, codex exec), OpenCode, Cline, Aider, Copilot agent.
The safe pattern
on:
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
jobs:
claude:
if: contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@<full-commit-sha> # vX.Y.Z
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: --allowedTools "Bash(npm test),Read,Grep"Let the agent read the issue or PR through its tools as data instead of pasting the text into the prompt.
Run it
- Agents:
codexguild_scan_workflowson the local MCP server reviews.github/workflows/*.ymloffline — nothing is uploaded. - Web: paste a workflow at /lint?mode=workflow.
- REST:
POST https://api.codexguild.com/v1/lint/workflow{ "content": "…" }(public, nothing stored).