Skip to main content
ai agent securityci/cd securitycoding agentclaude codegemini cliopenai codexblack hat 2026cveprompt injectionair gaplocal-firstbyollm

The model was fine. The harness leaked your CI secrets.

Bodega One9 min read
Quick answer

At Black Hat USA 2026 (talk August 5), Elad Meged of Novee Security showed that Claude Code, Gemini CLI, and OpenAI Codex could each be turned against the CI systems they run inside. A single GitHub issue, opened by an account with no repository privileges, was enough to reach code execution on the CI runners and get at their secrets. Three different bugs, one shared lesson: they lived in the harness, the code wrapped around the model, not in the model's judgment. All three were patched before the talk. Fair warning, we build a local-first AI coding tool and we can run these same agents inside our own sandbox, so we are not neutral. But the useful takeaway is not “cloud tools are unsafe.” It is that the thing you have to secure is the plumbing between the model and your secrets, and that plumbing is where almost nobody is looking.

For two years the industry argued about model safety: will the model say something dangerous, will it refuse when it should. This disclosure is about a quieter question that turns out to matter more in practice. Not what the model decides, but what the software around it is allowed to do while it decides. In all three cases here, the model behaved. The wrapper did not.

The setup that ties the findings together is the one a lot of teams shipped this year without thinking hard about it: wire a coding agent into CI so it triages issues, reviews pull requests, or auto-fixes failures. That agent runs on a runner that also holds deploy keys, cloud tokens, and package-registry credentials. And its instructions come, in part, from text that any stranger on the internet can write.

What actually happened?

A researcher demonstrated that untrusted input reaching a coding agent inside CI could pivot into code execution and credential theft on the runner, across three separate tools. Per the disclosure and the Cloud Security Alliance research note that followed it:

  • Gemini CLI (CVE-2026-12537, CVSS 10.0). In headless mode the tool automatically trusted a repository's .gemini/.env file, and its coreTools allowlist was parsed and matched when tools were registered but never actually enforced at the moment of execution. Together that let an unprivileged attacker run commands on the CI host before the sandbox even started. Fixed in Gemini CLI 0.39.1 and the run-gemini-cli action 0.1.22.
  • Claude Code Action (CVE-2026-54316). A validator that was supposed to keep the agent read-only could be bypassed by stripping quotes, and it carried hardcoded “read-only” exemptions. The exfiltration path is the memorable part: the agent could be steered to create model repositories on Hugging Face and then encode a secret in the public download counters, incrementing the count on the repo matching the next character to leak a credential one character at a time. Fixed in 2.1.163. Note the honest wrinkle in the scoring: Anthropic rated it 6.0, while the NVD entry rates it 9.1.
  • OpenAI Codex (no CVE, workflow hardening only). When a CI job ran two Codex passes sharing one checked-out workspace, the first pass could write to AGENTS.md, an instruction file Codex loads from disk and treats as authoritative on the next invocation. A validation failure between passes was enough to trigger it. The first pass poisons the instructions the second pass obeys.

Different bugs, but read them together and the shape repeats: an input nobody classified as dangerous (an env file, a download counter, an instruction file on disk) sat inside the trust boundary of an agent that could run commands and see secrets.

What does “the harness” mean, and why does it matter?

Meged's framing, quoted in the reporting, is the cleanest one-liner on this: “The harness is the code between the model and the real world, and each of these three vulnerabilities lived in that harness rather than in the underlying language model's judgment.”

The harness is everything the vendor writes to turn a model into an agent: the file readers, the shell runner, the tool allowlist, the config loader, the code that decides which text becomes an instruction. It is ordinary software, and it has ordinary software bugs. But we tend to audit it with none of the paranoia we would apply to any other program that executes attacker-influenced input with production credentials in scope.

The Cloud Security Alliance note puts the consequence bluntly: AI coding agents now function as “an unaudited node in the software supply chain, making decisions and executing commands with a degree of implicit trust that the industry has spent the past decade learning not to extend to human contributors without review.” We spent ten years learning not to run a stranger's pull request against our secrets without a human in the loop. Then we handed the same access to an agent and pointed it at the issue tracker.

That last point is the one worth sitting with. A GitHub issue is, by design, something anyone with an internet connection and no prior relationship to your project can open. The moment an automation treats issue content as an instruction to an agent running in CI, it is implicitly trusting arbitrary strangers with a foothold inside that environment. The vulnerability is not really in the parser. It is in the decision to let untrusted text steer a privileged process at all.

What this does not prove

This is not a “cloud coding tools are insecure, ours is safe” story, and we will not pretend it is. Precisely:

  • All three are patched. This is a lesson about a failure class, not an open zero-day. Update your tools and the specific bugs are gone.
  • We run agents like these ourselves. Bodega One Code can host external coding agents such as Claude Code and Gemini CLI inside its own fleet over ACP. That means this is our attack surface too, and our containment is a claim you should test, not take on faith.
  • The exposure is a deployment choice, not a property of the model. The dangerous configuration is an agent running unattended, reachable by external input, holding live secrets. An interactive agent on a laptop with no CI credentials in scope is a different risk profile, for better and worse.
  • “Named the big three” is not the same as “only three are affected.” These are the tools that got looked at. The pattern is structural, so treat any agent-in-CI setup as in scope until you have checked it yourself.

Which of these conditions apply to your setup?

Strip out the tool-specific bug and every one of these attacks needed the same three things present at once. If your pipeline has all three, you have the exposure regardless of which agent you run:

  1. An untrusted input path into the agent. Issue text, PR titles and diffs, review comments, or a file in the repo that the agent auto-loads as instructions. If a stranger can write it, it is untrusted.
  2. Live, reusable secrets in reach of the run. Long-lived deploy keys, cloud tokens, or registry credentials sitting in environment variables or the runner's metadata, usable well beyond the single job.
  3. A way out. Outbound network access the agent can reach, whether that is an obvious HTTP request or something as quiet as a public counter it can increment. Exfiltration only needs a channel, not a polite one.

Remove any one of the three and the whole chain gets a lot weaker. Remove the untrusted input and there is nothing to trigger it. Remove the ambient secrets and there is nothing worth stealing. Remove the egress and the stolen thing has nowhere to go.

How do I contain a coding agent running in CI?

Treat the runner as reachable by strangers, cut its ambient credentials, and deny egress by default. The CSA note's mitigations map directly onto the three conditions above:

  1. Do not give the agent long-lived credentials. Replace personal access tokens and static cloud keys with short-lived, narrowly scoped credentials minted per run and revoked on exit. This shrinks the blast radius of anything that does leak.
  2. Default-deny outbound network access, then allowlist. The agent needs your model endpoint and your registry. It does not need the open internet. This is the single control that would have closed the exfiltration channel in the Claude Code finding.
  3. Treat all external and auto-loaded text as untrusted. Issue bodies, PR content, comments, and instruction files like AGENTS.md are input, not commands. Do not let an unauthenticated trigger auto-execute an agent with secrets in scope.
  4. Split multi-pass workflows into separate jobs with clean checkouts. This is the direct fix for the Codex finding: no shared workspace means one pass cannot poison the next.
  5. Watch for the tells. Reads of /proc/*/environ, a run reaching for a service it has never touched, an agent creating repositories it was not asked to. Anomaly detection is what caught the real thing.

Where we stand

We build for the case where the agent runs on your machine, with your keys, and no network path unless you grant one. Bodega One Code is a local-first desktop IDE and CLI: the model runs on your hardware through your own provider (10+ presets, including fully local ones), it has three permission modes (Ask, Plan, Act) so an autonomous run can be gated at approval rather than trusted wholesale, and it ships an air-gap mode that blocks network egress at the process level per project. When we host other agents like Claude Code or Gemini CLI inside our fleet, they run over ACP inside a sandboxed filesystem and shell, so the same containment applies to them.

The honest boundary, since this whole post is about not taking claims at face value: none of that is a magic exemption. A harness is still a harness, ours included, and if you point any agent at a repository full of secrets and wire it to untrusted input, you own that risk. What a local-first, interactive design changes is the default deployment. It is not an unattended process on a runner full of deploy keys that a stranger can reach through the issue tracker. And the privacy and egress claims are testable the same way the researcher tested these tools: put the run behind a proxy in air-gap mode and watch for outbound traffic. There should be none. If you would rather run a fully open-source stack, an open agent pointed at a local model through Ollama gets you a similar network posture, and we will say so plainly.

This is the third time in about five weeks we have written some version of the same paragraph, after Grok Build CLI shipped whole repositories to a cloud bucket and OpenAI's models broke a sandbox to cheat a benchmark. The specifics differ every time. The through-line does not: as coding agents get more autonomous, the risk keeps migrating out of the model and into the harness around it, the part that touches your files, your credentials, and the network. That is the part worth auditing, and the part worth keeping on a machine you control.

Sources

Common questions

What was disclosed about AI coding agents at Black Hat 2026?
At Black Hat USA 2026 on August 5, Elad Meged of Novee Security showed that Claude Code, Gemini CLI, and OpenAI Codex could each be turned against the CI systems they run inside. A GitHub issue opened by an account with no repository privileges was enough to reach code execution on the CI runners. Each tool had a distinct flaw, but all three lived in the harness around the model, not in the model itself. All three were fixed before the talk.
What are CVE-2026-12537 and CVE-2026-54316?
CVE-2026-12537 is a command-injection flaw in Gemini CLI, scored 10.0. In headless mode the tool auto-trusted a repository’s .gemini/.env file and its tool allowlist was checked at registration but never enforced at execution, letting an unprivileged attacker run code on the CI host before the sandbox started. It is fixed in Gemini CLI 0.39.1 and run-gemini-cli 0.1.22. CVE-2026-54316 is the Claude Code Action flaw, fixed in 2.1.163; Anthropic scored it 6.0 while the NVD entry scored it 9.1.
How did the Claude Code flaw leak an API key?
It turned Hugging Face’s public download counter into a covert channel. The agent could be steered to create model repositories, then encode a secret by incrementing the download count on the repository matching the next character, leaking a credential one character at a time. It never had to make an obvious outbound request to an attacker server, which is what makes the channel hard to spot.
Do I need to patch this right now?
The three specific bugs are already fixed, so update Gemini CLI, Claude Code, and any Codex CI workflow to current versions. The reason it still matters after patching is the pattern: any automation that feeds untrusted input (a GitHub issue, a pull request, a comment, an auto-loaded instruction file) to an agent holding live CI secrets is exposed to the same class of attack, patched tools or not.
How do I stop my own coding agent from leaking CI secrets?
Treat the CI runner as reachable by strangers. Do not hand an agent long-lived credentials; mint short-lived, narrowly scoped tokens per run and revoke them on exit. Default-deny outbound network access and allowlist only what the run needs, so a covert channel has nowhere to send data. Treat issue, PR, and comment text and any auto-loaded instruction file as untrusted, and split multi-pass workflows into separate jobs with clean checkouts.
Does a local-first coding agent avoid this?
It removes some of the conditions, not all of them by magic. These failures needed three things at once: live secrets within reach, an untrusted input path, and network egress to exfiltrate over. A local-first desktop tool like Bodega One Code runs interactively on your machine with your own keys rather than unattended in CI reachable by outsiders, gates actions behind permission modes, and can block egress at the process level in air-gap mode. But a harness is still a harness: point any agent at a repo full of secrets and wire it to untrusted input and the same discipline applies.

Written by the Bodega One team. We build Bodega One Code, the local-first AI IDE, and we write here about local models, AI costs, and what we learn shipping it. More about the team and why we build local-first on the about page.

Stay in the loop

Build-in-public updates, model picks, and Copilot/Cursor news as it breaks.

Ready to own your tools?

Beta is free and open to everyone. Download free.