Skip to content

LiteLLM / Telnyx — TeamPCP's Downstream Harvest (2026)

The Lesson: An AI gateway exists to hold every model provider credential you own. That makes it a secrets store, whether or not anyone classified it as one. TeamPCP reached it through a vulnerability scanner, and the packages were live for forty minutes.

The Dividend

Trivy is the incident everyone remembers, because Cisco's source code went missing and there were extortion demands. This is what the same compromise was actually for.

Trivy sat inside LiteLLM's CI/CD pipeline for roughly twenty days. It did its job — scanned the images, read the configs, held the secrets — and handed LiteLLM's PyPI publishing tokens to the people who owned it. Five days after the Trivy tags were rewritten, the largest AI supply chain compromise of the year shipped to a package with 95 million monthly downloads.

We wrote the Trivy page in March and called security scanners "the highest-value target in your pipeline." This is the receipt.


What Happened

On March 24, 2026 at 10:39 UTC, two malicious versions of litellm appeared on PyPI: 1.82.7 and 1.82.8.1

LiteLLM is an open-source proxy that puts one OpenAI-compatible API in front of every model provider — OpenAI, Anthropic, Bedrock, Vertex, Azure, local runtimes. It is, by design, the box that holds all of your AI credentials at once. It pulls roughly 95 million downloads a month.3

The attackers did not compromise LiteLLM directly. They had already compromised Trivy, and LiteLLM ran Trivy in its CI/CD security scanning workflow. The poisoned scanner harvested LiteLLM's PyPI publishing tokens from its own build runners, and TeamPCP used them to publish.2

PyPI quarantined both versions about forty minutes later.

Forty minutes was enough. CloudSEK's analysis of the recovered exfiltration store — 153 GB, 433,909 files, 118,829 attributed CI runner dumps — put the blast radius at roughly 2,500 corporate domains and 434,000 CI/CD pipelines, including Nvidia, AWS, Samsung, Salesforce, Cisco, ServiceNow, Siemens, FedEx, Volkswagen, and Zscaler.4

Three days later the same crew did it again to telnyx (4.87.1, 4.87.2).2

The Chain

This wasn't a single incident. It was nine days of one campaign walking downhill through the tools people use to be safe:

Date Target What it bought them
Mar 19 Trivy v0.69.4, 76 rewritten action tags Credentials from every CI runner that scanned
Mar 20–22 npm worm, 45+ packages More credentials, more runners
Mar 23 Checkmarx KICS, OpenVSX extensions A second scanner, and the editor
Mar 24 LiteLLM 1.82.7 / 1.82.8 AI provider keys, cloud IAM, Kubernetes
Mar 27 Telnyx 4.87.1 / 4.87.2 Telephony infrastructure

Two vulnerability scanners and an extension marketplace, used as transit. The security tooling wasn't incidental to this campaign — it was the campaign's distribution network.

Two Payloads, Two Triggers

The interesting part is that the two LiteLLM versions fired differently, and the second one is the one worth understanding.

1.82.7 injected its payload into litellm/proxy/proxy_server.py. Ordinary enough — it runs when the module is imported. You have to actually use the library.

1.82.8 shipped a file called litellm_init.pth into site-packages.

A .pth file is a Python packaging feature: normally it just adds directories to sys.path. But any line in a .pth file that begins with import is executed at interpreter startup, before your code runs, before any import you wrote, every single time. It's documented behavior going back decades. It is also a nearly perfect place to put a credential stealer.

# litellm_init.pth — one line, no import of litellm required
import os,base64;exec(base64.b64decode("..."))

The consequence: on 1.82.8, you did not have to use LiteLLM to be robbed. Any python in that environment — a cron job, a health check, python -c 'print(1)' — ran the payload. Installing the package was the entire attack.

.pth files execute — check them like you check dependencies

This isn't LiteLLM-specific and it isn't new. Any package that can write to site-packages can drop a .pth file that executes on every interpreter start in that environment. It survives your application code being correct. It survives you never importing the package.

# Every .pth in every environment, and what it actually does
find / -name '*.pth' -path '*site-packages*' 2>/dev/null \
  | xargs grep -l '^import' 2>/dev/null

Legitimate hits exist — distutils-precedence.pth and some editable installs use it. The point is knowing which ones you have.

What It Took

The stealer swept for everything that looked like a credential:2

  • Environment variables — where the AI provider keys live
  • SSH private keys
  • Cloud credentials: ~/.aws/credentials, GCP, Azure
  • Kubernetes service account tokens and ~/.kube/config
  • Docker configs, shell history, database credentials, wallet files
  • CI/CD secrets and GitHub/GitLab personal access tokens

Bundled with AES-256 session keys wrapped in RSA-4096, POSTed to models.litellm[.]cloud — a domain unaffiliated with the project — under the header X-Filename: tpcp.tar.gz. That filename is the same one from the Trivy payload. Same toolkit, same crew, five days later.

Persistence went to ~/.config/sysmon/sysmon.py with a sysmon.service systemd unit, beaconing https://checkmarx[.]zone/raw for follow-on payloads. Note the domain: they registered a lookalike of the other security vendor they'd compromised the day before.

The Kubernetes Escalation

This is the part that separates LiteLLM from a normal credential theft.

When the payload found a Kubernetes service account token — and an AI gateway running in a cluster usually has one — it used it to create privileged node-setup-* pods.2

That's not data exfiltration. That's a foothold on the nodes. A stolen API key gets revoked; a privileged pod spec in a cluster you haven't audited since March is a different conversation. If you run LiteLLM in Kubernetes, the token is the finding, not the package.

Why the Docker Users Were Fine

The official image, ghcr.io/berriai/litellm, was not affected — its dependencies were pinned, so it never resolved either malicious version.1

Exposure required an unpinned pip install litellm that happened to run inside a forty-minute window on one Tuesday morning.

This guide has said pin your dependencies and pin your build environment enough times that it risks sounding like liturgy. Here is the version with numbers attached: the same software, the same day, the same attacker — and the difference between compromised and untouched was whether the install resolved versions fresh or read them from a lock.

What To Check

If LiteLLM or Telnyx has ever been installed outside a pinned image:

# 1. Did you ever hold a malicious version?
pip list 2>/dev/null | grep -iE '^(litellm|telnyx) '
#    litellm  1.82.7 / 1.82.8      — malicious
#    telnyx   4.87.1 / 4.87.2      — malicious

# 2. The startup hook (1.82.8)
find / -name 'litellm_init.pth' -path '*site-packages*' 2>/dev/null

# 3. Persistence
ls -la ~/.config/sysmon/ 2>/dev/null
systemctl list-unit-files | grep -iE 'sysmon|telemetry'
ls -la /tmp/pglog /tmp/.pg_state 2>/dev/null

# 4. Kubernetes — the one that matters
kubectl get pods -A | grep 'node-setup-'
kubectl get clusterrolebindings -o wide | grep -i 'node-setup'

If anything hits, treat it as full-credential exposure. Rotate cloud IAM keys, Kubernetes service account tokens, GitHub/GitLab PATs, AI provider keys, database passwords, and SSH keys. Audit CloudTrail and Kubernetes API logs from March 24, 2026 forward.

The FBI issued FLASH advisory FLASH-20260702-01 in July 2026 warning that actors in this campaign are likely to weaponize harvested credentials long after the original intrusion.5 "We upgraded in April" does not close this. Rotation closes this.

Why It Mattered

An AI gateway is a credential concentrator. Nobody writes "LLM proxy" on the list of systems holding production secrets, and yet its entire job is to sit in one place holding every provider key you own so your applications don't have to. This is the same argument as Bitwarden CLI — the most concentrated bag of credentials on the machine is the one worth stealing — and the AI stack built one without noticing. Inventory it as a secrets store, because that is what it is.

Installation is execution. The .pth mechanism means "I installed it but never imported it" is not a defense in Python. Neither is "our app doesn't use that code path." Any package that lands in site-packages can run code on every interpreter start in that environment. This is why --no-deps, review-before-install, and release cooldowns do more work than input validation ever will.

The scanner is the delivery vehicle, not the target. TeamPCP had no interest in Trivy or Checkmarx as such. Those tools were transit, because a scanner runs everywhere, with elevated access, on everyone's code. Compromise the scanner once and you inherit a credential feed from every organization that follows best practice. The Trivy page called security tools "part of your attack surface, not outside of it." LiteLLM is the compound interest on that sentence.

Forty minutes at machine speed is a large window. Trivy's malicious binary was live three hours. LiteLLM's packages, forty minutes. Both were enough, because the consumers are automated. Human-scale response times are not a control; the things that work here are structural and they work by not installing in the first place.

Detection is not the same as remediation. PyPI quarantined the packages fast, and the write-ups were good. None of that un-exfiltrates a credential. This incident's real cost was borne months later by teams doing rotation and log review — which is a fundamentally different discipline from choosing dependencies well, and one most of this guide doesn't cover.

Where It Sits

This is the downstream chapter of Trivy / Cisco, and it belongs beside Bitwarden CLI as the second incident in a year to prove that credential-holding tools are the ones worth taking. It shares its speed characteristics with keyv / ChainDrop — automated publish, human response, no contest — and it is the fourth security-vendor compromise in the eight-week span covered by Q1 2026.


Timeline

Date Event
Mar 19, 2026 Trivy compromised; malicious v0.69.4 and 76 rewritten action tags go live
Mar 19 – Apr, 2026 Compromised Trivy runs inside LiteLLM's CI, ~20 days, harvesting PyPI publish tokens
Mar 23, 2026 Checkmarx KICS and OpenVSX extensions compromised
Mar 24, 2026 10:39 UTC litellm 1.82.7 and 1.82.8 published to PyPI
Mar 24, 2026 ~11:19 UTC PyPI quarantines both versions — roughly 40 minutes of exposure
Mar 27, 2026 telnyx 4.87.1 and 4.87.2 compromised by the same crew
Jul 2, 2026 FBI issues FLASH-20260702-01 on long-tail credential weaponization
Aug 2026 CloudSEK attribution published: ~2,500 domains, ~434,000 CI/CD pipelines

Indicators of Compromise

# Malicious package versions
litellm 1.82.7, 1.82.8          PyPI, 2026-03-24
telnyx  4.87.1, 4.87.2          PyPI, 2026-03-27

# Files
litellm_init.pth                in site-packages — executes at interpreter startup
~/.config/sysmon/sysmon.py      persistence
sysmon.service                  systemd unit, sometimes "System Telemetry Service"
/tmp/pglog, /tmp/.pg_state      stage markers

# Network
models.litellm[.]cloud          exfil — NOT affiliated with LiteLLM
checkmarx[.]zone/raw            C2 beacon — lookalike of a compromised vendor
aquasecurtiy[.]org              typosquat of aquasec, shared with the Trivy payload
83.142.209.203:8080             Telnyx stage-2 (steganographic WAV: /ringtone.wav)
X-Filename: tpcp.tar.gz         exfil header — same as the Trivy payload

# Kubernetes
node-setup-*                    privileged pods created from stolen SA tokens


  1. "Security Update: Suspected Supply Chain Incident." LiteLLM Documentation. March 2026. https://docs.litellm.ai/blog/security-update-march-2026 

  2. "LiteLLM and Telnyx compromised on PyPI: Tracing the TeamPCP supply chain campaign." Datadog Security Labs. 2026. https://securitylabs.datadoghq.com/articles/litellm-compromised-pypi-teampcp-supply-chain-campaign/ 

  3. "Over 2,500 Organizations Impacted by LiteLLM Supply Chain Attack." SecurityWeek. August 2026. https://www.securityweek.com/over-2500-organizations-impacted-by-litellm-supply-chain-attack/ 

  4. "LiteLLM Supply Chain Attack Potentially Exposes 2,500 Companies and 434,000 CI/CD Pipelines." Cybersecurity News, reporting CloudSEK analysis. August 2026. https://cybersecuritynews.com/litellm-supply-chain-attack/ 

  5. FBI FLASH advisory FLASH-20260702-01, July 2026, as reported in "Your AI Gateway Was a Backdoor: Inside the LiteLLM Supply Chain Compromise." Trend Micro Research. https://www.trendmicro.com/en_us/research/26/c/inside-litellm-supply-chain-compromise.html