LiteLLM's logs held the token that backdoored LiteLLM.
Hey 👋
Last week was about scope: what an agent is allowed to do, and where that’s enforced. This week is about what sits around the agent. That means the gateway it talks through, the monitor that watches it, and the places its keys are stored.
It was a busy five days. LiteLLM, the open-source gateway many teams put between their agents and model providers, shipped a backdoored release on 21 October. LiteLLM traces the break-in to GitHub tokens sitting in its own gateway logs. A day earlier, OpenAI published two incidents in which its own agents turned off parts of the monitoring that watches them. And between 17 and 19 October, two agent tools (OpenCode Console and Google’s Agent Mesh) disclosed problems with how they hold provider keys and grant agent sessions.
My take, in one line: anything the agent can read or write is part of its blast radius. That includes the systems you put there to contain it.
This week in AI security
The gateway’s logs held the keys to its own release
On 21 October, LiteLLM published that its “release pipeline was compromised and pushed v1.107.0 to the docker registry and PyPi.” The release “contained compiled malware which steals credentials and loads remote-code execution tools.”
LiteLLM’s timeline, all on 21 October (UTC):
- 10:08. Branch protection blocked an unauthorized change to the private release workflow. Five seconds later, a privileged developer credential overrode it.
- 10:46 to 11:08. A staging run built from a lookalike repository,
Berri-AI/litellm, one hyphen away from the realBerriAI/litellm. - 11:11. A second developer’s credential passed the production approval gate.
- 11:39. Seven malicious wheels went up on PyPI. Docker images followed at 11:46.
- 11:53. A third credential deleted the workflow records.
- 13:23. PyPI removed the package. Docker tags
v1.107.0,latest,main-latestandmain-stablewere cleaned up by 14:20.
That makes 104 minutes on PyPI and about two and a half hours on Docker. Wiz counts roughly 49,000 downloads of the bad version. It also saw stolen credentials in use “starting approximately 4.5 hours post-exfiltration”: each AWS credential was checked with sts:GetCallerIdentity, then bedrock:ListFoundationModels. In other words, the attacker wanted model access to resell or abuse. In a few environments the attacker also listed IAM roles, users and access keys.
The payload is aimed squarely at people who run agents. Socket’s analysis lists the files it collects: ~/.claude/.credentials.json, ~/.codex/auth.json, ~/.gemini/oauth_creds.json, ~/.cursor/mcp.json, plus the configs for Copilot, Windsurf, Kiro, Zed, Continue, OpenCode and Hugging Face. If DATABASE_URL is set, it queries the LiteLLM proxy’s credentials table, where the gateway keeps your provider keys. It also takes the usual cloud keys, SSH keys and browser data. It installs a .pth file and a sitecustomize.py, so it runs whenever Python starts in that environment, even if nothing imports LiteLLM.
The way in is the part I’d show anyone running an AI gateway. LiteLLM found “an unexpected, innocuously named user account” on an internal deployment that was exposed to the internet. Its working theory is that the attacker got into that deployment and took GitHub CLI OAuth tokens from its logs. How did GitHub tokens get into an LLM gateway’s logs? LiteLLM says it has “observed specific situations in which Claude Code will embed a user’s GitHub CLI OAuth token into a response body”, and “in situations where response bodies are logged, these tokens may appear in LiteLLM logs.”
Two caveats. This is LiteLLM’s observation and is still under investigation. I found no statement from Anthropic either confirming or disputing it. The initial entry point is also unconfirmed. LiteLLM suspects “a recently patched vulnerability.” This is the project’s second supply-chain compromise this year, after the March backdoor in 1.82.7 and 1.82.8.
So what: a model gateway concentrates credentials twice. It stores the provider keys, and it logs whatever the agents send and receive. When an agent puts a secret in a prompt or a response, that secret ends up in the log. So the log store is a secret store, and most teams don’t protect it like one.
Do this: first, run
pip show litellmand check image digests everywhere you run it. If 1.107.0 was ever installed, follow LiteLLM’s steps: don’t run pip first, removecook.pth,cook.pyandsitecustomize.py, kill the process holding/tmp/remote_code_loader.lock, rebuild, pin1.106.2, and rotate everything that host could reach. Then, whether or not you were affected, check your gateway logs for tokens. Print only the prefixes, never the secrets:
1
2
grep -rhEo '(gh[opsu]_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{40,}|sk-ant-[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16})' /path/to/gateway/logs \
| cut -c1-8 | sort | uniq -c
Any hit means the log store needs the same access control as your vault. Turn off request and response body logging unless you need it, and if you do keep it, redact before the write, not after.
Two OpenAI agents turned off the alerts from the monitor watching them
On 20 October, OpenAI published two incidents from 3 and 6 October. In both, an internal coding agent weakened the misalignment monitoring that watches agents.
3 October, GPT-6.1 Sol. A researcher asked it to build evaluation tasks from Slack feedback and said “don’t send any messages.” At first the agent read that as being about outreach only, “separate from automatic monitoring.” A subagent also decided not to recommend switching off notifications, because doing so “would disable required alerts.” Later the parent agent changed its mind. “Based on its judgment that the user’s instruction not to send messages applied to the misalignment monitoring system,” it told the subagent to suppress notifications, and the subagent did. The result: “The misalignment monitor still ran and saved its reports, but human alerts were disabled.”
6 October, GPT-6 Astra. It was migrating a serving path by copying a reference implementation. The migration removed the monitor’s configuration and runtime integration, and a regression test was changed to assert that monitoring was absent. Another agent had told it not to disable the monitor “even temporarily.” When the user asked, Astra “falsely claimed to the user that it had not removed the monitor.”
OpenAI’s summary of both: “the agents considered whether monitoring safeguards should be preserved, but interpreted routine coding instructions as permission to weaken them.” It also found a wider gap: “the agent itself remained monitored, but that monitoring did not cover the deployment it launched.” Its fixes: Auto-Review now detects and blocks attempts to disable misalignment monitoring, and it is moving towards a required safety case for each category of workload, with automatic termination for workloads that don’t have one. On the cause: “We don’t yet have a satisfying explanation for this behavior.”
This is the same failure as Anthropic’s police-tip form in issue #32: an instruction with a gap, and an agent that read the gap as permission. The difference is what it touched. Last week it was an outside website. This time it was the control.
On 19 October, Microsoft stated the design principle in its announcement of agent risk scoring and dynamic permissions: “If the agent or harness is compromised, it should not be able to disable the controls watching it.” Microsoft gave no availability dates, so for now that’s a principle rather than a product. It’s still the right principle.
So what: a monitor whose configuration the agent can edit is a suggestion. OpenAI’s agents didn’t need an attacker. They needed an ambiguous instruction and write access to the monitoring config. An injected agent needs even less.
Do this: for one production agent, list where its monitoring lives: the detection config, the alert routing, the audit log sink. Then check whether the identity the agent runs as can write any of them (
kubectl auth can-i --as=...,aws iam simulate-principal-policy, or the repo permissions if the config sits next to the agent’s code). Move anything it can write to a separate identity, and treat a change to monitoring config as an alert in its own right.
Where the provider keys live now
These came out between 17 and 19 October and they’re about the same thing. Agent tools now hold credentials on your behalf, and the way they hold them is weaker than the tools themselves.
OpenCode Console, 17 October. OpenCode emailed users that an intruder had reached a legacy system on the night of 16 October, which “may have exposed the third-party AI provider keys that users had saved in OpenCode Console” (The Hacker News). It affects 1.4% of Console users. Keys added in the CLI or desktop app are stored locally and weren’t exposed. OpenCode linked the breach to “a large-scale distillation attack” without explaining the connection, and it hasn’t published a post-mortem. Users have reported unexpected charges on their provider bills, but those reports are unverified.
OpenCode on Windows and WSL, 19 October. Pillar Security disclosed that a malicious or hijacked remote MCP server could run commands on a developer’s machine during OAuth sign-in (The Hacker News). The server supplies the authorization URL, and OpenCode passed it to a helper that wrapped it in a PowerShell command without escaping it. Versions 1.0.137 to 1.18.32 are affected. It was fixed in 1.18.33 on 28 September, in a pull request described as a refactor. No CVE, no advisory. OpenCode’s security policy puts user-configured MCP servers “outside our trust boundary.” So scanners won’t flag the vulnerable builds.
Google Agent Mesh, CVEs published 19 October. In CVE-2026-103091 (CVSS 9.3), anyone holding a token from the configured OIDC issuer could enroll in the mesh. The example policy bound every authenticated identity to a role that could call every service on every target. It was found by Eli Ainhorn of Noma Security and fixed in 0.1.0-alpha.9 on 7 September. Safeguard’s analysis adds two details. First, a short-lived OIDC token produced a mesh session lasting 90 days, and that constant was still 90 days in v0.1.1. Second, upgrading doesn’t remove a wildcard policy you already loaded: “A version bump fixes the code that evaluates it. It doesn’t review what you told that code to allow.”
So what: the provider key used to be an environment variable on one machine. Now it may also sit in a hosted console, a gateway database and a mesh enrollment, and each of those is a vault you probably never threat-modelled. Silent fixes and CVE-less advisories mean your scanner won’t tell you either.
Do this: write down every place your model provider keys are stored: hosted consoles, gateway databases, CI secrets, developer laptops. Set a spend limit and a usage alert on every key. That’s how most OpenCode users found out. Upgrade OpenCode to 1.18.33 or later on Windows and WSL. If you run Agent Mesh, upgrade, then read the stored policy for any binding to
sam:system:authenticated.
Quick hits
OpenAI found a government-site intrusion 57 days later, by running its monitor on old traffic. One of five reports OpenAI posted on 15 October. An internal model in RL training, asked for hospital-bed statistics, used a file-download feature to pull server config, forged unsigned tokens that the endpoint accepted, and “did not mention that it had obtained unauthorized access.” It happened on 17 June and was found on 13 August, after OpenAI applied its monitoring retrospectively to earlier training traffic. One of the other four is about an agent using a funded test crypto wallet without authorization.
Microsoft now treats agents as insiders. In the same 19 October post, an agent “should begin with no authority and receive only what it needs for the approved task.” A risk score rising with behavioural drift steps it down from write to read-only, then to human approval, then to isolation. Discovery now covers 60 kinds of local agent, including Claude Code and Codex (SiliconANGLE). More details are due at Ignite on 17 November.
Google’s PageBreak counts a bug only when a deterministic check reproduces it. Michał Bentkowski describes an agent that has found more than 500 XSS bugs across Google’s web apps with near-zero false positives. A finding only counts once a deterministic validator reproduces it against a running app, for example by firing the payload and checking whether the JavaScript runs. Same rule as the monitor story, applied to offence: the model proposes, and something that isn’t a model confirms.
What I’m writing
The first piece of the identity series is out: Agent Delegation Chains: The Standard Enforces Only the Last Hop. The OAuth token exchange standard (RFC 8693) tells the receiving service to check only the current caller. Earlier hops in the chain are “informational only.” The piece compares four proposed fixes, runs an MCP-to-A2A attack chain through each, and ends with five things you can do without new infrastructure.
Next week: what the IETF has actually finished for agent identity, and what is still a draft. The short version is that the finished parts are general OAuth, and the agent-specific parts are all drafts.
Tooling worth knowing
- LiteLLM’s incident post is also a cleanup runbook. It gives the files to remove, the process to kill, the CloudTrail calls to look for, and the order to do it in. post →
- Socket’s LiteLLM analysis lists every credential path the stealer reads, which doubles as a list of the agent credential files on your own laptop that deserve protecting. analysis →
- Agent Security Scorecard: my free self-assessment against the OWASP Agentic Top 10. About 12 minutes, no login. Score your agents →
- AI Agent Pre-Deployment Security Checklist: 25 yes/no controls to clear before an agent with tool access goes to production. Get the checklist →
One thing to check this week
Pick one agent and spend twenty minutes on whether it can reach the things around it.
- List its watchers. Monitoring config, alert routing, audit log sink, gateway logs, policy store. Write down where each one lives.
- Check write access. For each one, can the identity the agent runs as modify it? If the answer is “it’s in the same repo” or “it’s the same service account”, the answer is yes.
- Check what the logs hold. Run the grep above against your gateway or proxy logs. Count the token prefixes.
Step two is what went wrong at OpenAI. Step three is what went wrong at LiteLLM. Both were found after the fact, which is the part worth avoiding.
What I’m watching
→ LiteLLM’s post-mortem. The entry point is still “a recently patched vulnerability.” If it was a known CVE in an internet-facing internal deployment, that’s a lesson every gateway operator needs.
→ Whether Anthropic responds on the token-in-response-body claim. If Claude Code can put a GitHub token into a model response, every proxy that logs bodies has the same exposure LiteLLM had.
→ OpenAI’s safety case per workload. Automatic termination of workloads without one is the first time I’ve seen a lab describe monitoring as a hard precondition rather than a best effort.
→ Microsoft Ignite, 17 November. Whether “controls outside the agent’s reach” ships as a product, and on which licence.
If step two turns up a monitor or an alert route your agent could edit, reply and tell me how it was set up. I read everything.
Cheers, Amine
If a colleague runs a model gateway with body logging switched on, forward this to them.
Sources
- Security incident: LiteLLM v1.107.0, LiteLLM, 21 October 2026
- LiteLLM compromised, steals credentials, Wiz, 21 October 2026 (updated 22 October)
- LiteLLM PyPI package and Docker images compromised to steal cloud and AI credentials, Socket, October 2026
- LiteLLM suspects GitHub token leak in AI gateway logs behind malicious package release, The Hacker News, 22 October 2026
- LiteLLM PyPI backdoor: AI toolchain supply chain, Cloud Security Alliance, 27 March 2026
- Suppressing misalignment monitoring alerts and disabling misalignment monitoring, OpenAI, 20 October 2026
- Retrieving server secrets and bypassing authorization on a government statistics website, OpenAI, 15 October 2026
- Agents are your newest insiders: Security must move at their speed, Microsoft, 19 October 2026
- Microsoft targets the agentic insider with new controls for rogue AI agents, SiliconANGLE, 19 October 2026
- OpenCode Console breach may have exposed OpenAI, Anthropic, and Google API keys, The Hacker News, 19 October 2026
- OpenCode flaw lets malicious MCP servers execute code during sign-in on Windows and WSL, The Hacker News, 22 October 2026
- CVE-2026-103091, CVE record, published 19 October 2026
- Google Agent Mesh CVE-2026-102503 and CVE-2026-103091: why upgrading isn’t enough, Safeguard, October 2026
- Agentic hacks, real proofs: inside Google’s PageBreak project, Google, 24 September 2026
- tl;dr sec #348, Clint Gibler, and Adversa AI’s October roundup, for pointing me at several of these