Two flaws in Google's adk-python repository let a low-privileged AI agent trigger actions reserved for maintainers, an AI agent privilege escalation path built entirely out of ordinary CI/CD plumbing. Pillar Security found and reported both flaws in June 2026, and Google had closed both by late July. This isn't a live vulnerability report. It's a resolved case study that maps out exactly what to check if you've wired an agent into your own GitHub Actions pipeline.
What Pillar Security found in Google's ADK repo
The repository is google/adk-python, Google's toolkit for building AI agents, and the project runs its own agents to triage issues and pull requests. Pillar's team found two separate ways an outside contributor could turn that automation against itself.
The first flaw sat in adk-bot, a low-privileged agent that responds to public issues and PR comments. Pillar showed the bot could be prompt-injected into posting an @gemini-cli mention, and that mention alone was enough to trigger three maintainer-tier workflows: gemini-review.yml, gemini-invoke.yml, and gemini-dispatch.yml. Those workflows carry a GITHUB_TOKEN scoped to pull-requests:write and issues:write. Part of what let this work was identity: the bot posted as a user with collaborator-level privileges instead of a scoped bot account, so its comments carried more trust than a public-facing agent's output should.
The second flaw lived in issue-fix.yml, a workflow triggered by an /adk-issue-fix comment that hands an agent a run_command tool. Pillar found a denylist on that tool blocked dangerous characters but not the commands built to use them: the allowed git and gh subcommands carried their own mechanisms for running code, and a contributor who understood those mechanisms could turn an approved command into an escape hatch. We're not walking through how, because the point of an audit checklist is to close that gap, not reopen it. The path reached a personal access token, ADK_TRIAGE_AGENT, and a GCP service-account key, ADK_GCP_SA_KEY.
Both reports went to Google in early June: the first on June 2, the second on June 5. Google's VRP panel ruled on the first report on July 9, issuing an honorable mention rather than a monetary bounty and noting the full impact required a maintainer to merge something plus a degree of social engineering on top of the technical bug. Google hardened the repository against the first issue around that same verdict, and confirmed the second fix on July 21 in commit 66730e9. As of Pillar's write-up, the second report was still awaiting its own VRP verdict. Pillar published the research on August 3. Nobody browsing issues on adk-python today is walking into either path.
Why this generalizes past one Google repo
Google didn't have some exotic bug. The shape of the failure is what carries over to every other repo running an agent. Pillar frames it as an agent-to-agent privilege boundary failure: a downstream agent trusted a signal, a mention, a comment, a label, that an upstream agent produced from text an anonymous stranger wrote. The upstream agent wasn't compromised in any dramatic sense. It just did its job, and its job happened to be reading whatever showed up in a public issue.
Plenty of engineering teams have built exactly this shape over the past year, usually without deciding to. A support bot answers issues. Someone adds a slash command that kicks off a fix workflow. A separate pipeline picks up a label or a mention and runs with more permissions than the first bot had, because it's assumed a human, or at least a trusted process, put that signal there. Nobody maps what token the second stage holds until something forces the question.
If your team has been debating how AI coding assistants actually perform on real work, this is the security side of the same question: agents are getting wired into more of the pipeline before anyone has agreed on what they're allowed to touch. It also changes what a senior backend hire needs to own. What separates a backend engineer who owns CI/CD pipeline design from one who just ships code through it is exactly this kind of boundary-mapping, deciding which workflow gets which credential before an agent forces the question for you. It's also part of why ramping engineers into AI-assisted workflows now needs a security pass, not just a tooling walkthrough.
How to audit your CI agent's privilege boundaries
1. Inventory every agentic workflow that touches untrusted input
List every workflow triggered by issue_comment, pull_request_target, issues, or a bot mention. Mark which ones can be triggered by an anonymous or first-time contributor's text, not just a maintainer's.
2. Map what each workflow's token and credentials can actually do
For every workflow on that list, write down the exact token or secret it loads, a GITHUB_TOKEN scope, a PAT, a cloud service-account key, and what that credential can do if the workflow is manipulated. Pillar's case makes the point plainly: the failure wasn't that an agent got tricked. It was how much the agent could do once it was.
3. Separate the untrusted-input agent from the privileged-action agent
The agent reading public issues and comments shouldn't share an identity or a trigger path with the agent that can merge, approve, comment as a maintainer, or run infrastructure commands. In the ADK case, one agent's comment was enough to start a second, more privileged workflow. That's the boundary that failed.
4. Give agents dedicated identities, not long-lived PATs or human accounts
A bot commenting as a user, carrying collaborator-level privileges instead of a scoped bot identity, was part of what let the first flaw escalate. Use short-lived, narrowly scoped tokens, a GitHub App installation token over a personal access token, generated fresh for each run.
5. Treat your agent's tool allowlist as a security boundary, not a UX filter
A denylist on characters didn't hold because the allowed commands had their own escape hatches. Blocking a symbol isn't the same as auditing what an approved command can be made to do. Go through your agent's tool list and ask what each allowed command can reach, not just which ones are blocked.
6. Keep the human gates that prompt injection can't forge
Branch protection, required human review before merge, and a clean split between who can trigger a workflow and who can approve its output don't depend on any AI tool behaving correctly. Those are the controls Pillar recommends keeping in place no matter how the agent tooling underneath them changes.
FAQ
Is Google's ADK repository still vulnerable to this?
No. Google hardened the repository against the first issue in July and confirmed the second fix on July 21, 2026. This is a resolved case study, not something you'll still find in the repo today.
Do we need a public-facing AI agent to be at risk from this?
Yes, if a workflow triggered by a comment, an issue, or a mention can reach a token with write, merge, or infrastructure access, either directly or through a second workflow it triggers. The public-facing agent is the entry point. The privileged workflow sitting behind it is the actual exposure.
How is this different from a normal prompt injection attack?
Prompt injection is the delivery mechanism, not the damage. What made the ADK case worth a VRP review was that the injected instruction crossed a privilege boundary: a low-privileged agent's output triggered a workflow carrying maintainer-level credentials. Prompt injection against one already-low-privileged agent is a much smaller problem than prompt injection that reaches a second, more powerful agent downstream.
What's the minimum first step if we can't run a full audit this week?
Do steps 1 and 2 alone. List every workflow that fires on public issue or PR activity, and write down what token each one loads. That tells you your actual exposure before you touch anything else.
