TeamPCP Poisoned The Security Tools
In Your CI/CD Pipeline
When Trivy, KICS, and LiteLLM sit inside trusted delivery paths, compromising them is not opportunistic. It is efficient.
The March 2026 TeamPCP campaign did not just hit application dependencies. It moved through the security and developer tooling layer itself: Trivy, Checkmarx KICS, and LiteLLM release paths. This post breaks down what appears verified, what remains reported attribution, and the controls that would have cut the chain early.
Last verified against available public sources on March 28, 2026.

Spark Mode: This Was the Strategy
The uncomfortable part is not that a package got poisoned. Packages get poisoned. The uncomfortable part is which packages and which workflow surfaces were chosen.
Trivy and KICS are security-adjacent CI/CD components. LiteLLM sits in a fast-growing AI integration layer. Those are exactly the places where you find broad credentials, release automation, Kubernetes reach, and teams that trust the tool by default.
The Reported Five-Day Chain
Late February to early March 2026
The Trivy compromise created the opening
Public incident reporting and postmortem coverage indicate Aqua Security’s Trivy project was abused through GitHub Actions workflow weaknesses, leading to stolen credentials and malicious downstream publishing activity.
March 23, 2026
Checkmarx KICS GitHub Actions were reportedly retargeted
Follow-on reporting tied the KICS GitHub Action compromise to credentials harvested earlier in the campaign, extending the blast radius from one trusted security tool to another.
March 24, 2026
LiteLLM versions 1.82.7 and 1.82.8 were published to PyPI with malicious code
Endor Labs research, cited in multiple reports, found the malicious code was not present in the upstream repository and that version 1.82.8 additionally dropped a .pth-based persistence path that executed on Python startup.
What Looks Verified
LiteLLM versions 1.82.7 and 1.82.8 on PyPI contained malicious code not present in the upstream GitHub repository.
The payload harvested credentials and secrets, attempted Kubernetes lateral movement, and installed persistent host-level components.
GitHub’s own guidance still says pinning third-party actions to a full-length commit SHA is the only way to treat an action reference as immutable.
Teams that only removed the poisoned package without rotating secrets were underreacting to the actual blast radius.
What Needs Careful Wording
Exact counts of moved tags, the precise PAT origin point, and some ecosystem-to-ecosystem linkages are reported in follow-on analysis, but not every detail is backed by a vendor-published primary incident report.
Attribution to TeamPCP is strong in research and media coverage, but where direct vendor confirmation is unavailable, it should be described as reported or linked by researchers, not as courtroom-grade proof.
Public reporting connects the Trivy compromise to the LiteLLM release poisoning chain. That linkage is credible and repeated, but still should be framed as investigative attribution.
Under The Hood: Three Payload Goals
Stage 1: Credential harvest
Researchers reported theft targets including SSH keys, cloud tokens, Kubernetes secrets, crypto wallets, CI/CD secrets, and .env material. This is not just package compromise. It is operator environment compromise.
Stage 2: Kubernetes lateral movement
The reported behavior included deploying privileged pods broadly across clusters to gain node-level leverage. If your affected workload had enough rights to create privileged pods, the attacker did not need another bug.
Stage 3: Persistence
Reports describe a persistent systemd backdoor and filesystem artifacts such as `~/.config/sysmon/`. That means “pip uninstall” is not incident response. It is cosmetic cleanup.
Blueprint Mode: Break The Chain At Step One
GitHub’s own security guidance is unambiguous here: pin third-party actions to a full-length commit SHA. Not a major version tag. Not `main`. Not `latest`. A full SHA.
Why? Because tags move. The attacker only needs repository write access once. If your workflow follows a mutable tag, you just subscribed your pipeline to the attacker’s release process.
# Unsafe: mutable tag
- uses: aquasecurity/trivy-action@v0.33.1
# Safer: immutable commit SHA
- uses: aquasecurity/trivy-action@d0c8b7f5c8f5d7c99c9f1b9d8b0d5e2b6f4a1c77
# Organization policy:
# Require all third-party actions to be pinned to full-length SHAsAudit Right Now
Immediate triage commands
# 1. Find mutable third-party action references
rg -n "uses:\s+[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+@(v|main|master|latest|[0-9]+\.)" .github/workflows
# 2. Check whether LiteLLM poisoned versions were installed
python -m pip show litellm || true
python -m pip freeze | rg '^litellm=='
# 3. Search for likely persistence artifacts on Linux runners/workstations
find ~/.config -maxdepth 3 -type f 2>/dev/null | rg 'sysmon|systemd|pg_state|pglog' || true
systemctl --user list-units --type=service 2>/dev/null | rg 'sysmon|pg' || true
# 4. Look for suspicious cluster-wide privileged pod creation patterns
kubectl get pods -A -o json | jq -r '
.items[]
| select(any(.spec.containers[]?; .securityContext.privileged == true))
| [.metadata.namespace, .metadata.name] | @tsv
'
# 5. Hunt for the attacker pod naming pattern mentioned in reporting
kubectl get pods -A | rg 'node-setup-' || trueIf You Ran It, Rotate More Than The Package
Rotate SSH keys used on any machine that installed the affected packages or ran the affected actions.
Rotate cloud credentials, kubeconfigs, and every API key stored in `.env` files on those systems.
Invalidate CI/CD tokens and GitHub credentials tied to release pipelines, package publishing, or bot automation.
Treat self-hosted runners as potentially burned if they executed poisoned workflows or packages.
Rebuild from known-good images where persistence is possible. Do not trust in-place cleanup alone.
What This Means For AI Stacks
LiteLLM matters because it is not a niche package. It sits in the request path between apps, models, gateways, and agent frameworks. That makes transitive compromise realistic.
If an AI platform team says “we did not install that package directly,” that is not a reassuring sentence. It is the definition of supply-chain exposure.
What This Means For Platform Teams
Stop thinking of scanners, release actions, package publishers, and extension registries as support tooling. They are production control planes with nicer branding.
The controls belong in the same risk tier as cluster admin, package signing, registry trust, and workload identity.
Bottom Line
The attack worked because teams trusted the tools inside the pipeline more than they trusted the pipeline itself. Raise the bar: immutable action references, short-lived credentials, runner isolation, and package compromise playbooks that assume persistence instead of hoping for cleanup.
Read More TNTM AnalysisSources
Related Posts
A Trojanized kubectl Binary, One AirDrop, and a Multimillion-Dollar Kubernetes Breach
Google Cloud Threat Horizons H1 2026 details a real campaign where UNC4899 used social engineering and a trojanized kubectl-like binary to pivot from a developer workstation into cloud control paths. This post breaks down the kill chain, the control failures, and the exact audits platform teams should run now.
47 Known CVEs Just Deployed to Production: Why Container Image Scanning Isn't Optional
A developer pulls a base image from Docker Hub, builds their app on top, and ships it. Nobody checks what's inside that base layer. 87% of container images in production carry high-severity CVEs. Here's how to shift-left on container security with scanning, digest pinning, distroless images, and approved base image registries.
We Benchmarked AI Coding Agents on DevOps Work, Not Just Code
Most AI benchmarks measure coding tasks, not infrastructure operations. We ran a 20-task DevOps benchmark across GitHub Copilot, Claude Code, and Amazon Q Developer to test real platform engineering workflows: Terraform, Kubernetes debugging, CI/CD migration, and incident-style triage. Here is what held up and what broke.