The AI Supply Chain Map: Where LiteLLM 1.107.0 Should Have Been Caught

  • ai-security
  • sdlc

On October 21, a compromised LiteLLM 1.107.0 release was published to PyPI. It also reached the project's official container images. Two days later, Microsoft published its analysis: the package installed a Python startup hook, and the payload collected authentication material across developer tools, AI applications, cloud environments, browsers, and infrastructure.

The detail that matters is in one sentence of Microsoft's report: an application did not need to import LiteLLM for the payload to run.

Why "we don't use that package" was not an answer

Python processes .pth files in site-packages every time the interpreter starts. A line in such a file that begins with import is executed. A package that drops one runs code in every Python process on that machine or image, whether or not any program imports it.

That defeats the question most teams asked first: "Which of our applications depend on LiteLLM?" The answer that mattered was "Which of our environments installed it?" Those are different lists. A developer laptop that tried an AI gateway once, a shared CI image, a notebook server, and an agent's container can all carry a package no application declares.

A dependency scan that reads requirements.txt sees what your code asks for. It does not see what the environment executes at startup.

Why the AI gateway is a high-value target

LiteLLM is a gateway: one interface in front of many model providers. Organizations that run several models route traffic through components like it, which means those components hold the keys to every provider at once, and often sit next to the cloud credentials of the agents that call them.

That makes the AI control plane part of your software supply chain, with a larger blast radius than most libraries. A compromised logging package leaks logs. A compromised gateway can leak every model API key, and the cloud and tool credentials of every agent on the same host.

The map: eight layers

For each agent or AI application, trace one path from the model to the data it touches. At every layer, ask one question: where is provenance or integrity actually verified, and by whom?

  1. Model. Which model and version, from which provider or registry? Verified by: a pinned version or digest, or "whatever the provider serves today."
  2. Gateway. What sits between your code and the model: a proxy, a router, a hosted gateway? Verified by: the same release controls as any production service, or none because it was "just config."
  3. SDK and packages. Which libraries call the model, and which do they pull in? Verified by: a lockfile with hashes, installed from a mirror you control, with a delay before new releases are admitted.
  4. Container. Which base image and which upstream images? Verified by: digest pinning and signature verification, not a mutable latest tag. LiteLLM's official images carried the payload too.
  5. Runtime. Where does the process run, and what else is installed there? Verified by: an inventory of the installed environment, including startup hooks, not only the declared dependencies.
  6. Credentials. What secrets can the process read: environment variables, mounted files, instance roles, a developer's keychain? Verified by: short-lived, scoped credentials, so a theft expires before it is useful.
  7. Tools and MCP servers. Which tools can the agent call, and where does each come from? Verified by: an allowlist of approved servers at pinned versions. A local MCP server is a package with its own supply chain.
  8. Data. What can the path finally read or write? Verified by: access granted per task, so the compromise of any upper layer is bounded here.

Most first passes find verification at layers 3 and 4 for production applications, and almost nowhere else. Gateways, agent runtimes, and developer machines usually have none.

Five controls that would have changed the outcome

  • A quarantine on new releases. Install from an internal mirror that admits new versions of a package only after a waiting period. A release that is pulled within hours never reaches your builds.
  • Hash-pinned lockfiles. A build that installs exactly the reviewed artifact cannot silently take a new release.
  • Digest-pinned images. Refer to container images by digest, and rebuild on your schedule, not on the upstream's.
  • Startup hook monitoring. Alert on new or changed .pth files in production images and on developer machines. It is a short list, and it rarely changes legitimately.
  • Egress control on AI hosts. A gateway needs to reach its model providers. It does not need the rest of the internet. An allowlist turns credential theft into a blocked connection and a near miss you can count.

When a compromise is announced, the first hour is spent answering one question: where did this version run? If you already keep an AI agent inventory, the runtime and credentials fields give you the list of hosts and the list of secrets to rotate. Without it, you are searching.

How we help

Our GenAI Security Readiness Assessment builds this map for your agents and AI applications. We trace each path, record where integrity is verified, and turn every unverified layer into a finding with an owner and a fix. It is ordinary supply chain assurance, applied to the components that now hold your most valuable keys.

Three questions to test yourself

  1. If a package you never declared were compromised today, could you list every environment where it is installed?
  2. Which of your systems holds keys to more than one model provider, and what else can read them?
  3. How long after a new release does it reach your builds: hours, or a waiting period you chose?