LiteLLM on Friday revealed that an Agent Platform master key accidentally published to a public GitHub repository in late May 2026 ultimately allowed the threat actor to push a malicious version of the popular Python package.
“On May 27, 2026, a configuration file was committed to the public LiteLLM-Labs/lite-harness repository which inadvertently contained the master key to a deployment of the LiteLLM Agent Platform, an open source tool we use for orchestrating agents,” LiteLLM’s Oliver Jensen and Mateo Wang said.
“The error was quickly identified, the commit force-pushed over, and we identified the exposed keys as requiring revocation. However, key revocation did not occur for the master key.”
LiteLLM said the unknown attacker (operating from “69.48.229[.]143”) used this unrevoked key on October 10, 2026, to gain access to the Agent Platform and extracted a GitHub CLI OAuth token the service was configured with to allow self-hosted cloud agents to file pull requests to GitHub repositories.
The token, per the developers of the open-source large language model (LLM) gateway, was “not scoped down” and associated with its GitHub organization owner’s account.
Gaining access to the token allowed the attacker to possess owner-level access to all repositories across the organization and perform additional credential exfiltration. The sequence of actions performed by the threat actor following this step is as follows –
- October 10, 2026, between 10:11 and 10:12 p.m. UTC: Author commits into throwaway branches on internal repositories to run workflows (BerriAI/litellm and BerriAI/litellm-auto) designed to acquire GitHub CLI Oauth tokens associated with two engineers with maintainer privileges via an attacker-controlled webhook[.]site endpoint. The two runs are deleted minutes later.
- October 21, 2026, between 10:08 and 11:08 a.m. UTC: Override branch protection and alter the release pipeline with the source set to the lookalike repository “Berri-AI/litellm” rather than “BerriAI/litellm.”
- October 21, 2026, between 11:39 and 11:40 a.m. UTC: LiteLLM version 1.107.0 gets published to PyPI on
- October 21, 2026, 11:46 a.m. UTC: Docker Hub and GHCR images are published.
- October 21, 2026, between 11:53 and 11:54 a.m. UTC: Production and staging run records are deleted.
- October 21, 2026, 12:06 p.m. UTC: Supply chain attack reported by Upwind researcher Lidor Machluf.
- October 21, 2026, 1:23 p.m. UTC: PyPI quarantines LiteLLM version 1.107.0.
- October 21, 2025, 2:20 p.m. UTC: Docker Hub tags v1.107.0, latest, main-latest, and main-stable are removed or repointed to verified clean images.
“In typical operation, building and publishing a release requires being kicked off by an authorized engineer and being approved by a special account locked to a physical device in our office,” LiteLLM said.
![]() |
| Leaked master key in May 2026 |
“This restriction was relaxed earlier this week to accommodate the temporary push for more frequent releases and bugfix backports, allowing any two engineers to trigger and approve a release. As such, the threat actor used one of the tokens to trigger the release (after having repointed the deployer to their malicious repository), and another to approve it.”
In addition, the project maintainers noted that the threat actor could have very well loosened this restriction (or removed it entirely) themselves given that they were already in possession of a token belonging to an organization owner. It’s suspected that this was not done to evade detection.
LiteLLM also said the workflows are designed to identify and exfiltrate additional keys and tokens, specifically focusing on upstream inference API tokens. In response to the incident, the company said it’s working to revoke each and every token associated with every internal system and vendor platform.
More Details About the Workflows Emerge
Socket, which published its own investigation into the malicious workflows, said it recovered two malicious commits that each added a workflow at “.github/workflows/cache.yml.” The first commit was made on October 10, 2026, at 10:11:45 p.m. UTC. It was followed by a second commit on October 12.
“Neither commit was pushed to a branch that still exists,” Socket security researcher Karlo Zanki said in a report shared with The Hacker News. “Both were pushed to short-lived branches named ci-tmp-
According to the application security firm’s analysis of the repository’s activity log records, both commits rely on a legitimate commit as the branch base to make the push look seemingly harmless –
- Create a throwaway branch named “ci-tmp-
” (namely, ci-tmp-a351cc and ci-tmp-4d8517) from a recent legitimate commit on the repository. - Push a commit adding “.github/workflows/cache.yml” with the same subject, “ci: bump cache config.”
- The workflow is configured to be run every time a commit or tag is pushed (i.e., “on: [push]“), causing it to be triggered.
- Delete the branch.
Both workflows, as highlighted by LiteLLM, are equipped to harvest GitHub tokens and API keys for the organization’s Linear workspace, LiteLLM deployment, and Together AI, along with the identifier and signing key of a GitHub App.
The October 12 run extends the collection to more secrets, including API keys for Anthropic, OpenAI, AWS Bedrock, Tavily, and GitGuardian’s secret-scanning tenant. It also captures Playwright storage state, PostgreSQL database information (connection string, account name, password), Redis endpoint address, port, and authentication password.
The data gathered from the two workflows is exfiltrated to two different webhook[.]site endpoints –
- webhook[.]site/65a42464-3cfa-4b02-a18c-17a6d7b86f37
- webhook[.]site/4da03473-a3e7-4dc2-a087-9c564b4208e1
“A GitHub token and a GitHub App private key are credentials for the platform hosting the repository, not for a third-party service,” Zanki said. “GITGUARDIAN_API_KEY is a credential for the secret-scanning platform itself, which gives an attacker visibility into, and potentially control over, the alerts that would surface this activity.
“E2E_LINEAR_STORAGE_STATE_B64 is serialized browser session state used by Playwright for end-to-end tests; a valid storage state permits authenticated access to the associated Linear account without a password and without satisfying multi-factor authentication.”
The findings rule out LiteLLM’s initial hypothesis that the GitHub CLI OAuth tokens were stolen from the logs of an internal LiteLLM deployment. “The investigation was a process in which we continually learned additional information, meaning some of our assumptions and beliefs were later proven to be inaccurate or incomplete,” Jensen acknowledged.
What the Malicious Version of the Package Does
Multiple reports have revealed that the files bundled with LiteLLM version 1.107.0 are engineered to execute automatically when Python starts, even if an application did not import LiteLLM.
The malware features two execution paths: a credential harvesting module that targets authentication material across developer tools, AI applications, cloud environments, and web browsers, and a Unix-oriented backdoor that’s launched as a background process to fetch and execute arbitrary code supplied by the attacker every one hour.
![]() |
| Compromised LiteLLM 1.107.0 execution flow |
The stealer also collects system information, SSH files, Git and GitLab credentials and tokens, environment variables, and tokens associated with npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems, and Cargo. The data is then compressed and sent to “litellm[.]dev/healthcheck” using an HTTP POST request. The domain was registered on October 13, 2026.
“Together, these mechanisms extended potential exposure beyond active LiteLLM deployments: simply starting Python in an affected environment could activate the malicious code, even when LiteLLM itself was never imported,” the Microsoft Security Research team said.
“Because the startup files resided outside the LiteLLM application directory, removing only the application files could leave the malicious startup components behind.”






