Updated September 10, 2026. First published March 24. This revision adds the FBI’s July advisory, CloudSEK’s August exposure analysis and LiteLLM’s subsequent release and MCP security changes.
Removing a malicious package does not revoke the credentials it copied. That is the unfinished part of the LiteLLM supply chain incident, almost six months after two poisoned Python releases reached developers and automated builds.
The FBI’s July 2 advisory on TeamPCP makes that concern explicit. It places LiteLLM alongside Trivy, KICS and the Telnyx Python SDK in a wider campaign, and warns that affiliated attackers may reuse stolen data and credentials long after the initial compromise. The operational question now extends beyond whether a team removed the affected package: which access survived, and what evidence shows it was closed?
There is another part of the story worth updating. LiteLLM has changed its publishing process and continued hardening its gateway. A useful assessment has to account for those improvements while examining the permissions and dependencies around the product. At Oktsec, this is where supply chain inspection, runtime controls and incident evidence need to meet.
What we learned since March
On August 11, CloudSEK reported more than 2,500 organizations and approximately 434,000 CI/CD pipelines potentially exposed in its reconstructed dataset. Those are exposure estimates. Its methodology covers the cascade involving Trivy, Checkmarx KICS and LiteLLM; the numbers do not establish that every organization executed a malicious LiteLLM package or lost credentials.
That distinction is visible in CloudSEK’s follow-up analysis of Indian organizations. Several records predate the March 24 LiteLLM releases. The report separates workflow runs, secret observations and confirmed package execution. A domain match can justify an investigation, but it cannot supply the missing execution history.
For a security team revisiting the incident, this changes the search. Start with the affected software and build environments, then follow the identities those processes could use. A replaced runner may leave behind a valid repository token. A rebuilt gateway may still use the same cloud key. The disappearance of the original host does not answer whether someone else retained access.
There are two timelines to reconstruct: when the malicious software ran, and how long the exposed authority remained usable. The second can extend past package removal, redeployment and the first incident ticket.
The attack began before the first tool call
LiteLLM’s incident update identifies PyPI versions 1.82.7 and 1.82.8 as compromised. The maintainers linked the incident to Trivy in their security workflow and reported that attackers appear to have uploaded the packages directly to PyPI, bypassing the official release process. They reported no malicious changes on main.
That makes the distributed artifact important. Reviewing a repository is useful, but it does not establish that a downloaded wheel contains the same code. Package origin, build provenance and the exact bytes installed are separate pieces of evidence.
The versions also had different execution paths. Version 1.82.7 carried a payload in proxy_server.py. Version 1.82.8 included that payload and litellm_init.pth. As Python’s startup documentation explains, executable import lines in relevant .pth files are processed during normal site initialization. In the affected environment, starting Python could trigger the code without an application explicitly importing LiteLLM.
Callum McMahon’s first-hand account shows how this reached an agent workflow: an MCP server launched through Cursor used uvx and resolved an unpinned LiteLLM dependency. A process-spawning failure in the malware made the compromise visible. The entry point was software startup; no hostile instruction had to convince the model to invoke a tool.
A tool-call policy starts too late to govern arbitrary startup code.
- ResolveDependency entersAn MCP environment selects a poisoned LiteLLM release.
- StartPayload executesThe affected Python environment runs malicious code.
- ReachHost access is usedReadable credentials and permitted network routes define exposure.
The original technical report described credential collection, outbound exfiltration and persistence behavior. The material at risk included SSH keys, cloud credentials, Kubernetes tokens and environment secrets accessible to the process. In a developer environment, that can include access unrelated to the MCP task the user intended to run.
Deployment paths differed. LiteLLM’s incident update says its official Proxy Docker image and LiteLLM Cloud were not affected by these poisoned PyPI releases. A custom image that installed the malicious package is a different case. The product name alone is not enough to determine exposure.
What LiteLLM changed after the incident
On March 30, LiteLLM announced CI/CD v2: isolated scanning and testing, separate validation and release repositories, PyPI Trusted Publishing and signed container releases. These changes address how build tooling can reach publishing authority and how users can verify an artifact’s origin.
The announcement distinguished delivered work from planned work. It described immutable Docker release tags, while further GHCR work and SLSA build provenance were still on the roadmap in that post. A historical roadmap should not be treated as evidence that a particular artifact has an attestation today. Verify the release you actually deploy.
Signing and isolation solve different problems. A valid signature ties an artifact to a signing identity; it does not certify that every dependency is benign. Separating release credentials from test jobs reduces what a compromised test dependency can reach. Consumers still need to verify the expected identity and digest, inspect dependencies and restrict the running process.
A March recovery version is not a September maintenance strategy
LiteLLM’s June support policy introduced a rolling window of four stable minor release lines, effective June 29. That means an old recommendation to freeze on a March release is incomplete. Teams need both a reproducible deployment and a route to supported security fixes.
Pin the artifact selected for production, test the next candidate and schedule its replacement before support expires. Automatic adoption of every new release and indefinite attachment to an old one create different risks. A controlled update process needs an owner, a supported target and deployment-specific tests.
MCP credentials became an explicit engineering concern
In its July 11 update, LiteLLM described replacing inferred MCP authentication with a single credential resolver and explicit authentication modes. The team reported problems including credentials reaching the wrong upstream, stale or duplicate authorization headers, and OAuth cache behavior crossing user boundaries. The new design was intended to reject unhandled cases rather than silently select credentials.
These are subsequent gateway changes, not evidence of another supply chain compromise. They matter because they affect the authority available after software has been installed. In a shared gateway, selecting the wrong credential can grant a legitimate request the wrong person’s access.
LiteLLM’s August 27 update reported 79 security fixes, including access control and credential handling, and introduced a public release-test dashboard. These are the maintainers’ reported changes, not an independent Oktsec audit. The useful next step is to inspect the fixes and tests relevant to your configuration, rather than using the total as a safety score.
For example, test two users with different permissions against the same upstream. Expire one user’s token. Remove one team’s access. Change the upstream destination. Each test should establish which identity was used, whether the request was permitted and what the destination received. A green release dashboard is useful context; it cannot substitute for those checks in your environment.
Revisit exposure with evidence that can answer the question
Months later, a current inventory can look clean even when the March build was affected. Look for historical lockfiles, package metadata, build logs, cached artifacts and image digests. Connect the artifact to the process that ran it, then to the credentials and destinations available at that time.
Swipe or scroll horizontally to compare all columns.
| Evidence | What it helps establish | What remains to check |
|---|---|---|
| A dependency or exposure match | A project or organization needs review. | Which artifact was installed and whether it ran. |
| An affected wheel or cached image | The malicious software reached an environment. | Startup or import execution, and the permissions available. |
| Process or credential-access records | The payload ran or reached sensitive material. | Transfers, persistence and subsequent use of identities. |
| Destination and identity audit records | Observed transfers or unauthorized access. | Other routes, delegated access and gaps in retention. |
This is an investigation model, not a reason to wait for complete proof before containment. If an affected process could read a production credential, restrict and rotate that access while investigating. Use a trusted system for recovery. Preserve suspect files without starting their Python environment merely to query the installed version.
Package removal, host recovery and credential recovery need separate closure criteria. Rebuild affected environments from reviewed artifacts; revoke exposed keys and relevant sessions; check for additional accounts, tokens or persistence created with the old access. Reissuing one model-provider key does not resolve exposure of repository, registry or cloud credentials on the same host.
Where records have expired, document the gap and the conservative action taken. “No activity found in retained logs” is narrower than “no credentials were used.” Our article on incident evidence develops that distinction.
Approval has to follow the installed software
An MCP server’s name, tool list and description can remain unchanged while its dependency tree changes. A team can therefore keep approving the same apparent tool while running different code underneath it. Checking only a tool schema or top-level manifest misses that change.
There is also a change that happens entirely outside your environment: a new advisory about an artifact already installed. Its hash stays the same; the evidence about its safety changes. Rechecking only when the repository changes will miss that event.
For an agent inventory to support that review, it needs a path from the client to the server, the resolved package or image, the host and the responsible owner. Where possible, retain versions and digests alongside when and where they were observed. An unresolved dependency should remain an explicit gap rather than being treated as absent.
That connection gives an advisory a useful destination. The team can identify which deployments need inspection, which owner can suspend them, and which credentials require review. A generic alert that a package is malicious leaves those decisions unanswered.
How we apply this at Oktsec
Aguara, the inspection engine behind Signal, examines the software and configuration around agent workflows. Its current checks cover known malicious-package evidence and suspicious patterns across supported package artifacts, installed environments, MCP configuration and other execution surfaces. The original LiteLLM response added rules for credential collection, executable .pth content, exfiltration and persistence.
That work has grown beyond a list of ten incident rules. Supported lockfiles can be inspected before installation; installed-package and Python startup evidence can help examine an existing environment. Coverage varies by ecosystem and evidence format. Aguara’s malicious-package checks complement general vulnerability scanning; they do not cover every CVE or prove that a machine was never compromised.
The next requirement is to connect inspection with what an organization uses. Node discovers supported agent and MCP configurations. The continuous ecosystem monitoring described for Signal is still in development: it is intended to connect that inventory with changes in repositories, advisories and research. LiteLLM illustrates why both artifact changes and newly published evidence must trigger review.
Control serves a different part of the deployment. It applies policy to actions routed through its enforcement points. It does not turn arbitrary code inside an MCP server into governed tool calls, and a signed decision cannot account for activity that bypassed that route. Cloud helps teams organize policy and evidence across their deployments; incident investigation still needs relevant host, identity and destination records.
Test the boundary before trusting it
Proxy environment variables are not an operating-system sandbox. An MCP server can ignore HTTP_PROXY or HTTPS_PROXY and attempt direct connections. Restricting routed tool calls is useful, but direct process traffic needs controls at the host, container or network layer.
Use a harmless test workload in an isolated environment to check that boundary before connecting real secrets. Confirm it can reach its approved service. Then attempt an unapproved destination, a direct connection that ignores proxy settings and a read outside its permitted files. Check the enforcement result and the receiving system. A failed connection caused by a broken service is not evidence that policy blocked it.
The upstream Trivy incident supplies another relevant test. Aqua’s analysis described an exfiltration fallback using a victim’s GitHub account. That behavior belongs to the Trivy payload analysis; it should not be silently attributed to every LiteLLM payload. It does show why allowing a trusted domain is only part of an outbound policy. A permitted code-hosting service can still receive data in the wrong repository under an overprivileged token.
What should change in the next deployment
A deployment review should be able to show the artifact selected, the identity allowed to run it and the access that identity receives. It should also show who follows upstream security changes and how an affected deployment is stopped or updated.
For a team that used the poisoned LiteLLM releases, the remaining work is concrete: reconcile historical builds with affected artifacts, close the credentials those processes could reach, investigate downstream use and establish a supported update path. For a team that did not, the case is an opportunity to test the same assumptions before another dependency exposes them.
AI agents can take useful work further because their tools connect to real systems. Those connections deserve a security model that covers installation, startup, execution and recovery. The LiteLLM incident remains relevant because a tool-call boundary covers only one part of that sequence.
Sources and update history
This article was first published March 24, 2026, restored September 10 and expanded the same day with reporting through August 27. Original publication metadata is preserved. Later gateway fixes are discussed separately from the March compromise; exposure estimates are attributed to their publishers.
- LiteLLM incident update and initial technical report — affected artifacts and deployment scope.
- LiteLLM CI/CD v2, March 30 — publishing and artifact verification changes.
- FBI FLASH, July 2 — broader TeamPCP campaign and continuing credential risk.
- CloudSEK, August 11 — reconstructed exposure, with its methodology and limits.
- LiteLLM MCP authentication update, July 11 and August 27 security update — subsequent gateway hardening.
Related Oktsec guidance: AI supply chain security, deployment boundaries and audit evidence.