LiteLLM Compromise and the New Insider Risk: Coding Agents & Unmanaged Identities

How a leaked coding agent key led to the poisoned LiteLLM 1.107.0 release: the full attack chain, what to fix at each step, and signals to watch.

Oct 27, 2026

On October 21, 2026, a poisoned litellm==1.107.0 spent about two hours on PyPI, Docker Hub and GHCR, stealing credentials from every machine that installed it.

LiteLLM's candid root-cause analysis and Socket's timeline show how the compromise happened, starting from a key leaked from an AI coding agent's config in May, three stolen GitHub CLI tokens, and secret-stealing CI workflows that ran 11 days before the release.

Each failure on its own is mundane: a plaintext key in a coding agent's config, automation running on a person's token, CI secrets any branch can read, a leak handled by deleting the commit. Together they make a new kind of insider risk. Coding agents work with a developer's access and read whatever keys sit in their configs, while the non-human identities (NHIs) they touch, such as API keys, tokens and service accounts, are rarely inventoried, scoped or watched. One leaked key turned an outsider into an org owner, and then into the publisher of a package other companies install and trust.

LiteLLM attack timeline: the chain at a glance

‍

ALT: Diagram of the LiteLLM attack chain, from the leaked Agent Platform master key to the poisoned litellm 1.107.0 release, with a timeline of the 11 days between October 10 and October 21.

Stage 1: A coding agent config leaks a master key

What happened. On May 27, an opencode.json, the OpenCode coding agent's config, was pushed to a public LiteLLM repository with the master key of LiteLLM's internal Agent Platform in it. The commit was cleaned up, and the key stayed valid for four and a half months.

Why it worked. The key sat in plaintext in a file the agent reads, and project-level agent and MCP configs are easy to commit by accident: Cyera researchers found hundreds of publicly accessible files holding AI platform credentials, and MCP configs routinely carry keys in cleartext. The cleanup then removed the commit but never revoked the key, and deleted commits survive in forks and public archives such as GH Archive (see why deleting Git commits isn't enough). The same mistake preceded Cloudflare's 2023 breach, through Okta-leaked credentials believed unused and never rotated, and Trivy's March 2026 compromise, where Aqua's advisory says rotation "was not atomic".

What to do instead.

  • Turn on push protection everywhere, with custom patterns for in-house key formats.
  • Keep long-lived keys out of agent configs; fetch short-lived credentials at runtime.
  • Revoke first, clean history second, and confirm the old key is dead.

In Cyera, Agent Guardian inventories the coding agents and MCP servers on developer endpoints, so a config holding a live key shows up before it is committed. 

ALT: Cyera Agent Guardian inventory of a coding agent's configuration, flagging a config file that holds a live plaintext key.

Stage 2: From a platform key to an org owner's GitHub token

What happened. On Oct 10, the attacker called the Agent Platform's API with the master key from 69.48.229.143. GET /api/v1/managed_agents/agents?limit=100 returned every agent's config, and one held a GitHub CLI OAuth token belonging to an owner of LiteLLM's GitHub organization. The leaked key wasn't a GitHub credential, but it could read one.

‍Why it worked. An application was running on a person's credential. A GitHub CLI token carries its user's full reach, never expires and isn't scoped to the agent's job; LiteLLM notes it also skips the second-factor prompt on sensitive org actions. The agent platform had become a store of human credentials behind a single key.

What to do instead.‍

  • Know which tokens have admin reach and keep sensitive tokens to a minimum.
  • Give automation its own identity: a GitHub App with fine-grained permissions and short-lived installation tokens.
  • When an agent acts for a person, prefer delegation per task, with scoped and short-lived tokens, over long-lived or over-privileged tokens.

Below is an illustrative example from Cyera Identity, showing a classic personal access token with its owner, scopes and age, flagged as over-permissive and unrotated.

‍

ALT: Cyera Identity view of a GitHub classic personal access token with its owner, scopes and age, flagged as over-permissive and unrotated.

Stage 3: CI workflows as the exfiltration channel

What happened. On Oct 10, 44 minutes after reading the owner's token, the attacker pushed a temporary branch adding .github/workflows/cache.yml with on: [push]. Per Socket's reconstruction, a single step bundled six secrets, base64-encoded them and POSTed them to webhook.site. Among them, and in a sibling run against a second repository, were two maintainers' personal GitHub CLI tokens. On Oct 12, a second run, with jobs bound to deployment environments, took 14 more secrets, including database and Redis credentials.

Why it worked. Personal and sensitive tokens were stored as Actions secrets, a push to any branch could read them, and the environments holding database credentials accepted jobs from a branch minutes old.

What to do instead.

  • Don't store GitHub credentials in GitHub; use GITHUB_TOKEN or a GitHub App installation token.
  • Prefer federating with OIDC instead of static keys wherever possible.
  • Put unavoidable secrets behind environment protection rules (branch restrictions, required reviewers), and scope org secrets to the repositories that need them.

By keeping an inventory of sensitive repository and organization secrets, you can flag overshared secrets, understand their usage, and control blast radius. 

‍

ALT: Cyera Identity inventory of GitHub repository and organization secrets, flagging secrets shared with more repositories than they need.

Stage 4: The payload sweeps endpoints for secrets

What happened. litellm==1.107.0 was live from 11:39 UTC until 13:23 on PyPI and 14:20 in Docker images. Per Datadog Security Labs, cook.pth and sitecustomize.py ran at every Python start, even in processes that never imported LiteLLM. The stealer, cook.py, took:

  • Cloud credentials, including from instance metadata
  • Kubernetes, Vault and Terraform secrets
  • SSH keys, and Git, npm and PyPI tokens
  • .env files and shell history
  • LLM provider keys and AI tool sessions
  • Browser passwords
  • On a proxy with a database, the stored upstream provider keys

It sent them encrypted to litellm[.]dev/healthcheck and checked a GitHub dead drop hourly for more code.

Why it matters. Credentials were the goal at every hop, and this last one was no different. You can't stop every poisoned dependency, so ideal posture assumes one will run and leaves it nothing to take. Blast radius is more than the packages installed: it’s the credentials a host can reach.

What to do instead.‍

  • Scan endpoints for secrets: keys in agent and MCP configs, .env files, shell history and cloud CLI profiles on developer machines and build hosts. Move them to a secrets manager or short-lived credentials.
  • Shrink the blast radius: pin dependencies and use separate keys per environment. Suppliers should also require hardware-bound release approval; LiteLLM's had been relaxed to any two engineers.
  • If you installed 1.107.0: follow LiteLLM's cleanup, then rotate everything the host could reach from a clean machine and hunt for use since 11:39 UTC.

In Cyera, Agent Guardian scans developer endpoints for secrets and alerts on API keys held by local AI tools, agents and MCP servers.

ALT: Cyera Agent Guardian alert for an API key found on a developer endpoint by endpoint scanning.

How to detect stolen token abuse: signals to watch

Every stolen credential in this chain behaved in a way it never had. Three shapes cover it:

  • New consumers. A credential used from a network, client or workflow it has never been used from. The master key called from 69.48.229.143 on Oct 10, then the owner's token pushing from attacker infrastructure 44 minutes later, 11 days before the release, were the earliest signals in the chain. So is a token that only ever ran on GitHub Actions runners acting anywhere else, or CI secrets read by a workflow file minutes old.
  • One place, many tokens. Several people's tokens from one place at once is one actor. On Oct 21, a maintainer's token and the owner's pushed from a single IP five seconds apart; the same IP approved the production gate at 11:11.
  • New behavior. A credential using privileges or making calls its usual work never needs. The master key pulled every managed agent's config in one call; on Oct 21 the owner's token disabled branch protection, repointed the release, approved the production gate and deleted run records, all within two hours. Admin reach is a posture finding; a token using it outside its usual pattern is an incident.

Securing the new insider threat

LiteLLM's attacker never needed a software vulnerability. Every hop used a credential that sat where someone had left it: a key in a coding agent's config, an owner's token inside an agent platform, personal tokens in CI secrets. That is the new insider risk. The insider is not a rogue employee; it is a coding agent working with a developer's access, and the unmanaged identities it picks up along the way.

The answer is not to slow developers down or take their agents away. It is to give every agent and automation its own scoped, short-lived identity, keep secrets off endpoints and out of configs, and monitor every agent activity to detect drift or misuse. Access should be decided at the moment of action - get that right, and teams can keep building with agents at full speed without worrying about leaking keys or risking the enterprise.

Frequently asked questions

What happened in the LiteLLM compromise?

On October 21, 2026, a poisoned litellm==1.107.0 was published to PyPI, Docker Hub and GHCR and stayed live for about two hours. The attacker reached the release pipeline with credentials, not a software vulnerability: a master key leaked from a coding agent's config in May, an organization owner's GitHub CLI token read through that key, and two maintainers' tokens taken from CI secrets.

Which LiteLLM versions were affected?

Version 1.107.0. The PyPI release was live from 11:39 to 13:23 UTC and the Docker images until 14:20 UTC. Earlier in 2026, Datadog Security Labs linked a separate compromise of versions 1.82.7 and 1.82.8 to TeamPCP, and no connection between the two incidents has been established. LiteLLM's incident post lists the affected artifacts, how to check for exposure and the cleanup steps.

What is a non-human identity (NHI)?

A non-human identity is any credential or account that acts for software rather than for a person: API keys, tokens, service accounts, CI secrets and AI agents. In this incident that meant a platform master key, a person's GitHub CLI token running inside an agent platform, and tokens stored as CI secrets.

How do I stop coding agents from leaking credentials?

Keep long-lived keys out of agent and MCP configs and fetch short-lived credentials at runtime. Turn on push protection, and if a key does leak, revoke it before cleaning up history. Give automation its own scoped identity instead of a person's token, and scan developer endpoints for secrets in configs, .env files and shell history.

References

Primary sources‍

From Cyera and Oasis‍

‍

Compartilhar