The git tag was clean, the release wasn't: what the LiteLLM 1.107.0 compromise shows
On October 21, 2026, LiteLLM's own release pipeline built, signed and published a malicious
litellm==1.107.0 to PyPI and to its container registries. The official v1.107.0 source tag on
GitHub did not contain the malicious files. If you checked the repo and the tag, everything looked fine.
The lesson for anyone who installs software: reading the source is not the same as checking the thing you
installed.
What happened
According to LiteLLM's root cause analysis, an administrative key for an internal service was committed to a public repository on May 27, 2026 and never revoked. On October 10, the attacker used it to get the GitHub CLI token of a LiteLLM organization owner, then used that access to collect tokens belonging to two other maintainers.
On October 21, seven litellm==1.107.0 wheels went out to PyPI between 11:39:51 and 11:40:13 UTC
(4:39 to 4:40 AM PT), and Docker Hub and GHCR images followed at 11:46:56 UTC (4:46 AM PT).
GitHub issue #47826 flagged the compromise about 20 minutes after publication, and LiteLLM
says the artifacts were live for about two hours before they were pulled.
The tag was clean, the release wasn't
LiteLLM describes the release as built from a lookalike fork, then the history was cleaned. Its release
workflows hardcoded BerriAI as the source owner. The attacker pushed workflow commit
9cf97e9, which added a source_owner input, and used the owner's token to override
branch protection. The staging build then ran against the lookalike Berri-AI/litellm at commit
20535d8f, a commit that existed only on the attacker's fork.
After publishing, the attacker deleted the release run records, pushed a revert, and force-pushed
main back to the commit before the change. main then showed neither the change nor
the revert. LiteLLM notes both commits are still retrievable by SHA and the organization audit log recorded
each override.
The chain in one line: real repo and real tag, release workflow quietly pointed at a lookalike fork, the project's own pipeline signs and publishes the fork build, then the workflow change is wiped from visible history.
Why signing and branch protection didn't save it
Branch protection did reject the first push. But an organization owner's token can override branch protection, and the attacker had one. A second stolen token approved the production gate.
Signing did what signing does: it proved the artifacts came from LiteLLM's pipeline. In LiteLLM's follow-up, the team says its otherwise unchanged pipeline built the fork, signed the images with its cosign key and published with its Trusted Publisher identity. A signature tells you who published something. It does not tell you the published bytes match the source you reviewed.
Why installing it could hurt even if you never used LiteLLM
Microsoft's analysis found the wheels shipped cook.pth, cook.py
and sitecustomize.py, files Python can run during normal startup. An application did not need to
import LiteLLM: starting Python in an affected environment could be enough. That is why Microsoft says not to
run python or pip inside a suspect environment to check it, and why removing the
package or a release tag is not enough recovery.
How to tell if the artifact matches the source
These checks come from Microsoft's guidance, plus tool docs for how to do each one:
- Hash-pinned lock files. Install only the exact files you reviewed earlier, for example with pip's hash-checking mode. A new upload under a version you never pinned will not install silently.
- Container digests, not floating tags. Tags like
latestcan be repointed, and in this incident several were. A digest names fixed image content. - Check provenance, not just a signature. Where a project publishes build provenance, check that it names the repository and workflow you expect. GitHub's artifact attestation docs show
gh attestation verify. - Review before mirroring. Microsoft recommends admitting packages to internal mirrors only after review, so a bad release does not reach every build at once.
None of these is a guarantee on its own. Together they make a quiet mismatch between source and artifact much harder to miss.
If you installed 1.107.0
Follow LiteLLM's incident post, which lists the affected artifacts, time windows and cleanup steps, and Microsoft's guidance, which includes its indicator list and hunting queries. We link to them rather than copy them so you always get the current version. In short: do not start Python in a suspect environment, rebuild from verified artifacts, and rotate credentials from a known-clean machine.
Check your tools on ReleaseLock
ReleaseLock tracks GitHub releases, not PyPI packages or container images. The same idea applies, though: a published artifact should be locked and checkable against something you already trust. For GitHub releases, look up a tool's lock level in the directory, and read Can this GitHub release be swapped? for what each level means. More incidents are collected in What 2026's GitHub supply-chain incidents show about unlocked releases.
Quick answers
What happened to LiteLLM 1.107.0?
On October 21, 2026, LiteLLM's release pipeline published a malicious litellm 1.107.0 to PyPI and its container registries. LiteLLM says an attacker with stolen GitHub tokens pointed the release workflow at a lookalike fork, so the release was built from the fork, then the history was cleaned. The artifacts were live for about two hours.
Why did the LiteLLM source history look clean afterward?
The official v1.107.0 tag never contained the malicious files, because the release was built from a commit on a lookalike fork. After publishing, the attacker deleted the run records, reverted the workflow change and force-pushed main back to its earlier state, so main showed neither change.
Why didn't signing stop the LiteLLM release?
Because the project's own pipeline did the signing. LiteLLM says its pipeline built the fork, signed the images with its cosign key and published with its Trusted Publisher identity. A signature proves who published an artifact, not that it matches the source you reviewed.
Could installing litellm 1.107.0 cause harm without importing it?
Yes. Microsoft found the wheels added Python startup files, so starting Python in an affected environment could run the payload even if LiteLLM was never imported. Microsoft advises against running python or pip inside a suspect environment.
What checks help catch a package that does not match its source?
Microsoft recommends hash-pinned lock files, verifying package and image provenance, using container digests instead of floating tags, and admitting packages to internal mirrors only after review.
Look it up in the directory, or add the free scan step to your workflows.
Search the directorySources
- LiteLLM, The attack chain behind the v1.107.0 LiteLLM release (Oct 23, 2026)
- LiteLLM, Contained: Oct 21, 2026 LiteLLM release v1.107.0 Compromised
- LiteLLM, What we are changing after October 21
- Microsoft Security Blog, Inside the LiteLLM 1.107.0 supply chain compromise (Oct 23, 2026)
- BerriAI/litellm, issue #47826
- pip documentation, Secure installs
- Docker Docs, Digests
- GitHub Docs, Using artifact attestations