agentsec · Tools · agentci

Offline · stdlib-only · MIT

agentci: detect prompt injection in AI-agent GitHub Actions in AI agents


Audits GitHub Actions workflows that run AI agents for prompt injection and excess privilege, offline.

What it detects

Audits GitHub Actions workflows that run AI agents for prompt injection and excess privilege, offline.

Agent actions (Claude Code, Codex, Gemini CLI, actions/ai-inference, home-grown claude -p / curl api.openai.com steps) are increasingly wired to issues, issue_comment and pull_request_target. That means any GitHub user can write text that lands in an LLM prompt, and that LLM often holds a write-scoped GITHUB_TOKEN, cloud secrets and a shell. This is the "prompt injection in CI" class (sometimes called *PromptPwnd*). agentci finds the AI steps in your workflows and reports how untrusted text reaches them, who can trigger them, and what they can do once hijacked.

Standard library only (it has its own small YAML-subset parser). No network.

Rules

RuleDefault severityFinding
AC01critical (high outside the agent step)Untrusted event text (issue.title/body, comment.body, pull_request.title/body/head.ref, github.head_ref, commit messages, toJSON(github.event), ...) interpolated with ${{ }} into the agent step, or into a run/env/prompt-like input of another step in the AI job
AC02medium (high for *)Outsider trigger (issues, issue_comment, pull_request_target, discussion*, workflow_run, review events) with no author_association / actor / label gate in the job or step if:. anthropics/claude-code-action checks write access itself, so it is only flagged when allowed_non_write_users / allowed_bots is set
AC03critical (high for gh pr checkout)pull_request_target / workflow_run job that checks out the PR head (or fetches pull/N), so the agent reads attacker-controlled CLAUDE.md, AGENTS.md, scripts and configs with secrets in scope
AC04low / medium / highAI job token scope: no permissions: block (low), write-all (high), write to contents/actions/packages/pages/... (high with outsider triggers), id-token: write (high)
AC05critical with outsider triggers, else highAgent shell/sandbox unlocked: Bash(*) or bare Bash in allowed tools, --dangerously-skip-permissions, --dangerously-bypass-approvals-and-sandbox, danger-full-access, Codex safety-strategy: unsafe, Gemini --yolo, bypassPermissions, approvals never
AC06medium / high / criticalSecrets reachable by the agent that are not model API keys (workflow, job or step env/with), and toJSON(secrets) (critical)
AC07low (medium for @main/no ref)AI action not pinned to a full 40-character commit SHA
AC08lowactions/checkout in the AI job without persist-credentials: false (token left in .git/config)
AC09infoInventory: which step is an AI agent and how it was recognised

Usage

cd tools/agentci
python3 agentci.py examples/risky              # 3 workflows, 26 findings, exit 1
python3 agentci.py examples/clean --fail-on any # 2 AI workflows, 0 findings, exit 0
python3 agentci.py                              # defaults to ./.github/workflows
python3 agentci.py .github/workflows --sarif > agentci.sarif
python3 agentci.py . --ai-action 'acme/review-bot*' --json --min-severity medium

After pip install of the kit, the same options work as agentsec agentci …. Every tool also accepts --help and almost every tool accepts --json.

Example output

See the examples under tools/agentci/examples/ in the repository.

SARIF and CI

agentsec agentci path/to/input --sarif > agentci.sarif

# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
  with:
    tools: agentci
    paths: path/to/input
    fail-on: high

SARIF 2.1.0 can be uploaded to GitHub code scanning. The composite action writes per-tool reports under agentsec-sarif/ by default.

OWASP mapping

Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.

Known limits

with the text it is given, and a clean report does not mean the workflow is safe.

hosts. Unusual wrappers, composite/reusable workflows (uses: ./... or workflow_call) and Docker actions are not followed; add them with --ai-action.

to its content; agentci only flags the trigger/gate/permission side of that (AC02, AC04, AC05). Data flowing through step outputs (steps.x.outputs.y) into prompts is not followed.

whether a condition is actually correct.

error (exit 2) instead of being guessed at. Action input names change between versions; checks use the names documented as of 2026.

Full source, tests, and fixtures: tools/agentci/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.