.png)
CI Green Is Not Merge Safe
On June 1, 2026, security researcher RyotaK of GMO Flatt Security published a disclosure that should stop every team running AI coding agents in CI/CD: a single malicious GitHub issue could compromise any public repository using Anthropic's Claude Code GitHub Action, including Anthropic's own repos. The fix landed in claude-code-action v1.0.94. If you haven't updated, stop reading and do that first.
This isn't a theoretical attack. Variants of the same pattern were exploited against Cline's npm publishing pipeline in February, and the autonomous HackerBot-Claw bot probed similar misconfigurations across Microsoft, Datadog, and CNCF projects. Three incidents in six months makes this a class of vulnerability, not a one-off.
Claude Code Action's permission model was supposed to restrict who could trigger it. The checkWritePermissions function verified that the triggering actor had write or admin access to the repository. Reasonable enough. But it had a carve-out: any actor whose name ended in [bot] was waved through unconditionally.
The assumption was that GitHub Apps are trusted entities installed by admins. The reality: anyone can register a GitHub App, install it on their own repository, and use that app's installation token to open issues on any public repo. GitHub Apps have implicit read access to all public repositories and can create issues and pull requests without any special permissions. The actor name ends in [bot], the permission check returns true, and the attacker's payload is processed as trusted input.
Tag mode had an additional checkHumanActor call that verified the actor type was User via the GitHub API. Agent mode didn't. That's all it took.
Once past the permission gate, the attacker's issue body reached Claude's context window. RyotaK crafted a description that looked like an error message, tricking Claude into "recovering" by executing commands embedded in the text. This is indirect prompt injection: planting instructions inside content the AI reads so it follows the attacker's instructions instead of its actual task.
The target was /proc/self/environ, the Linux pseudo-file that exposes a process's environment variables. Claude Code blocks trivial reads like a bare cat of that file, but RyotaK bypassed those guards with more sophisticated techniques. Once the environment variables were in Claude's context, the mcp__github__update_issue MCP tool wrote them back into the issue description for the attacker to collect.
The critical secrets in those variables were ACTIONS_ID_TOKEN_REQUEST_TOKEN and ACTIONS_ID_TOKEN_REQUEST_URL. GitHub Actions uses these to request an OIDC token, a cryptographically signed proof that says "I am workflow X running in repository Y." Claude Code Action trades that OIDC token with Anthropic's backend for a Claude GitHub App installation token with read/write access to code, issues, pull requests, and workflows. Steal the OIDC credentials, replay the exchange, and you hold write access to the target repo.
Point this at the anthropics/claude-code-action repository itself, and you could poison the action that downstream projects pull.
The bot-trust bypass required crafting a malicious GitHub App. But there was an easier route that skipped it entirely. Anthropic's own example issue-triage workflow shipped with allowed_non_write_users: "*", which lets any user trigger the workflow. Anthropic's own security docs flagged this as risky, but they used it anyway in their example, and repos downstream copied it.
The documentation said this was safe for "extremely limited permissions" like issue labeling. That claim doesn't hold up. Even with only issues: write, an attacker could delete or edit existing issues, and the workflow exposed the Anthropic API key as a secret. Worse, Claude Code Action was posting task summaries to the publicly visible workflow run summary panel by default, giving attackers a ready-made exfiltration channel.
RyotaK also demonstrated a chaining attack. An attacker could trigger the permissive triage workflow to steal a GITHUB_TOKEN with issues: write, then use that token to edit a trusted user's issue after it fired the more privileged tag-mode workflow but before Claude read it. The injected payload rides in as "trusted" input, and the attacker escalates to full OIDC credential theft and repository compromise.
The Claude Code Action disclosure isn't an isolated event. It fits a pattern that's been accelerating.
February 2026: cline@2.3.0 supply chain attack. A prompt-injected issue title against Cline's claude-code-action triage workflow let attackers steal an npm publish token and push an unauthorized package version. The rogue cline@2.3.0 only force-installed a non-malicious AI agent and was pulled within eight hours, but the same chain could have shipped real malware to every user who updated.
Late February 2026: HackerBot-Claw probes. An autonomous bot spent weeks probing GitHub Actions misconfigurations at Microsoft, Datadog, and CNCF projects. When it tried to prompt-inject a Claude-based reviewer through a poisoned config file, Claude caught it and refused. But the bot successfully exploited other targets using the same class of workflow misconfiguration.
The common thread: AI coding agents given broad CI/CD permissions plus untrusted input plus no pre-merge review of workflow configuration. Each incident exploited workflow YAML that a human reviewer, or an automated one, would have flagged.
Every vulnerability in this exploit chain traces back to workflow YAML that was committed without adequate review. The patterns are detectable before they become exploitable.
Overly broad trigger conditions. The triage workflow triggered on issues: [opened] with no actor filtering, meaning any GitHub user or app creating an issue could fire it. A reviewer should flag any workflow triggered by issue or PR events that doesn't explicitly constrain which actors can invoke the downstream action.
Missing or flawed actor-validation logic. Checking whether an actor name ends in [bot] is not the same as verifying the actor has legitimate permissions. A string suffix check on a user-controlled field is an authentication bypass waiting to happen. Pre-merge review should catch permission checks that rely on naming conventions instead of actual API-level permission verification.
Dangerous permission scopes. The default Claude Code Action workflow requested id-token: write, contents: read, issues: read, and actions: read. The id-token: write permission is the one that enabled OIDC token theft. Combined with a permissive trigger, it's a direct path to repository compromise. Any workflow that pairs id-token: write with untrusted triggers should be flagged immediately.
Wildcard user allowlists. The allowed_non_write_users: "*" setting is the action-input equivalent of chmod 777. It bypasses the permission model entirely. A code reviewer that understands workflow semantics would flag this on sight.
These aren't exotic patterns. They're the kind of thing that shows up in a PR diff when someone adds a new workflow or modifies an existing one. Tenki's code reviewer runs on every PR, including changes to .github/workflows/ YAML. When it sees a workflow granting id-token: write alongside a trigger that accepts untrusted input, or a wildcard actor allowlist on an action that has access to secrets, it flags it before the merge. That's the point of pre-merge review: catching the misconfiguration in the diff, not in the incident postmortem.
Prompt injection is not a solved problem. RyotaK has reported around 50 separate ways to bypass Claude Code's permission system and execute arbitrary commands. That number should make anyone uncomfortable about giving an LLM write access to production repositories.
The Claude Code GitHub Action's default permissions include read and write access to code, issues, pull requests, discussions, and workflow files. That permission surface exists because the action needs it to do useful things: review PRs, label issues, generate code. But "useful" and "safe for untrusted input" are different things, and the gap between them is where every one of these exploits lives.
Anthropic responded well. They fixed the bot-trust bypass within four days of RyotaK's January report, disabled the workflow summary exfiltration channel, implemented argument validation on the gh CLI wrapper, scrubbed environment variables from child processes, and added mitigations against the issue-editing race condition. They rated the vulnerabilities 7.8 under CVSS v4.0 and paid a $4,800 bounty. That's responsible handling.
But patching one action doesn't fix the pattern. Every AI coding agent that processes untrusted input in CI/CD has this same attack surface. The defenses are always defense-in-depth, never a security boundary, because prompt injection doesn't have a reliable fix. The only hard control is what happens before the workflow is deployed: review the YAML, check the permissions, validate the triggers.
If you're running any AI coding agent as a GitHub Action, here's the short list.
*, remove it or replace it with an explicit list of trusted usernames. Don't expose secrets beyond the Anthropic API key and GITHUB_TOKEN to workflows that accept untrusted input.id-token: write or contents: write. Remove any tools and permissions that aren't strictly required..github/workflows/ files should never land without a reviewer who understands the security implications of triggers, permissions, and action inputs. Tenki automates this on every PR.The pattern is clear. AI agents are being deployed into CI/CD with broad permissions and insufficient gatekeeping on who can trigger them. Prompt injection turns read access into write access, and write access into supply chain compromise. The fix isn't better prompt engineering on the agent side. It's catching the misconfigured workflow before it ships.
Tags
Recommended for you
What's next in your stack.