Blog
min read
My Agentic Trust Issues: From Prompt Injection to Supply-Chain Compromise on gemini-cli
%20(1).png)
Executive Summary
Pillar Security researchers identified a CVSS 10 critical vulnerability (dubbed TrustIssues) in Google's AI powered GitHub workflows that allowed any external attacker, with nothing more than a public GitHub issue, to a full supply chain compromise of the gemini-cli repository, Google's AI coding agent with 101,000+ stars.
The critical severity rating reflects a specific bypass our researcher Dan Lisichkin identified inside Gemini CLI itself. The strategic impact is what that vulnerability enabled: a complete supply-chain compromise of Google's gemini-cli repository.
The attack worked in four steps:
- The vector. An attacker opens a public Issue on a Google GitHub repository.
- The mechanism. Google deployed a Gemini-powered AI agent to read and triage incoming public issues automatically. The attacker hides instructions inside the issue text. When the agent reads the issue, the prompt injection takes control of the agent.
- The exploit. Under the attacker's instructions, the Gemini agent extracts the workflow internal secrets from the build environment and exfiltrates them to an attacker-controlled server. From those credentials, the attacker pivots to a token with full write access on the repository.
- The impact. Full supply-chain compromise. The attacker can push arbitrary code to the main branch of gemini-cli’s repository, which then ships to every downstream user.
We confirmed this vulnerability on gemini-cli and identified the same vulnerable workflow across at least eight other Google repositories.
Google patched the vulnerability two days after reporting and released a fixed version of gemini-cli (version 0.39.1).

Why This Happened: The Lethal Trifecta in CI/CD
Simon Willison coined the term "lethal trifecta" for three properties that, combined in a single AI agent, make data exfiltration inevitable: access to private data, exposure to untrusted content, and the ability to externally communicate.
CI/CD pipelines contain the entire combination. Workflow secrets sit in the runner's process tree. Every issue body and PR description on a public repository is attacker-controlled input. Any tool that can write somewhere readable works as an exfiltration channel, including gh issue edit, and echo to runner logs that are publicly visible.
The pattern we focused on is AI-powered issue triage: an agent reads a new issue, picks a label, and writes it back. Google's implementation of this pattern met all three conditions.
How We Found It: The Draco Discovery
During routine research, one of our automated workflow scanners detected a GitHub Actions workflow with an AI injection entry point. It was a Gemini-powered issue triage workflow deployed by Google across multiple repositories. The workflow uses the run-gemini-cli action and triggers on issues: opened, so any GitHub user can activate it by opening an issue.
The agent runs Gemini CLI in --yolo mode, which auto-approves every tool call without human confirmation. The allowed tools include gh issue edit and shell access, enough to read files and execute commands. The issue body feeds directly into the agent's prompt without sanitization.
We first identified this workflow on the google/draco repository. To confirm the vulnerability, we crafted a prompt injection that induced Gemini to execute the following command:
This read the parent process's environment variables and wrote them into the public issue body. The leaked environment included the workflow's GEMINI_API_KEY, and OIDC credentials. We immediately blanked the issue body and reported the leak to Google who mitigated the issue in less than a day.
Full Supply-Chain Compromise on gemini-cli
After confirming the vulnerability on google/draco and reporting it to Google, we turned our attention to the broader blast radius. The same workflow template was deployed across multiple Google repositories, but the highest-value target was google-gemini/gemini-cli, a repository with over 100,000 stars and active use as Google's flagship AI coding agent.
The triage workflow on gemini-cli had the same prompt injection entry point, but the exploitation path to full repository compromise required several additional steps. Here is how the full chain works.
The starting permissions
The (now disabled) triage workflow requests these permissions:
These are broad, but the workflow authors were aware of the risk. The GITHUB_TOKEN is explicitly not passed to the Gemini CLI step:
So the agent does not have the token in its environment. On the surface, this looks like a reasonable mitigation.
The token is on disk
The mitigation covers the environment, but not the filesystem. The actions/checkout step that runs before the Gemini CLI step persists Git credentials to disk by default as can be seen in this runner log:
The token is written into .git/config as part of the remote URL. The agent can read this file the same way it reads any source file in the repository.
Exfiltrating the token
Inside the workflow, a prompt injection payload can induce the agent to execute:
This reads the .git/config file containing the GITHUB_TOKEN, base64-encodes it, sends it to an attacker-controlled server, and then holds the workflow open with sleep 300. The token remains valid for as long as the workflow run is alive, giving the attacker a five-minute window to use it.
Pivoting to contents: write
Proof of concept
We built a full end-to-end PoC demonstrating this attack chain. We copied both smoke-test.yml and the automated triage workflow into our own organization and reproduced the complete escalation from prompt injection to pushing code to main.
The only modification we made was relaxing the system prompt in the Gemini labeling step. This was deliberate. The purpose of the PoC was to demonstrate the post-injection privilege escalation path, not to demonstrate that the system prompt can be bypassed. System prompts are not a reliable security boundary against prompt injection, and defeating the prompt would not change the underlying vulnerability or its impact. A full PoC of the view is available here:
Responsible Disclosure Timeline
- April 16, 2026: Pillar Security reports the vulnerability to Google's OSS Vulnerability Rewards Program with a proof-of-concept against google/draco. Exposed secrets are documented and issue bodies are blanked.
- April 16, 2026: Google acknowledges the report, files internal bugs with the product team, and deletes the exposed issues.
- April 17, 2026: Pillar provides additional scope analysis. Vulnerable workflows identified across additional Google repositories.
- April 17, 2026: Pillar identifies the run-gemini-cli example templates and Best Practices page as the source of the ecosystem-wide adoption of the vulnerable pattern. As a mitigation step, Google disables the vulnerable workflow across several repositories.
- April 20, 2026: Full supply-chain compromise PoC against gemini-cli demonstrated and submitted.
- April 24, 2026: Google publishes GHSA-wpqr-6v78-jr5g, a security advisory covering the run-gemini-cli action (patched in 0.1.22) and Gemini CLI (0.39.1 / 0.40.0-preview.3). Tool allowlisting is now enforced under --yolo mode.
We would like to thank Google for the amazing cooperation and for quickly resolving this issue.
The Patch
On April 24, 2026, Google published GHSA-wpqr-6v78-jr5g, covering updates to both Gemini CLI and the run-gemini-cli GitHub Action. The advisory addresses two separate issues: our workflow-level prompt injection vulnerability, and a separate finding related to Gemini CLI's folder trust model in headless environments, discovered by Elad Meged of Novee Security.
The changes relevant to this research are in the run-gemini-cli action (patched in version 0.1.22) and the Gemini CLI policy engine (@google/gemini-cli versions 0.39.1 and 0.40.0-preview.3):
Tool allowlisting now enforced under --yolo mode. Previously, running Gemini CLI with --yolo caused it to ignore any fine-grained tool allowlist in settings.json. A workflow could specify run_shell_command(echo) as the only permitted tool, but --yolo would approve any command. The patched version evaluates tool allowlists even in --yolo mode, so a triage workflow that only permits echo and gh issue edit will now actually restrict execution to those tools.
Additionally, Google added more command sanitization, attempting to execute commands through shell command substitution, shell redirects and other injection techniques are now obsolete.
Finally, Google updated their best practices and example workflows to reflect these changes, which can be found here.
Recommendations
Allowlists are only as good as their entries. If a workflow permits run_shell_command(cat) or any tool capable of reading files, the /proc and .git/config primitives still work. Google also recommends this list is kept safe and constrained.
Disable credential persistence in actions/checkout. By default, the actions/checkout step persists Git credentials to disk on the workflow runner. This is what made our second read primitive possible. Set persist-credentials: false in the checkout step to prevent the token from being written to .git/config:
This should be treated as a baseline requirement for any workflow that processes untrusted input.
Audit your AI agent triggers. Find every place in your CI/CD where an outside user can trigger an AI agent: issues, PRs, comments, scheduled runs over user-supplied data. Any issues: opened trigger without an author_association gate is a prompt injection surface.
Check for the lethal trifecta. Does the agent have access to private data, exposure to untrusted content, and the ability to communicate externally? If all three are present, exfiltration is possible regardless of prompt hardening.
Model your threat around the escalation, not the initial theft. The token the attacker steals is rarely the one they use. Privilege escalation through workflow dispatch, OIDC token minting, and cross-workflow pivoting should be in your threat model.
Do not rely on GITHUB_TOKEN: '' as a mitigation. Unsetting a token in the child process environment does not protect the parent's process memory or credentials on disk. Secrets need to be architecturally unreachable, not just absent from the agent's env.
Treat prompt injection as a privilege problem. Prompt hardening does not change the blast radius of over-permissioned agents. The model refused five researchers who asked for secrets by name. It ran our payload because we never mentioned secrets at all.
Secure your Agentic CI/CD with Pillar
Our automated workflow scanning is what flagged the Google triage pattern in the first place. We shipped Pillar for Agentic CI/CD to turn that same capability on your pipelines. Point it at your CI/CD and it finds the AI agents already running inside: the Gemini triagers, the Claude reviewers, the Copilot bots someone added six months ago and nobody re-reviewed. Then it tells you which ones sit on the wrong side of the lethal trifecta.
If you want to know which agents are running in your pipelines and what an outside attacker can wake up with a comment, talk to us.
Subscribe and get the latest security updates
Back to blog

%20(1).webp)



.webp)
.png)