Unrevoked LiteLLM Master Key Leads to Release Pipeline Hijack

Une clé maîtresse LiteLLM non révoquée mène au détournement de la chaîne de publication

On October 21, 2026, a trojanized version of LiteLLM, the widely used open-source gateway for accessing AI models, was published to PyPI and Docker Hub by the project’s own release pipeline. LiteLLM’s root-cause analysis, published October 23, traces it back to a mundane mistake: an administrative key pushed to a public repository in May, deleted from the file but never revoked. Five months later, that key gave the attacker a GitHub organization owner’s token, and from there the release pipeline. It is a direct lesson for every team deploying AI agents that hold credentials.

Key takeaways
  • A master key for an internal agent platform, exposed on May 27, 2026 in a public GitHub repository, was never revoked.
  • On October 10, the attacker used it to retrieve an organization owner’s GitHub CLI OAuth token, then exfiltrated CI secrets and the tokens of two more maintainers.
  • On October 21, the attacker overrode branch protection and published litellm==1.107.0 (7 PyPI wheels) plus compromised Docker images.
  • The malicious code runs every time Python starts, even without importing LiteLLM, and steals cloud credentials, SSH keys, CI secrets, AI provider API keys and AI coding tool configurations.
  • Any host that installed 1.107.0 must be treated as compromised: uninstalling the package is not enough.
Artifactslitellm 1.107.0 (PyPI) · Docker tags v1.107.0, latest, main-latest, main-stable
Exposure windowOctober 21, 2026, 11:39–14:20 UTC
Last known safe version1.106.2
SeverityCritical — credential theft

The attack chain

LiteLLM calls its October 23 analysis “the canonical source of truth”. It supersedes the provisional explanations in the October 21 incident notice. The chain unfolds in seven steps.

Date (UTC)Step
May 27, 18:53An opencode.json file containing an admin key to the LiteLLM Agent Platform is committed to the public LiteLLM-Labs/lite-harness repository. It is deleted three hours later but remains in history, and the key is not revoked.
October 10, 21:13–21:28The attacker calls the agent platform API; an agent listing request returns an organization owner’s GitHub CLI token.
October 10, 22:11–22:14Workflows pushed to temporary branches post CI secrets (including GH_TOKEN and RELEASE_PLEASE_TOKEN) to a webhook.site endpoint, then the runs are deleted.
October 12Secrets from several private repositories are exfiltrated the same way.
October 21, 10:08A release-workflow change, rejected by branch protection, is forced through with the owner’s token. It allows building from the lookalike fork Berri-AI/litellm.
October 21, 11:11–11:47The production approval gate is passed with a second maintainer’s token; seven 1.107.0 wheels, then Docker Hub and GHCR images, are published.
October 21, 11:53–11:54Run records are deleted with a third maintainer’s token.
October 21, 12:06 → 14:20An Upwind Security researcher reports the compromise; PyPI quarantines the package by about 13:23 and Docker tags are removed or repointed at 14:20.

Why a single key was enough

LiteLLM Agent Platform is an experimental project for self-hosted cloud agents that open pull requests. To do so, it held not a narrowly scoped token but the GitHub CLI OAuth token of an organization owner. According to LiteLLM, such tokens are unscoped, issued post-2FA and not subject to the re-authentication required for sensitive actions. Compromising the agent therefore meant obtaining owner rights.

Two other factors made things worse. The release workflow had been changed to accept an arbitrary source owner, enabling a build from a lookalike fork. And the release approval rule had been relaxed that very week: any two engineers could approve, instead of a dedicated account tied to a physical device.

Payload analysis

According to Corgea’s analysis, the attacker added a cook directory to the package build data. The wheels thus installed three files at the site-packages root: cook.pth, cook.py and sitecustomize.py. The sdist and the official source tag stayed clean, which kept the change out of sight in the code.

Execution and persistence

Python executes the .pth file at every interpreter start: the stealer runs even if LiteLLM is never imported. sitecustomize.py also launches a detached daemon (lock file /tmp/remote_code_loader.lock) that, every hour, fetches a hostname from a GitHub file, downloads Python code and executes it. No second stage has been observed so far.

What gets stolen

Browser passwords and cookies, SSH, GPG and TLS keys, AWS, GCP and Azure credentials (including via metadata services), Docker and Kubernetes secrets, CI configurations, Vault tokens, package registry credentials, environment variables and AI coding tool configurations. Specific to LiteLLM: the code queries the proxy’s credentials table, which holds model provider API keys. Data is encrypted (AES-256 and RSA-4096) and sent to litellm.dev, a lookalike of the legitimate litellm.ai.

Caveats. The attacker has not been identified. Download and victim counts have not been confirmed by LiteLLM. Payload details come from third-party analyses (Corgea, also citing Microsoft), not from LiteLLM’s analysis, which deferred its process changes to a later write-up. Sources differ on the recommended fixed release: check the official notice before upgrading. This incident is separate from the March 2026 LiteLLM compromise.

Why it matters

LiteLLM sits at the heart of AI architectures: by design, it concentrates the API keys of every model provider an organization uses. Compromising it yields a full keyring. But the lesson goes beyond this project. An AI agent acting on your repositories holds credentials, and those credentials become the target. An oversized token handed to an experimental agent was enough to turn a forgotten configuration leak into a software supply chain compromise.

And deleting a file revokes nothing. A secret pushed to a public repository must be considered compromised from the first second.

MITRE ATT&CK view

The sources do not provide an ATT&CK mapping. The table below is an indicative Defensy reading based on the behaviors described.

TechniqueObserved behavior
T1593.003 — Search Open Websites/Domains: Code RepositoriesAdmin key recovered from a public repository’s history
T1078 — Valid AccountsUse of the master key, then maintainer tokens
T1528 — Steal Application Access TokenTheft of the GitHub CLI OAuth token and CI secrets
T1567.004 — Exfiltration Over WebhookCI secrets posted to webhook.site
T1070 — Indicator RemovalDeletion of workflow runs
T1195.002 — Compromise Software Supply ChainRelease of 1.107.0 through the official pipeline
T1546 — Event Triggered ExecutionExecution at every Python start via .pth and sitecustomize.py
T1552.005 — Cloud Instance Metadata APIQueries to cloud metadata services

Recommendations

  1. ImmediateCheck for exposure to 1.107.0

    Look for Version: 1.107.0 in installed metadata, for cook.pth, cook.py and sitecustomize.py in site-packages, and for /tmp/remote_code_loader.lock. Review images pulled on October 21 with the latest, main-latest or main-stable tags.

  2. ImmediateTreat affected hosts as compromised

    Isolate them, stop the loader, and rebuild environments and images from clean inputs, pinning a verified version (1.106.2 or a release LiteLLM confirms as clean) and images by digest.

  3. ImmediateRotate every exposed secret

    AI provider keys stored in the proxy, cloud, Kubernetes, CI, registry, SSH and AI tool credentials. Review CloudTrail and equivalent logs from October 21, 11:39 UTC onward, and outbound traffic to litellm.dev.

  4. Short termReduce AI agent privileges

    Give each agent a dedicated service account and least-privilege tokens, never an administrator’s personal token. Inventory the credentials held by your agents and automation platforms.

  5. Short termRevoke first, clean up later

    Enable secret scanning at the source (push protection) and formalize a rule: any exposed secret is revoked immediately, even if the commit was deleted.

  6. Medium termHarden your own release pipeline

    Prevent admins from bypassing branch protection, hard-code the source repository in release workflows, verify provenance and diff package contents against the previous release (alert on any new .pth).

  7. Medium termPin dependencies

    Use lockfiles with hashes and digest-referenced images rather than floating versions and tags.

Defensy’s view

Nothing about this incident is exotic: a forgotten secret, an overpowered token, a poorly isolated AI agent. That is exactly why it should worry you. AI agents are privileged identities and must be governed as such.

Our Secure AI Adoption offering helps you scope the rights and secrets of your agents and LLM gateways. Our SOC, Detection & Response team can support you with compromise hunting and secret rotation.

References
  1. The attack chain behind the v1.107.0 LiteLLM releaseLiteLLM — O. Jensen, M. Wang — October 23, 2026
  2. LiteLLM 1.107.0 PyPI and Docker compromise (cook.pth, sitecustomize)Corgea — October 22, 2026, updated October 24
  3. The Unrevoked Key: Agent Credential to LiteLLM Release HijackCloud Security Alliance Labs — October 2026
  4. Leaked LiteLLM master key let attackers hijack the release pipelineThe Hacker News — October 2026