A zero privilege GitHub account opens an issue on a public repository. No fork, no pull request, no commit access. Forty seconds later, arbitrary code is running on the CI runner behind that repository with full access to workflow secrets. The repository belongs to Anthropic, Google, or OpenAI.
That is not a hypothetical. Novee Security researcher Elad Meged demonstrated exactly this attack at Black Hat USA on August 5, targeting the default configurations that each vendor ships for their own coding agent repositories. Two CVEs dropped. Both are now patched. But the architectural lesson they leave behind demands attention from every team running AI agents in CI/CD.
The New Attack Surface
AI coding agents — Gemini CLI, Claude Code, OpenAI Codex — graduated from developer toys to production infrastructure faster than security teams could update their threat models. Organizations now wire these agents into GitHub Actions workflows to triage issues, review pull requests, suggest fixes, and even merge code. The agents run with the permissions of the CI runner: access to secrets, write access to the repository, and often network egress to internal systems.
The premise is seductive: let the agent handle the toil. The problem is that “handling the toil” means the agent reads untrusted input and then executes tool calls with elevated privileges. Every GitHub issue body, PR description, and commit message becomes a potential instruction to an agent that can run shell commands.
Anatomy of the Attack
Novee’s research revealed three distinct attack chains, one per vendor, all reachable from a single GitHub issue:
Gemini CLI (CVE-2026-12537, CVSS 4.0: 10.0) — The container launcher for Gemini CLI in headless mode automatically trusted workspace folders, loading configuration from a local .gemini/.env file without validation. An attacker who could place a crafted .env file in the workspace (achievable through issue triggered workflows that check out repository content) gained OS command injection on the host before the sandbox even started. Additionally, the --yolo flag — commonly used in CI to auto approve commands — completely bypassed tool allowlisting. Every command the model requested was executed unconditionally.
Claude Code (CVE-2026-54316, CVSS v3.1: 9.1) — The command validator strips single quoted text before running its 23 security checks. That is correct bash parsing behavior, but it meant a payload embedded in the value of git push --receive-pack (a flag git executes server side) reached the runner untouched. A second chain turned Hugging Face’s public download counter into a covert exfiltration channel, leaking an API key one character at a time through telemetry the agent considered trusted.
OpenAI Codex — The openai/codex repository ran two Codex passes inside a single job sharing one checkout. The first pass could write AGENTS.md, the instruction file the second pass loads as its own system prompt. A failed JSON validation between passes triggered the second run with attacker controlled instructions. No CVE was issued — OpenAI’s position is that the sandbox performed as documented.
The common failure across all three was not in the model. It was in the harness: the code between the model and the real world. As Meged wrote, “one component treats repository content as untrusted, while a later component loads the same content as configuration, instructions, or executable state.”
A New Vulnerability Class: Prompt Injection → RCE
Traditional prompt injection gets a model to say something it should not. This is different. Here, prompt injection is merely the delivery mechanism. The actual vulnerability is that the agent’s tool execution layer trusts inputs that crossed a security boundary without revalidation.
This creates a new class of exploit chain: untrusted input → prompt injection → tool invocation → remote code execution. The severity depends entirely on what permissions the agent holds when the chain fires. In CI/CD, that typically means repository write, secrets access, and network egress — the complete supply chain trifecta.
Microsoft’s security team documented this pattern explicitly in June: “Defenders should treat AI workflows that process untrusted GitHub content as high risk when they also have access to secrets, file read tools, or external communication channels.”
The OWASP Agentic Skills Top 10 project has formalized this with their B1-B4 trust boundary framework, mapping how individual skill risks chain across trust boundaries from developer intent to production deployment.
Defensive Patterns That Actually Work
If your organization runs AI agents in CI/CD, here is what the post mortem evidence says works:
1. Sandbox Before the Agent Starts
The Gemini CLI flaw executed before the sandbox initialized. Your container isolation, your drop-sudo, your read only filesystem — none of it matters if the agent’s launcher parses untrusted configuration before those controls engage. Treat the agent bootstrap itself as an attack surface. Pin configurations. Never load .env files from checked out repositories in CI.
2. Principle of Least Privilege for Agent Runners
OpenAI’s remediation separated Codex passes into different jobs and dropped to a read only sandbox. Apply this universally:
# Instead of this:
permissions:
contents: write
pull-requests: write
# Grant only what the agent actually needs:
permissions:
contents: read
issues: read
Agents that triage issues need read access. They do not need write access to secrets, packages, or deployments.
3. Validate Inputs Before Agent Invocation
Do not hand raw issue bodies to an agent. Strip, sanitize, and structurally validate untrusted content before it enters the agent’s context window. Consider a preprocessing step that extracts only the fields the agent needs:
# Pre-process issue content before agent invocation
sanitized = {
"title": strip_markdown(issue.title)[:200],
"body": strip_code_blocks(issue.body)[:2000],
"labels": issue.labels,
}
# Only pass structured data to the agent
agent.invoke(context=sanitized)
4. Separate Trusted and Untrusted Passes
The Codex finding showed that running multiple agent passes in a shared job creates instruction injection opportunities. Each agent invocation should run in an isolated job with its own checkout, its own credentials, and no shared mutable state with other steps.
5. Treat Instruction Files as Untrusted Input
AGENTS.md, .gemini/, .claude/, CONVENTIONS.md — any file the agent reads as instructions is part of the untrusted input surface if an attacker can write to it. Pin instruction content outside the repository checkout, or verify checksums before loading.
The Broader Architectural Lesson
The zero trust community has spent a decade saying “never trust, always verify.” AI agents invert that principle by design: their entire purpose is to take loosely structured input and autonomously decide what to execute. The agent is a trust amplifier — it takes low privilege input and converts it into high privilege actions.
This means your threat model needs a new node. Between “untrusted external input” and “privileged CI execution,” there is now an agent that makes autonomous decisions about what to run. That agent is not a firewall. It is not a WAF. It has no deterministic security boundary. It is a probabilistic system making tool call decisions based on whatever context it was given.
Zentera’s zero trust architecture for agentic AI puts it cleanly: treat every AI agent as an untrusted principal that must authenticate, operate within a defined boundary, and produce an auditable record of every action it takes.
Your Call to Action
If your organization uses AI coding agents in CI/CD:
-
Audit your triggers. List every workflow an external user can activate (issues, PRs, comments, forks). If any of those trigger an agent, you have an untrusted input → agent execution path.
-
Audit your permissions. What secrets, tokens, and write access does the runner hold when the agent executes? Reduce to absolute minimum.
-
Update immediately. Gemini CLI ≥ 0.39.1, run-gemini-cli ≥ 0.1.22, Claude Code ≥ 2.1.163. Pin these versions explicitly in your workflows.
-
Instrument. Log every tool call the agent makes. If you cannot produce an audit trail of what the agent executed and why, you cannot detect compromise.
-
Assume breach. Rotate any secrets that were accessible to agent workflows running the vulnerable versions. CISA lists no known exploitation, but a public reproduction lab for the Claude Code flaw has been on GitHub since June 18.
The agents are not going back in the box. But treating them as trusted components in a pipeline they share with untrusted inputs is an architecture that Black Hat just proved broken. Fix the harness.