#
Google ADK Agent-to-Agent Attack: Privilege Boundary Breakdown Calling Privileged CI Workflows from Low-Privilege Triage Agents
#
- Basic Information
Article Name: I'll Just Call You: Agent-to-Agent Privilege Boundary Failures in CI/CD on Google's ADK Repository #
Publisher: Pillar Security #
Publication Date: August 3, 2026 #
Original Source: Pillar Security #
Related Sources: SecurityWeek #
Related Products: Google Agent Development Kit for Python, Gemini CLI, GitHub Actions, GitHub MCP server #
Related Workflows: pr-triage.yml
, gemini-dispatch.yml
, gemini-invoke.yml
, gemini-review.yml
Attack Status: Security research that verified the conditions in a real production repository. Mitigated by Google. No active exploitation confirmed. #
Severity: High
#
- Executive Summary
This is an attack where a low-privilege triage agent is manipulated via prompt injection hidden in an external PR. The agent posts a comment using a collaborator identity to recursively trigger a privileged Gemini workflow. Through runner RCE and the GITHUB_TOKEN
, the attacker spoofs reviews, comments, and labels.
#
- Attack Flow
Chain A: Privilege Escalation Between Agents
- An external attacker creates a PR on
google/adk-python
.
- The attacker embeds a prompt injection in the PR body, disguised as contribution guidelines.
- The public-facing
adk_pr_triaging_agent
processes the PR.
- The agent posts a comment using a Personal Access Token (PAT) linked to a collaborator user.
- As instructed by the attacker, the agent outputs
@gemini-cli <prompt>
at the start of the comment. #
gemini-dispatch
determines that the command comes from a trusted collaborator.
- It triggers high-privilege workflows named
gemini-invoke
/gemini-review
.
- The privileged agent leaks the MCP tool list.
- Because
tools.core
is not set, it reaches all bash commands on the runner.
- It accesses the environment's
GITHUB_TOKEN
.
Chain B: Spoofing the PR Approval Lifecycle
- After gaining trust, the attacker creates PR A containing malicious code.
- The attacker places a prompt injection in another PR B.
- Agent processing on PR B uses the
GITHUB_TOKEN
to modify PR A.
- It overwrites the triager's existing comment to fake a review request.
- It posts an in-progress review comment and an approval review under the bot's name.
- It dismisses the genuine review request and changes the label to
approved
.
- It presents a trail that looks legitimately reviewed to human maintainers.
Additional Condition: Final merging requires human judgment or social engineering.
Chain C: Non-Interactive RCE in Other Automations
Pillar found another vulnerability in Antigravity-SDK-related automations that leads to RCE without maintainer action. Details are limited, and Google fixed it by the end of July 2026.
#
- Attacker Position and Execution Location
Attacker: Inputs via GitHub PRs/issues as an external contributor. #
Low-Privilege Execution Location: ADK agent/workflow for PR triage. #
Privilege Bridge: Agent comments posted as a collaborator user. #
High-Privilege Execution Location: gemini-invoke
/gemini-review
GitHub Actions runner. #
Target of Operation: GitHub issues, PRs, reviews, labels, review requests, and runner environments.
#
- Visibility to Victims and Administrators
The PR body looks like a normal summary, testing plan, and CLA note. The agent comments, GitHub Actions bot reviews, and labels also look like normal automation outputs. Individual events are permitted token actions. Abnormalities are hard to spot without tracing the provenance chain: "untrusted PR content was converted into a privileged workflow trigger via a collaborator agent."
#
- Success and Failure Conditions
Success Conditions
- The agent processes untrusted PR/issue content as a prompt.
- Agent output is posted as a collaborator/member identity.
- The comment trigger trusts the poster's permissions rather than the actual human actor.
- The privileged agent has a broad tool scope and reaches the runner shell.
- The
GITHUB_TOKEN
has issues: write
/pull-requests: write
permissions.
- Supply-chain compromise relies on humans trusting the fake review and merging.
Failure Conditions
- A data boundary that does not treat untrusted content as instructions.
- Requiring signed capabilities and an explicit allowlist for agent-to-agent hand-offs.
- Implementing the bot as a short-lived GitHub App token instead of a collaborator user/PAT.
- Minimizing
tools.core
and MCP tools, and forbidding shells.
- Not counting agent approvals as human approvals for branch protection.
- Validating the original human actor and taint/provenance when a comment triggers an action.
#
- What Happens on Success
Runner RCE, acquisition of the GITHUB_TOKEN
, tampering with issues/comments, dismissal of review requests, and spoofing of PR reviews/labels become possible. Merging malicious PRs requires additional human action, but the entire review lifecycle can be convincingly forged to provoke a software supply chain compromise.
#
- Observable Logs
- GitHub review, mention, and workflow notifications.
- Notifications alone make it hard to distinguish from normal automation.
Proxy / SWG / DNS
- Unusual requests from the runner to the GitHub GraphQL API.
- Access from agents/MCPs to unexpected external endpoints.
Endpoint / EDR
- GitHub-hosted runners may lack organizational EDR.
- Shell commands, environment access, and process trees on self-hosted runners.
Identity / IdP
- Agent comments using a collaborator user PAT.
- Reviews, comments, and label changes using the
github-actions[bot]
token.
- Review dismissals and approvals with no human activity.
SaaS / Cloud
- Cross-object operations where PR B's workflow modifies PR A.
- Privileged workflow dispatches immediately following
@gemini-cli
comments.
- Editing existing comments, deleting review requests, and adding approved labels.
- Mismatch between the workflow run actor and the input source PR.
Network
- A series of mutations to the GitHub API.
- Token exfiltration attempts if runner egress control is present.
#
- Determining Attack Success
Contact Only: A PR/issue containing a prompt injection is created. #
User Action: Not required; low-privilege agent processing starts. Final merge requires human action. #
Initial Execution: The agent posts a @gemini-cli
hand-off. #
Authentication/Privilege Success: Privileged workflow launch, shell/tool access, and token access. #
Session/Information Compromise: Acquisition of the tool list or GITHUB_TOKEN
. #
Subsequent Compromise Confirmation: Modification of comments/reviews/labels on other PRs, and merging of malicious PRs.
#
- Investigation Playbook
Trigger
- Agent-generated
@gemini-cli
originating from an untrusted PR.
- Cross-PR mutations by bots or collaborators.
- Agent workflows escaping shell/tool scopes.
Initial Verification
- Preserve workflow runs, event payloads, PR bodies, and agent prompts/outputs.
- Separate the original actor of the trigger comment from the generation entity.
- Check token permissions, MCP/core tools, and secret exposure.
Endpoint / Runner
- Shell commands, environment reads, network egress, and artifacts.
- For self-hosted runners, rebuild images and rotate credentials.
Authentication / Cloud
- Issuing entity, scope, and all mutations of PATs/GITHUB_TOKENS.
- Subsequent use of GitHub Apps, repository secrets, and OIDC tokens.
Subsequent Operations
- Search for comment edits, review dismissals, labels, and approvals across all PRs/issues.
- Cross-check repositories, branches, and releases touched by the agent.
Containment
- Stop workflows, revoke PATs/tokens, and strip agent account permissions.
- Invalidate agent approvals in branch protection settings.
- Re-run affected reviews and verify releases/artifacts.
Judgment Categories
-
Prompt Injection Attempt
-
Agent Hand-off Triggered
-
Privileged Workflow Reached
-
Runner/Token Compromise
-
PR Lifecycle Tampered
-
Supply-Chain Merge Confirmed
#
- Defense and Detection Ideas
Single Events
@gemini-cli
at the beginning of an agent comment.
- Editing of existing human comments by a bot.
- Review request dismissal via a workflow token.
Time-Series Correlation
Untrusted PR → Triage agent → Collaborator comment → Privileged workflow → Shell/token → Cross-PR review/label mutation.
Hunting Perspectives
- Differences between the workflow trigger actor and the prompt origin.
- A run from PR X modifying PR Y.
- Command-like comments by agent accounts/PATs.
- Approval trails without human sessions.
Log Gaps
- Agent prompt/output/tool-call logs.
- Input provenance/taint.
- Complete audit of GitHub token API mutations.
- Hosted runner process/network logs.
Priority Countermeasures
-
Do not re-interpret agent output as trusted commands.
-
Establish an explicit authorization gateway between low- and high-privilege agents.
-
Minimize agent tokens/tools and separate shells from secrets.
-
Distinguish human approvals cryptographically and by identity.
-
Track PR/issue content end-to-end as untrusted data.
#
- Facts / Inference / Hypothesis
Facts
- The Google ADK repository contained both a low-privilege agent and a high-privilege agent for maintainers.
- Prompt injection forced the low-privilege agent to post a
@gemini-cli
comment, launching a privileged workflow.
- Due to poor tool scoping, the privileged workflow reached bash and could access the runner's
GITHUB_TOKEN
.
- Token permissions allowed manipulation of comments, reviews, labels, and review requests.
- Google implemented mitigations. No exploitation has been reported.
Inference
- Agent-to-agent hand-offs represent a new identity delegation boundary; natural language output must not be treated as an authorization token alone.
- Even minimum-privilege tokens can forge human trust signals when multiple mutations are combined.
Hypothesis
- Preserving prompt provenance and the GitHub object mutation graph enables high-accuracy detection of agent-initiated cross-privilege escalation.
#
- MITRE ATT&CK Mapping
High Confidence
T1195.002 Compromise Software Supply Chain (when final merge succeeds) #
T1059.004 Unix Shell #
T1528 Steal Application Access Token #
T1098 Account Manipulation / Operating authorized automation (conceptual match) #
T1565.001 Stored Data Manipulation
Medium/Low Confidence
T1078 Valid Accounts (use of agent PAT/token) #
T1036 Masquerading (fake approval trail)
- Prompt injection and agent-to-agent delegation themselves are not fully represented in Enterprise ATT&CK and require custom technique supplements.
#
- Unknowns / Further Investigation
- Precise workflow designs after mitigation.
- Details of the RCE on the Antigravity-SDK side.
- Presence of actual exploitation.
- Other repositories accessible by the agent PAT.
- How long GitHub audit logs retain before/after comment edits.
- The prevalence of similar multi-agent CI implementations.
#
- Impact on SOCs and Organizations
Organizations adopting AI code review and triage must manage agents not merely as "convenient bots," but as service identities. SOCs and AppSec teams should monitor not only prompt injection detection, but also input provenance, agent-to-agent delegation, tool permissions, and the authenticity of PR approvals as a unified set of controls.
#
- Summary
For SOCs
- Monitor PR input → agent output → privileged workflow → GitHub mutation as a single chain.
- Distinguish between bot approvals and human approvals.
- Investigate cross-PR operations and comment edits with high priority.
For Administrators
- Minimize agent accounts/PATs, MCPs, shells, and token permissions.
- Do not trigger privileged workflows directly from agent outputs.
- Require independent human reviews in branch protection rules.
For Users
- Do not merge based solely on AI review indicators; check original reviewers, workflow runs, and change histories.