On March 24, 2026, two versions of LiteLLM on PyPI shipped with a credential stealer. For roughly three hours, anyone who ran pip install litellm on one of the bad versions handed their SSH keys, cloud credentials, environment files, and anything else sitting on the box to a group that calls itself TeamPCP.
The part that should bother you is not that it happened. The part that should bother you is that it was always going to.
What actually happened
Five days before the LiteLLM release, on March 19, TeamPCP rewrote a git tag in the trivy-action GitHub Action repository so the tag pointed at a malicious release. Many CI pipelines use that action, LiteLLM among them. When the next LiteLLM release ran, the trojanized action exfiltrated the maintainer's PyPI credentials.
On March 24 at 10:39 UTC, TeamPCP used those credentials to publish litellm==1.82.7 and litellm==1.82.8. Both wheels included a file called litellm_init.pth. The .pth mechanism is a Python feature: any .pth file in a site-packages directory runs its contents every time the Python interpreter starts. The payload was three stages. First, harvest credentials. Then, attempt Kubernetes lateral movement via privileged pods. Then, install a persistent backdoor over systemd that phoned home for further payloads.
PyPI quarantined the packages within about three hours. In that window, the bad versions were pulled down roughly 119,000 times. For context, LiteLLM ships on the order of 3.4 million installs per day. The window was the cap on the damage, not the intent.
LiteLLM's team posted a security notice the same day, rotated credentials, and worked with PyPI on the post-mortem. The malicious code was not theirs. Their response was clean.
This is not a LiteLLM problem
The point is not that LiteLLM got hit. Anyone could have been hit. The point is the shape of what got hit.
When your "AI gateway" is a Python package, the thing that stands between attackers and your production is PyPI. Not PyPI the registry. PyPI as an ecosystem: every maintainer credential, every CI action, every transitive dependency, every tag you trust. LiteLLM's release flow went through a GitHub Action whose tag pointer was rewritten by somebody who had compromised a different project upstream. None of that has anything to do with AI, with gateways, or with LiteLLM specifically. It has to do with the fact that Python packages run arbitrary code at install, at import, and at interpreter startup, and that the registry they install from is a dependency graph you did not consent to.
A gateway is not an application you let your developers pip install into a virtualenv. A gateway is the thing every request hits first. If someone with a stolen credential on a dependency-of-a-dependency can put code on the box, they are in front of your traffic. That is the property of a gateway: traffic flows through it, plaintext, authenticated, with whatever context the application attached. Compromising the gateway compromises everything.
What a controlled supply chain looks like
The bar for a gateway's supply chain is boring and old. nginx and HAProxy have met it for twenty years:
- One artifact. A single binary, or a signed container image. Not a zip of hundreds of files that auto-execute at import.
- Built from a tagged commit in a repository you can audit.
- Built reproducibly. Same commit, same artifact. Verifiable by someone other than the publisher.
- Pinned, checksummed dependencies resolved at build time, not at install time, not at startup.
- Runtime does not fetch code. The gateway that starts in production is the gateway you built. No plugins pulled from a public registry on first boot.
- Narrow interpreter surface. No runtime
eval, no config that executes user-supplied code in the main process, no.pth-style auto-load mechanisms.
Every one of those is a direct control on the attack class TeamPCP used. None of them are novel. They are what production infrastructure has looked like for two decades.
The Python AI gateway model broke that baseline for a good reason: shipping a library was the fastest way to reach the audience that existed in 2023 and 2024. Developers wanted one pip install that spoke to every model. Fine. But the shape that works for a Python library inside an application does not scale to a gateway sitting in front of production traffic. The March incident was a mechanical consequence of running one at the wrong layer.
What SBproxy is, on this axis
SBproxy is a single static binary. No interpreter on the execution path, no package manager at startup, no plugins fetched at first boot.
Releases are cut from tagged commits in a public repo. The binary carries the version, commit hash, and build date linked in at build time. Container images ship with OCI labels that point back at the commit. Dependencies are pinned and checksummed in the build manifest. You can vendor the full dependency tree, audit it offline, and reproduce the binary from the tag.
When SBproxy starts, it does not reach out to a package registry. There is no auto-load mechanism that runs arbitrary code at process start. It does not execute a script that somebody uploaded with a stolen credential forty minutes earlier. It parses YAML and binds ports.
We are not claiming SBproxy is immune to supply chain attacks. Nothing is. Module registries can be compromised, toolchains can be compromised, CI can be compromised. What we are claiming is that the shape of the attack surface is auditable. One artifact. One upstream. One dependency graph that resolves at build time, not install time. Every link in that chain is a file you can fingerprint and a commit you can read.
What to do right now
If you are running LiteLLM today, the acute incident is over. PyPI pulled the bad versions within hours. If you ran pip install litellm during the window, rotate every credential that ever sat on that host, inspect your cluster for the systemd persistence, and read the Snyk technical writeup. BerriAI's own post-mortem is the first place to look.
If you are picking an AI gateway this quarter, the question to ask is not "is your code secure." The question is: "when I run your gateway in production, what is the full set of things that have to be trustworthy, and how do I verify each one."
If the honest answer involves a Python interpreter, pip, PyPI, some number of transitive packages, the CI actions those packages use, and every maintainer credential behind them, write that down. That is your trust boundary. Compare it to the one you have for nginx or Envoy or any other production proxy you already run. The gap is the thing the March incident taught everyone about, the hard way.
We did not set out to have opinions about supply chain. We set out to run in front of real traffic. The shape fell out of that.