A software supply-chain compromise involving LiteLLM has become significantly more serious months after the malicious packages were removed from PyPI.
When LiteLLM versions 1.82.7 and 1.82.8 were published on March 24, 2026, they contained credential-stealing code that could collect cloud credentials, SSH keys, Kubernetes configuration, database credentials, API keys and other secrets from systems where the packages were executed. The incident was not an isolated compromise of an AI library. It was another stage in a broader TeamPCP supply-chain campaign that had already compromised the Trivy security scanner and subsequently moved through other developer infrastructure.
At the time, the immediate concern was whether anyone had installed the malicious packages during their short availability on PyPI. The picture now looks considerably larger.
Recent threat-intelligence reporting based on attacker-collected material has identified hundreds of thousands of captured files and linked a substantial portion of that data to thousands of organizations. CloudSEK says its analysis of roughly 434,000 files indicates potential exposure involving more than 2,500 organizations, while Hudson Rock has separately reported analysis of a 153 GB archive containing 433,909 files, including 118,829 CI runner dumps attributed to 2,488 corporate domains. Those figures should not be read as a confirmed count of breached organizations. Attribution is based on evidence contained in the stolen material, and a captured file, CI run or credential does not by itself prove that the corresponding organization suffered unauthorized follow-on access.
That distinction matters. What is established is that the malicious LiteLLM packages existed, they contained credential-stealing functionality, the packages were connected to the wider Trivy compromise, and stolen material from the campaign has subsequently surfaced in threat-intelligence datasets. The more difficult question is how many organizations were actually affected and what attackers did with the credentials after stealing them.
For organizations that ran LiteLLM 1.82.7 or 1.82.8 during the relevant window, the safest conclusion remains straightforward: credentials accessible from the affected environment should be treated as potentially compromised, even if there is no evidence that an attacker subsequently used them.
What happened to LiteLLM?
LiteLLM is an open-source Python project used as a gateway and abstraction layer for applications that need to communicate with multiple large-language-model providers. Instead of implementing separate integrations for each provider, applications can route requests through LiteLLM and use a common interface.
That makes the package useful, but it also gives it an unusually valuable position inside some AI development environments. A LiteLLM installation may coexist with model-provider API keys, cloud credentials, Kubernetes configuration, CI/CD tokens and application secrets. In development and automation environments, those credentials are often exposed to processes through environment variables or mounted configuration files.
On March 24, attackers published malicious versions 1.82.7 and 1.82.8 to PyPI. The releases did not correspond to the normal upstream release state. LiteLLM’s own incident record says the attacker published the packages directly using compromised publishing access rather than through the project’s legitimate GitHub release workflow. The project’s security issue identifies 1.82.7 and 1.82.8 as the affected versions and describes two different execution mechanisms.
The incident was detected quickly enough for PyPI to quarantine the releases, but the packages were available long enough to be downloaded and installed.
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →There is some variation in public reporting over the exact exposure interval. NHS England records the malicious packages as being uploaded at 10:39 UTC and quarantined at 13:38 UTC, while downstream projects that investigated their own dependency exposure used a broader March 24 window of 10:39 to 16:00 UTC.
That is why an investigation should not be reduced to checking whether a package was installed at one particular timestamp. Organizations should examine package-manager logs, CI job logs, dependency-resolution records and artifact caches across the entire relevant period.
This was not a normal LiteLLM vulnerability
Calling the incident a “LiteLLM vulnerability” is technically misleading.
There was no conventional memory corruption, authentication bypass or remotely exploitable flaw in LiteLLM that allowed an attacker to break into arbitrary installations. The malicious code was deliberately inserted into legitimate software releases.
That makes this a software supply-chain compromise.
The distinction changes the investigation. A conventional vulnerability assessment asks whether an application was reachable, whether the vulnerable code path was exposed and whether exploitation occurred. A malicious package incident asks a different question: did the organization execute a trusted artifact that had already been modified before it reached the environment?
Once that happens, normal application boundaries may no longer matter.
The attacker does not need to find an exposed LiteLLM endpoint. The malicious code is already executing with the privileges of the Python process. If that process can read environment variables, filesystem credentials, cloud configuration or Kubernetes credentials, the malware can attempt to collect them using the same operating-system permissions available to the legitimate application.
This is one of the defining characteristics of modern software supply-chain attacks. The attacker is effectively borrowing the trust that the victim has already granted to the dependency.
The attack began with Trivy
The LiteLLM compromise was part of a much larger campaign attributed to TeamPCP.

The earlier stage targeted Trivy, Aqua Security’s widely used vulnerability scanner. On March 19, attackers used compromised credentials to publish a malicious Trivy v0.69.4 release, force-push malicious changes to 76 of 77 affected trivy-action version tags and replace the affected setup-trivy tags. The incident is tracked as CVE-2026-33634, which NIST’s National Vulnerability Database classifies as a known exploited vulnerability and which CISA added to its Known Exploited Vulnerabilities catalog.
The important detail is what happened next. LiteLLM’s build infrastructure used Trivy. When the compromised Trivy component ran inside the LiteLLM CI/CD environment, the attacker’s code could access secrets available to that environment. Among those credentials was access that could ultimately be used to publish packages to PyPI.
The resulting chain looked roughly like this:
Trivy compromise → CI/CD credential theft → LiteLLM publishing access → malicious PyPI releases → execution inside downstream environments → credential harvesting → exfiltration.
This is considerably more dangerous than compromising a single developer workstation because CI/CD runners routinely sit at the intersection of source repositories, package registries, cloud environments, signing systems and deployment infrastructure. A compromised scanner can therefore become a credential collection point for the entire build system.
The CVE record now explicitly lists LiteLLM versions 1.82.7 through 1.82.8 among the affected software associated with the campaign.
How the malicious LiteLLM packages executed
The two malicious versions did not use exactly the same trigger.

litellm_init.pth file could trigger code execution during Python interpreter initializationVersion 1.82.7 contained the malicious payload inside litellm/proxy/proxy_server.py. The code was hidden as an encoded payload and executed when the affected proxy module was imported. Version 1.82.8 retained that payload and added a more aggressive mechanism involving a file named litellm_init.pth.
The .pth mechanism is particularly important because it changes the normal assumption that a Python package only runs when application code imports that package.
Python’s site initialization process processes .pth files found in site-packages directories. Those files are normally used to add directories to sys.path, but they can also contain executable import statements. As a result, a malicious .pth file can cause Python code to execute during interpreter startup.
That means the presence of litellm_init.pth could make the malicious code execute even when an application did not explicitly import the LiteLLM module.
This is why the second package was substantially more dangerous from a defensive perspective. An organization might look at its application and conclude that LiteLLM was installed but never actually used in a particular workflow. With 1.82.8, that distinction is unreliable if the affected Python environment was subsequently used to start another Python process.
The upstream incident record identifies the litellm_init.pth file as approximately 34 KB and states that it caused execution on Python startup.
The technique also illustrates why package-level execution needs to be considered separately from application-level execution. Security teams frequently think in terms of imported modules and application entry points. Python startup hooks operate below that level.
What did the malware steal?
The payload was designed as a credential and configuration harvester rather than as a narrowly focused LiteLLM exploit.
Public technical analyses describe collection of environment variables, SSH material, cloud credentials, Kubernetes configuration, database passwords, CI/CD secrets, API credentials and other sensitive files. Unit 42 and other researchers have specifically documented the ability to target credentials used by AI services, including model-provider API keys.
That matters because environment variables are frequently treated as “secrets” by CI/CD systems without actually being isolated from processes running on the same host.
A typical CI runner might expose variables such as:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYOPENAI_API_KEYANTHROPIC_API_KEYGITHUB_TOKENPYPI_TOKENDATABASE_URLKUBECONFIG
The names vary between organizations, but the underlying problem is the same. If a malicious process runs with sufficient access to the runner environment, it can inspect values that were intended for legitimate build steps.The names vary between organizations, but the underlying problem is the same. If a malicious process runs with sufficient access to the runner environment, it can inspect values that were intended for legitimate build steps.
The malware also targeted local credential stores and configuration files. Kubernetes environments are especially sensitive because a kubeconfig or service-account token can provide access well beyond the machine where the Python package was installed.
The LiteLLM incident therefore should not be understood simply as “someone stole an OpenAI key.”
The potential blast radius includes the infrastructure that those keys could reach.
Why Kubernetes changes the severity
Kubernetes credentials deserve particular attention because they can transform a local package compromise into a cluster-level incident.
A Kubernetes client typically authenticates through a kubeconfig file, environment variables, service-account credentials or another credential provider. What the authenticated identity can do depends on its RBAC permissions.
If a compromised process obtains a service-account token with only narrow permissions, the impact may remain limited. If the token can list secrets, create workloads or access privileged namespaces, the situation changes substantially.
Technical analyses of the LiteLLM payload describe Kubernetes discovery and attempts to access cluster secrets. Other analyses of the wider TeamPCP campaign describe the creation of privileged workloads in compromised Kubernetes environments.
This is why a compromised CI runner should not automatically be treated as an isolated endpoint.
Consider a build runner that has permission to:
- build a container;
- push it to a registry;
- retrieve deployment credentials;
- authenticate to a Kubernetes cluster; and
- access cloud APIs.
A malicious package executing on that runner inherits the opportunity to interact with every one of those interfaces.
The package does not need a sophisticated privilege-escalation vulnerability if the runner already has excessive privileges.
That is an architectural problem rather than a LiteLLM-specific problem.
The exfiltration infrastructure
The malicious packages used attacker-controlled infrastructure to send harvested information out of the compromised environment.
The LiteLLM incident record identifies models.litellm.cloud as the exfiltration endpoint. The domain is distinct from LiteLLM’s legitimate project infrastructure and was registered immediately before the malicious releases appeared. The payload used encrypted archives for the collected information, with public analyses documenting AES-256-CBC and RSA-4096 in the packaging and encryption process.
The use of encryption is not unusual in modern information stealers. It prevents defenders who capture the network traffic or stolen archive from immediately reading the contents and allows the attacker to transport a bundle containing many different credential types through a relatively simple HTTP request.
It also reinforces an important detection lesson: looking only for plaintext secrets leaving the network is not enough.
A compromised runner can collect dozens or hundreds of files, package them locally, encrypt the archive and make a single outbound request. Network telemetry may therefore show nothing more suspicious than an HTTPS connection from a build environment.
The domain itself is a valuable indicator, but it should not be the only one. Infrastructure can disappear, be sinkholed or change. Behavioral detection is more durable.
The new evidence changes the picture
The most significant development in August is not the discovery of the malicious code. That was already known in March.
The new development is access to material that appears to represent part of the attackers’ stolen data.
CloudSEK has reported analyzing approximately 434,000 captured files and mapping potential exposure to more than 2,500 organizations. Its attribution process reportedly uses identity signals from CI environments, including host information and legitimate organizational domains, and applies additional ownership checks before assigning confidence.
Hudson Rock has separately reported a 153 GB archive containing 433,909 files. Its analysis attributes 118,829 CI runner dumps to 2,488 corporate domains.
These numbers are striking, but they need to be interpreted correctly.
433,909 files does not mean 433,909 victims.


Likewise, 118,829 runner dumps does not necessarily mean 118,829 unique CI jobs or unique organizations.
A single organization can generate many CI executions. A single execution can produce multiple captured artifacts. Some files may be duplicates, partial captures or material without enough evidence to establish ownership.
CloudSEK has therefore treated attribution as a confidence problem rather than simply matching a company name to a filename. The distinction is important because an email address, repository namespace or package name can produce false associations.
The existence of stolen material is stronger evidence than a theoretical dependency graph, but even the stolen material does not automatically establish successful exploitation of every credential found inside it.
The responsible conclusion is that the dataset demonstrates broad exposure and provides evidence for organizations to investigate, not that every named organization was necessarily breached after the LiteLLM compromise.
Why the names appearing in the dataset should not be treated as a victim list
Several large organizations have reportedly appeared in analyses of the stolen material.
That includes names such as NVIDIA, Cisco, Deloitte, Volkswagen, FedEx and Siemens in CloudSEK’s reporting, while Hudson Rock has published a different set of attributed domains including major technology and enterprise organizations.
But there is an important difference between saying:
credentials or CI artifacts associated with an organization’s infrastructure were found in attacker-collected material
and saying:
the organization was successfully breached and the attackers obtained unauthorized access to its production systems.
The first can be supported by the dataset. The second requires additional evidence.
That distinction is particularly important for large companies whose domains may appear in CI metadata, third-party services or shared infrastructure.
Security teams should therefore use public lookup services as an additional signal, not as a replacement for their own logs.
CloudSEK has published an exposure lookup service for the campaign:
CloudSEK LiteLLM exposure lookup
A domain appearing in the dataset should trigger an internal investigation. A domain not appearing there should not be interpreted as proof of safety.
The dataset is not necessarily complete, and attribution cannot cover every stolen secret.
The transitive dependency problem
One of the more uncomfortable lessons from the LiteLLM incident is that an organization did not necessarily need to choose LiteLLM directly.
A dependency can arrive through another package.
For example, an AI framework, agent framework, evaluation package or internal application can declare LiteLLM as a dependency. If that dependency allows a version range broad enough to include 1.82.7 or 1.82.8, a routine installation or update can resolve to the malicious release.
That is why statements such as “we don’t use LiteLLM” are not sufficient for incident response.
The right question is:
Did any environment execute a dependency graph that resolved to the compromised artifact?
This is also why version pinning alone is not a complete defense.
A requirement such as:
litellm>=1.80
does not identify a particular artifact.
Even:
litellm==1.82.7
would have explicitly selected the malicious version.
The stronger control is reproducible dependency resolution combined with artifact integrity verification. Lock files, hashes, private package mirrors, trusted artifact repositories and controlled promotion processes can reduce the chance that a registry-level compromise reaches production.
The broader lesson is that software composition analysis needs to account for what actually executes, not just what appears in a top-level manifest.
Why the CI/CD environment was so valuable
CI runners are attractive targets because they often contain exactly the information an attacker needs to move further into an organization.
A single runner can temporarily hold:
- cloud access tokens;
- source-control credentials;
- package publishing tokens;
- container registry credentials;
- signing keys;
- Kubernetes credentials;
- deployment secrets;
- API keys;
- database connection strings.
The runner may also have network access to internal services.
This makes a CI runner a temporary security boundary, and temporary boundaries are frequently weaker than permanent servers because they are created, modified and destroyed continuously.
The LiteLLM attack demonstrates the problem clearly. The malicious package did not need to compromise a company’s GitHub account directly. It could operate inside the environment where that account’s automation credentials were already being exposed to legitimate build processes.
This is also why secret masking does not solve the problem.
Secret masking protects log output. It does not prevent a process running inside the runner from reading the underlying environment variable.
If malware executes before the value reaches the logging layer, masking has nothing to mask.
The correct security control is therefore not simply “hide secrets from logs.” It is to reduce the number of secrets exposed to each process and restrict what those credentials can do.
The problem with long-lived credentials
The FBI’s July 2026 warning on TeamPCP emphasized a point that is easy to overlook after the initial incident has passed: stolen credentials do not necessarily expire when the compromised package is removed.
If an attacker copied a static AWS access key in March and that key remained valid in August, deleting LiteLLM in March does not invalidate the credential. The same applies to SSH keys, package publishing tokens, personal access tokens and other long-lived credentials. This is why remediation should be based on credential exposure, not merely malware removal.
If an affected environment had access to a credential, the organization needs to determine whether that credential has since been revoked, rotated or otherwise invalidated. The date of the rotation matters. Rotating a password today does not prove that an attacker did not use the old password yesterday. Cloud audit logs, GitHub audit logs, package registry logs, Kubernetes audit logs and identity-provider telemetry should therefore be examined for activity following the suspected exposure.
What organizations should investigate now
The first step is to identify every environment that installed or executed LiteLLM 1.82.7 or 1.82.8 on March 24, 2026.
That includes developer machines, CI runners, build containers, ephemeral test environments, internal automation and third-party systems operated on the organization’s behalf.
Package-manager logs are useful, but they are not sufficient. An ephemeral CI runner may have disappeared long ago, while its logs remain in the CI platform. Dependency lock files, build artifacts and container layers can provide additional evidence.
The next step is to identify what credentials were accessible from those environments.
For cloud infrastructure, review AWS, Azure and Google Cloud credentials. For Kubernetes, identify service-account tokens, kubeconfig files and the RBAC permissions attached to them. For source control, review GitHub, GitLab and other access tokens. For package registries, check PyPI, npm, container registry and artifact repository credentials. For AI infrastructure, include OpenAI, Anthropic and other model-provider credentials where applicable.
The important phrase is accessible from the environment.
Do not limit the investigation to variables explicitly documented as LiteLLM configuration.
The malware was a general credential harvester, so the investigation should follow the environment’s privilege and filesystem exposure rather than LiteLLM’s intended function.
Look for the .pth file, but don’t stop there
Forensic teams examining a surviving affected Python environment should search for litellm_init.pth in Python site-packages directories.
The file is a particularly useful artifact because it is associated with the 1.82.8 execution mechanism. Public analyses also describe persistence artifacts associated with the wider campaign, including ~/.config/sysmon/sysmon.py and a corresponding systemd user service.
A useful forensic search is therefore broader than checking the installed package version.
Investigators should examine Python installation directories, recently created .pth files, user-level systemd services, shell history, process execution logs and outbound network connections.
The presence of the malicious file is strong evidence of package compromise, but its absence does not prove that an environment was never affected. A package could have executed and subsequently been removed, or the affected environment could have been ephemeral.
That is why historical telemetry is so important.
Check GitHub for TeamPCP artifacts
The wider campaign also used GitHub as an exfiltration mechanism.
The CVE documentation and FBI-linked reporting identify repositories with names such as tpcp-docs and docs-tpcp as useful indicators. The exact naming pattern can vary, so an investigation should not rely on a single literal repository name.
Security teams should review GitHub audit logs for unexpected repository creation, unusual release creation, suspicious release assets and authentication activity involving compromised automation credentials.
This is particularly important because GitHub is normally trusted and heavily used by CI/CD pipelines. An attacker uploading an encrypted archive to a repository release can therefore hide data movement inside traffic that an organization already permits.
Network detection still matters
The known LiteLLM exfiltration domain, models.litellm.cloud, should be searched across DNS logs, proxy telemetry, firewall records and endpoint network telemetry.
The investigation should cover the period beginning with the package execution and extend beyond it because the presence of a connection can establish that the payload actually ran, while subsequent authentication activity can reveal how stolen credentials were used.
A useful hunting strategy is to correlate:
affected package execution → outbound connection → credential type → subsequent authentication.
For example, if a CI runner installed 1.82.8, contacted the malicious infrastructure and an AWS credential available to that runner was subsequently used from an unfamiliar IP address, those events together provide considerably stronger evidence than any individual indicator.
This kind of correlation is also more resilient than relying on a single domain or file hash.
What the incident says about AI supply-chain security
It would be easy to frame LiteLLM as an unusual incident because it involves an AI-related package. That would miss the more important point.
The attack worked because LiteLLM was software inside a modern development environment. The fact that the package was used for AI workloads increased the value of some of the credentials available to it, but the underlying attack mechanism is the same one that has affected conventional open-source software for years. What has changed is the infrastructure around those packages.
Modern AI applications increasingly connect model providers, cloud services, vector databases, Kubernetes clusters, Git repositories, CI/CD systems and external APIs. A single package may therefore execute in an environment with access to a much wider collection of credentials than a traditional application library would have had.
The LiteLLM incident exposes that concentration of privilege. The security boundary is no longer just the application. It is the entire dependency and automation chain that builds and runs the application.
Why artifact verification matters more than version numbers
One of the most important lessons from this incident is that a version number is not an integrity guarantee.
1.82.7 can mean one thing in a project’s source repository and something different in a compromised package registry if an attacker has obtained publishing access.
This is why mature software supply-chain defenses increasingly rely on provenance and artifact integrity rather than trusting a package name and version alone.
For high-risk dependencies, organizations should prefer reproducible builds, signed artifacts where available, trusted package mirrors, immutable references and cryptographic hash verification.
For GitHub Actions, immutable commit-SHA pinning is particularly important because version tags can be moved. NIST’s CVE record explicitly recommends using full immutable commit SHAs for the affected Trivy actions rather than mutable version tags.
The same principle applies to Python dependencies.
A dependency lock file tells you what you intended to install. A verified artifact hash gives you evidence that what you installed is the artifact you expected.
Those are different security properties.
What should change in CI/CD after LiteLLM?
The obvious response is to rotate credentials.
The more valuable response is to reduce how many credentials need to be rotated during the next incident.
CI jobs should receive the smallest practical set of permissions for the shortest practical period. Cloud authentication should favor short-lived workload credentials over static access keys. Package publishing should be isolated from ordinary build jobs. Deployment credentials should not be exposed to arbitrary test steps. Build environments should be treated as disposable and untrusted, especially when third-party code is executed.
Self-hosted runners require particular care because they may have persistent filesystem state and access to internal networks. A compromised dependency that executes on a self-hosted runner can potentially access artifacts left behind by previous jobs.
Ephemeral runners reduce that persistence risk, but they do not solve credential exposure while the job is running.
The best architecture assumes that arbitrary dependency code can execute with the privileges of the build process and designs credentials around that assumption.
The real lesson from TeamPCP
The most striking feature of the TeamPCP campaign is not that attackers compromised an open-source project. Attackers have been doing that for years. The important part is the sequence.
A security tool was compromised. Its legitimate consumers trusted it. Credentials were extracted from their automation environments. Those credentials were then used to compromise additional software projects. The resulting packages reached another ecosystem and harvested another layer of credentials.
The attacker was effectively moving through a graph of trust. Trivy trusted the CI environment. LiteLLM trusted Trivy. Downstream organizations trusted PyPI. CI systems trusted package resolution. Cloud platforms trusted the credentials exposed to those CI systems. The attacker exploited those relationships rather than having to defeat every security control individually.
That is the defining problem of supply-chain security.
Final assessment
The LiteLLM compromise should not be described simply as a brief malicious-package incident that ended when PyPI removed two releases.
The malicious releases were removed, but the credentials they accessed do not disappear with them.
The latest threat-intelligence findings show why that distinction matters. Hundreds of thousands of files collected during the campaign are now being analyzed, and thousands of organizations have reportedly been associated with portions of the stolen material. The exact number of affected organizations remains difficult to establish, and public attribution should not be treated as proof that every named company suffered a confirmed breach.
What is beyond dispute is the technical risk.
LiteLLM 1.82.7 and 1.82.8 were malicious releases. Version 1.82.8 introduced a .pth startup mechanism capable of executing code whenever Python initialized in the affected environment. The payload targeted credentials and configuration data that commonly exist on developer machines and CI runners. The compromise was connected to the broader TeamPCP campaign that began with the Trivy supply-chain breach.
For an organization that executed the affected versions, the correct remediation question is therefore not “Is LiteLLM still installed?”
It is:
What could that environment access, which of those credentials were exposed, and have all of them been invalidated?
That is the question that determines whether the March incident is a closed software-update problem or an unresolved identity and infrastructure compromise.
The broader lesson is equally straightforward. A software dependency is not isolated simply because it is listed in requirements.txt. If it runs inside a CI runner that can reach your cloud accounts, repositories, registries or Kubernetes clusters, it is operating inside a privileged part of your infrastructure.
Supply-chain security ultimately comes down to controlling that trust.
The LiteLLM incident shows what happens when an attacker gets the opportunity to borrow it.
Sources and further reading
The primary technical record for the LiteLLM compromise is the LiteLLM project’s security incident documentation and issue tracker.
The NIST National Vulnerability Database entry for CVE-2026-33634 documents the wider Trivy compromise, its affected components and its inclusion in CISA’s Known Exploited Vulnerabilities catalog.
Datadog’s Security Labs analysis provides useful context on the progression of the TeamPCP campaign and the relationship between the Trivy and LiteLLM compromises.
Endor Labs and StepSecurity provide additional technical analysis of the malicious LiteLLM packages and the different execution paths used by versions 1.82.7 and 1.82.8.
The latest exposure reporting should be treated as threat intelligence rather than as a definitive corporate victim list. Organizations should validate any indication against their own CI/CD, identity, cloud and network telemetry.









