
A LiteLLM Master Key Leaked in May. Nobody Revoked It. In October, It Hijacked a Release.
LiteLLM's second supply-chain compromise of 2026 traces back to a config file that was force-pushed over but never fully cleaned up — and a release-approval rule relaxed the same week.
CVE Tools4 min read
On October 21, 2026, LiteLLM — the open-source LLM gateway built by BerriAI and run in production by companies including NVIDIA, Netflix, AT&T and Okta — shipped a credential-stealing backdoor as a routine PyPI release. It is the second time this has happened to LiteLLM in 2026. Our read: the proximate cause was a textbook release-pipeline hijack, but the root cause was a half-finished incident response from May — a master key the team said it would revoke and never did — compounded by a release-approval shortcut taken the very week the attack began. The lesson for anyone running LiteLLM isn't "rotate harder." It's that an incident isn't closed until every credential it touched is confirmed dead, not just flagged for later.
The timeline
From a leaked config file to a poisoned release
- Master key leaksA config file (
opencode.json) holding the LiteLLM Agent Platform master key is committed to the public repoLiteLLM-Labs/lite-harness. The team force-pushes over the commit and flags the key for revocation — but the key is never actually revoked. - Key weaponizedAn attacker makes authenticated calls to the Agent Platform API using the leaked key. One call to
/api/v1/managed_agents/agentsreturns a GitHub org owner's OAuth token — unscoped and not tied to a service account. - Secrets exfiltrated, tracks coveredTwo throwaway branches on BerriAI repos run CI workflows that leak seven repo secrets — including two more maintainers' tokens — to a webhook.site endpoint. Both workflow runs are deleted minutes later.
- Branch protection overriddenA commit rerouting the release build source is blocked once, then force-pushed through after the attacker disables branch protection with the stolen org-owner token.
- Lookalike repo signed and releasedA second stolen maintainer token approves a production release built from
Berri-AI/litellm— a one-character typosquat of the realBerriAI/litellm. - Malicious package goes live
litellm==1.107.0publishes to PyPI across all seven wheels; matching Docker Hub and GHCR image tags follow within minutes. - Caught in under 20 minutesIndependent researcher LidorMachluf publicly flags the compromise on GitHub issue #47826.
- ContainedPyPI, GHCR and Docker Hub pull the artifacts. Total time live: roughly two hours.
A startup hook, not an import
The attacker didn't touch LiteLLM's actual application code. Three files — cook.pth, cook.py and sitecustomize.py — were planted in the package's site-packages directory. Python processes .pth files and imports sitecustomize automatically on every interpreter startup, before any application code runs. That meant simply running python or pip to inspect a poisoned install was enough to trigger the payload — importing litellm was never required.
- Cloud and infrastructure credentials: AWS, Azure, GCP, Kubernetes and Docker
- AI-specific secrets: coding-assistant auth files plus LiteLLM's own stored provider API keys and model configs
- Developer secrets: Git, GitHub, npm, PyPI and CI/CD tokens,
.envfiles, SSH/GPG/TLS keys - Browser data: saved logins, cookies, autofill and payment data
- Host and runtime data: environment variables, shell history, system and network info
A corner cut the same week
The gap between "flagged" and "fixed"
- Force-pushed over the exposed commit
- Flagged the master key for revocation
- Treated the exposure as handled
- Actually revoke and rotate the master key
- Audit everything the key could reach
- Verify revocation before closing the incident
LiteLLM's second compromise this year
| March 2026 | October 2026 | |
|---|---|---|
| Actor | Self-named "TeamPCP" | Unidentified; used a leaked internal key |
| Entry vector | Compromised Trivy CI/CD scanner | Unrevoked Agent Platform master key |
| Malicious versions | 1.82.7, 1.82.8 | 1.107.0 |
| Payload | AWS/SSH/Kubernetes/DB credential harvester | Cloud, AI, dev and browser credential stealer plus remote payload loader |
| Containment time | PyPI quarantined within 46 minutes | ~2 hours across PyPI, Docker Hub and GHCR |
| Clean version to pin | 1.82.6 | 1.106.2 |
Two unrelated entry vectors, four and a half months apart, both ending the same way: a poisoned PyPI release reaching every environment that updated. That repetition is itself the story — AI-gateway libraries sit on the same trust path as the cloud and model-provider credentials they route, which is exactly what makes their release pipelines worth automating an attack against.
What to do if you run LiteLLM
- Don't run
pip installor even a barepythoncommand in a potentially affected environment — either can re-trigger the loader. - Pin to
litellm==1.106.2, ideally by digest, and rebuild virtual environments and containers from scratch rather than patching in place. - Treat any host that ran 1.107.0 with outbound internet access as exfiltrated.
- Rotate everything the host could read: cloud IAM credentials, every provider API key stored in the LiteLLM proxy database, master and virtual keys, and the database password.
- Audit CloudTrail (or your cloud's equivalent) for
GetCallerIdentitycalls and other use of the credentials the host held.
Data as of October 25, 2026
Sources: LiteLLM's canonical incident report and attack-chain writeup, the original disclosure thread on GitHub (BerriAI/litellm issue #47826), Microsoft's independent technical analysis of the Python startup-hook mechanism.