LiteLLM's Root-Cause Report Says the Poisoned Release Began With an Admin Key Committed to a Public Repo on May 27 and Never Revoked. The 'Tokens in Logs' Theory Is Out. Four IPs Are in Our Feed.

If you ever committed a key to a repository and then deleted it, rotate it today, because deleting did not protect LiteLLM. Its own root-cause analysis, dated October 23, 2026, says the poisoned litellm 1.107.0 release began with an administrative key committed to a public repository on May 27 and never revoked. The attacker used it 136 days later. That replaces the explanation we repeated on October 22, which was that GitHub tokens ended up in the logs of an internal deployment.

What LiteLLM's analysis says
The key. On May 27, 2026 at 18:53 UTC, an opencode.json file was committed to the public LiteLLM-Labs/lite-harness repository. It held an administrative key for an internal deployment of LiteLLM's Agent Platform. A later commit deleted the file about three hours afterward, but the original commit stayed in the public history until October 22. The key was never revoked.
The first use. On October 10, between 21:13 and 21:28 UTC, the attacker made authenticated requests to the Agent Platform API from 69.48.229.143. At 21:27 one request listed every managed agent, and the response included the GitHub command-line token of one of two organization owners. That gave the attacker owner-level access to the GitHub organization.
The harvest. About 45 minutes later, a workflow pushed on a temporary branch in the main litellm repository sent six repository secrets, including a second maintainer's token, to a webhook.site endpoint, and the run was deleted within three minutes. Twenty-four seconds later a similar workflow in a second repository sent a third maintainer's release token to the same place. A later round on October 12 sent more secrets from private repositories, which the analysis says were not on the path to the poisoned release.
The release. On October 21 at 10:08 UTC a push to the release repository was rejected by branch protection when made with the second maintainer's token, and succeeded five seconds later with the owner's token, which overrode protection. The commit let the release build from a fork. At 10:46 the staging workflow ran against a lookalike organization, Berri-AI instead of BerriAI. At 11:11 the production gate was approved with the second maintainer's token, from 199.91.221.39. Seven wheels went to PyPI between 11:39 and 11:40, and the container images followed at 11:46. LiteLLM says it had loosened the release rule earlier that week so any two engineers could trigger and approve a release, and the attacker used two separate tokens, which the analysis believes was meant to avoid noisy audit logs.
The cover. Around 11:54 the run records for production and staging were deleted. A revert commit at 12:09 and a force-push of main at 12:24 overrode the protections too. Both commits can still be fetched by their IDs, and the organization audit log recorded the overrides.
LiteLLM says the bad packages were live for about two hours, that it assumes every token, key and authenticator was taken and is revoking them all, and that process changes will come in a later post.
What changed from what we said on October 22
On October 22 we wrote that GitHub tokens for three developers ended up in the logs of an internally exposed deployment, citing the reports then available, and said the cause was not confirmed. LiteLLM's analysis retracts that theory. It says the first token came from the Agent Platform API, a different service, and the other tokens came from CI secrets. Reporting in late October also relayed an explanation in which Claude Code can embed a user's GitHub token in a response body that then gets logged. The analysis does not mention Claude Code, so we are not relying on that. We are leaving the October 22 post as it stands, because it was hedged and matched the sources at the time, and this post carries the update.
The pattern worth taking away
This is the case Truffle Security described on November 4, which we covered in "Truffle Security Says 81% of Leaked Keys It Reported Were Still Valid Six Months Later." A key leaked, was removed within hours, and stayed valid for months because nobody revoked it. The deletion made the repository look clean, and the history still held the key. Everything after that, the owner token, the bypassed branch protection and the lookalike fork, followed from one unrevoked string.
What to do
- Treat any key that was ever committed as exposed, whether or not you deleted it. Revoke it at the issuer, then clean up.
- Search your git history, not just your current files. Our free scanner, claude-settings-leak-check, covers Claude Code settings files only. For full history use a tool built for it, such as TruffleHog or gitleaks.
- Do not use broad command-line OAuth tokens for automation. The analysis itself calls for scoped tokens.
- Make branch protection hard to override, and alert on any override. Here the override was logged and nobody was watching.
- Require a different, scoped identity to approve a production release, and keep the approving token out of any place an API can read.
- Alert on workflow runs that are deleted soon after they finish.
- If you ran litellm 1.107.0 at any time on October 21, follow LiteLLM's incident guidance and rotate everything that host could read.
Indicators
We added four IP addresses to the feed under the source manual-batch-litellm-1107-rca-2026-11. 69.48.229[.]143 made the Agent Platform API calls on October 10, and 199.91.221[.]39 approved the production release on October 21. Both are cited to LiteLLM's analysis, at confidence 85. The analysis does not say who owns either address, so treat them as leads for your logs and not as proof about a hosting provider. 168.100.8[.]57 and 165.227.201[.]8 were reported as addresses that tested stolen cloud credentials on October 21. We have that only secondhand, through The Hacker News citing Wiz, and went in at confidence 70. The analysis also names a webhook.site endpoint used to collect secrets. We did not add it, because webhook.site is a shared public service that thousands of legitimate users rely on and blocking it would hurt them. The lookalike GitHub organization Berri-AI and the commit IDs are there for your own searches. The analysis names no attacker accounts.
Block coverage of an address is not the same as detecting this campaign. We did not see these addresses at our own edge, and we make no claim of an earlier sighting. The credit for this research belongs to LiteLLM and the researchers who worked the incident.
Limits
We read LiteLLM's root-cause analysis and The Hacker News. We did not read Wiz's, StepSecurity's or Microsoft's own write-ups for this post, and we did not examine the repository history ourselves. The timeline is LiteLLM's account of its own breach. It does not explain how the attacker found the key in a public commit, and it says process changes are still to come.
Five percent of this is wrong somewhere. It always is. LiteLLM's promised follow-up on its process changes will correct or extend parts of it.
Every indicator in this post is in the feed. Free.
1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.