Skip to content

Security Alert | LiteLLM Supply Chain Attack — Root Cause Update: An Unrevoked Master Key Leaked Five Months Earlier

Oct 26, 20261 min
TL;DROn October 24, LiteLLM published its full attack-chain investigation and retracted the October 23 theory that Claude Code's response logging leaked the GitHub token. The confirmed root cause: an Agent Platform master key leaked on May 27, 2026 into a public repo and was never actually revoked. On October 10, attackers used that key to steal an over-scoped (org-owner-level) GitHub token, then used throwaway branches with push-triggered workflows that self-deleted within minutes to steal more secrets almost invisibly, before hijacking the release pipeline on October 21. Defense: once a credential has leaked, assume it's compromised and force revocation even if the commit was overwritten; auditing GitHub Actions can't rely on existing branches alone — check the activity log.

Look up & save

Loading dictionary…

🌏 中文版

Summary

On October 24, LiteLLM published its complete attack-chain investigation into the October 21 supply chain attack (the malicious v1.107.0 build shipped to PyPI, Docker Hub, and GHCR), and pushed the root cause back nearly five months — formally retracting the earlier theory. The hypothesis covered in this series on October 23 — that Claude Code had embedded a user's GitHub CLI OAuth token in a response body, which then got logged by an exposed internal deployment and leaked — has now been officially ruled out. The real starting point was an accidental commit on May 27, 2026 that leaked LiteLLM Agent Platform's master key, which was never actually revoked afterward. The update also adds technical detail Socket.dev dug up: attackers used a technique of creating short-lived branches that trigger an auto-run workflow and get deleted within minutes, leaving the credential theft almost invisible in ordinary repo history.

Key facts

ItemValue
Incident typeSupply chain attack (root cause: a long-unrevoked leaked credential combined with an over-scoped token)
ScopeSame affected population as the October 23 report (LiteLLM v1.107.0 users); this update revises the root cause and attack technique, not the blast radius
SeverityCritical
CVENone (LiteLLM treats this as a supply chain incident, not a single code vulnerability)
SourcesThe Hacker News, LiteLLM's official attack-chain report, Socket.dev, Microsoft Security Research

Attack Surface Analysis

The full timeline is longer and more detailed than what was reported on October 23:

Full timeline of the LiteLLM supply chain attack (official Oct 24 update)
Full timeline of the LiteLLM supply chain attack (official Oct 24 update)From a leaked master key in May to the release-pipeline hijack on October 21, with two near-invisible credential-theft runs in between. 05-27 master key leak never revoked after 10-10 GitHub token stolen org-owner level more secrets via self-deleting branches two rounds, traces wiped in minutes 10-21 release pipeline overridden repointed to lookalike repo v1.107.0 published PyPI / Docker / GHCR
  1. 2026-05-27: Agent Platform master key accidentally committed to a public repo, never revoked afterward
  2. 2026-10-10 22:11 UTC: attacker uses the master key to steal an over-scoped GitHub token
  3. 2026-10-10 / 10-12: two rounds of credential theft via self-deleting branches running push-triggered workflows
  4. 2026-10-21 10:08-11:08 UTC: branch protection overridden, release pipeline repointed to a lookalike repo
  5. 2026-10-21 11:39 UTC: malicious v1.107.0 published to PyPI, Docker Hub, and GHCR

It started on May 27, 2026, when a configuration file was committed to the public LiteLLM-Labs/lite-harness repo and accidentally contained the master key for LiteLLM Agent Platform — the tool the team uses internally to orchestrate coding agents. The team quickly spotted it and force-pushed over the commit, and judged that the leaked key needed to be revoked — but the master key itself was never actually revoked. That unrevoked key sat exposed for nearly five months until the night of October 10 (22:11–22:12 UTC), when an attacker used it to log into Agent Platform and extract a GitHub CLI OAuth token that was meant to let self-hosted cloud agents file pull requests on behalf of the service. The problem: that token "wasn't scoped down" — it was tied to the GitHub organization owner's account, so one step handed the attacker owner-level access across every repo in the organization. This is a textbook case of OWASP LLM06 Excessive Agency applied to a supply-chain setting: a credential granted to an agent tool carried far more scope than the task it was meant to perform (filing PRs), so a single leak became total compromise.

Rather than touching the release pipeline right away, the attacker first spent time stealing more credentials — using a technique Socket.dev later reconstructed from GitHub's activity logs. In two internal repos, BerriAI/litellm and BerriAI/litellm-auto, the attacker branched off a legitimate recent commit into a short-lived branch named ci-tmp-<hex>, pushed a workflow file (.github/workflows/cache.yml) with a commit message deliberately mimicking routine maintenance ("ci: bump cache config"), configured it to trigger on every push, let it run, and deleted the branch within minutes. Both runs (October 10 and October 12) completed so fast that, as Socket's researcher put it, the activity "leaves almost nothing behind in the repository's ordinary history" — only the activity log, not the branch list, reveals it happened. The first run harvested GitHub tokens and API keys for the team's Linear workspace, the LiteLLM deployment itself, and Together AI, plus the identifier and signing key of a GitHub App. The second run expanded the haul to API keys for Anthropic, OpenAI, AWS Bedrock, and Tavily — and, notably, the API key for GitGuardian, the very secret-scanning platform meant to catch this kind of leak, meaning the attacker gained the ability to see, and potentially suppress, the alerts that would have surfaced their own activity.

The actual release-pipeline hijack came on the morning of October 21: the attacker disabled branch protection and repointed the release source to a lookalike repo, Berri-AI/litellm, one hyphen off from the real BerriAI/litellm. This succeeded in part because of a timing coincidence: LiteLLM's normal release process requires one engineer to trigger a release and a separate, device-locked account to approve it, but that week the rule had been temporarily relaxed — to speed up bugfix backports — to let any two engineers trigger and approve each other's releases. The attacker, already holding two sets of maintainer-level credentials, simply plugged into that relaxed process. Tellingly, the attacker had org-owner-level access and could have disabled or rewritten the rule outright, but chose not to — likely to avoid leaving a more obvious trace. In other words, a routine, well-intentioned loosening of release controls the day before happened to open exactly the window the attacker needed.

Defense

Immediate actions

  • If your organization has ever accidentally committed a master key or any long-lived credential to a public repo, treat it as compromised and actually complete revocation, even if the commit was later overwritten — don't just mark it "pending revocation" and move on. The root cause here was precisely the gap between deciding a key needed revoking and actually revoking it.
  • Audit the scope of GitHub tokens issued to agents or automation: check whether any are unnecessarily tied to an organization-owner account, and replace them with fine-grained tokens scoped to specific repos and operations.
  • Check GitHub Actions activity logs, not just the current branch list, for the pattern of "create a short-lived branch, push a push-triggered workflow, delete the branch within minutes" — this is the newly disclosed technique, and it's invisible if you only look at existing branches.
  • Review any temporary relaxation of release or approval permissions: confirm it has an expiry and a clear rollback mechanism, so "temporary" doesn't quietly become permanent.

Long-term architecture

  • Leaked-credential handling needs an enforced closed loop: detect leak → mark for revocation → actually revoke → verify revocation took effect. All four steps are required; consider automated reconciliation between "marked pending revocation" and "still valid" credential lists.
  • Protect AI, from this site's watchlist, offers supply chain scanning that can watch AI toolchain packages like LiteLLM for tampered releases or build configs — but the root cause here sits in credential lifecycle management, which scanning alone won't fix; pair it with a secrets-management platform that enforces revocation audits.
  • CI/CD systems that allow on: push auto-triggered workflows deserve extra scrutiny: short-lived branches followed by immediate deletion is a detectable pattern (e.g., alert when a branch's lifetime falls below a threshold) rather than something you only discover by manually combing through the activity log.

Impact

This update doesn't expand the affected population reported on October 23 (still users who installed v1.107.0 during the October 21 UTC morning window) — its significance is correcting the root cause. The earlier suspicion that Claude Code's response logging leaked the OAuth token has now been officially excluded; the real source traces back to a credential leak from six months earlier that was never properly cleaned up. Microsoft's malware analysis also adds persistence detail: v1.107.0 executes automatically at Python interpreter startup via .pth files and sitecustomize.py, triggering even if litellm is never imported, and because those startup files sit outside the LiteLLM application directory, removing only the application's own files can leave the malicious startup components behind. For any team running an agent platform that issues credentials so automation can act on GitHub or cloud resources, this incident demonstrates how an over-scoped credential and an incompletely revoked leaked credential compound into something far worse than either problem alone.

Today's Takeaway

The October 23 report used the word "suspected" root cause, and this update directly overturned that theory — a reminder that early attribution in a security incident is often provisional, and should be revisited as the official investigation progresses rather than treated as final on day one. What's more striking is how far back the real root cause traced: a leak that was "overwritten and flagged for revocation" sat unresolved for nearly half a year before it was actually exploited, because the revocation itself was never completed. The lesson worth keeping isn't just "credentials leak" — it's that the step between identifying a risk and actually eliminating it, confirming the fix was really carried out, is often the easiest one to drop.

References