CVE
Not assigned
CWE
CWE-506, CWE-494, CWE-829
Affected Surface
Trivy v0.69.4 release artifacts, Docker Hub images v0.69.5 and v0.69.6, aquasecurity/trivy-action tags before 0.35.0, and aquasecurity/setup-trivy tags before the recreated 0.2.6 release, Checkmarx KICS and AST GitHub Actions that resolved compromised tags during the 2026-03-23 exposure window, LiteLLM PyPI versions 1.82.7 and 1.82.8, Telnyx Python SDK PyPI versions 4.87.1 and 4.87.2, npm and PyPI publisher accounts, CI runners, and developer workstations exposed to Mini Shai-Hulud or Miasma credential-stealing propagation paths, GitHub organizations where attacker-created repositories such as tpcp-docs or docs-tpcp appeared
New July 2026 FBI-linked reporting on TeamPCP matters because it turns what looked like a loose pile of March incident reports into a single operator playbook. The alert coverage from SafeBreach and Security Affairs does not disclose a fresh one-line “zero-day.” Instead, it consolidates the mechanics already visible across earlier Trivy, KICS, LiteLLM, Telnyx, TanStack, and related incidents: mutable CI artifacts, stolen publishing credentials, startup-hook execution, runner-memory scraping, and exfiltration through attacker-controlled GitHub repositories.
That is publication-worthy because AppSec teams often triage each incident as if it were a separate package compromise. The July alert says the more useful boundary is the execution surface. If your build or developer workflow resolved a mutable GitHub Action tag, pulled an unpinned PyPI package during the exposure window, or let malware read runner memory and registry credentials, the package ecosystem is only the delivery layer.
Publicly named affected tools and package artifacts
The July alert summaries publicly name TeamPCP activity across developer and security tooling rather than providing a single exhaustive npm or PyPI package list. The table below focuses on the artifact names and versions that are confirmed by the alert coverage plus the vendor advisories behind each incident.
| Tool or package | Type | Confirmed malicious versions or exposure | What executed |
|---|---|---|---|
github.com/aquasecurity/trivy | Go project / release artifacts | v0.69.4 release artifacts; Docker Hub images v0.69.5 and v0.69.6 | Trojanized Trivy binaries and images distributed through normal release channels |
aquasecurity/trivy-action | GitHub Action | Any non-immutable tag before 0.35.0 during the March exposure window | Malicious entrypoint.sh ran before the intended scan |
aquasecurity/setup-trivy | GitHub Action | Replaced tags v0.2.0 through v0.2.6 before cleanup; safe tag later recreated as v0.2.6 | Malicious setup step ran before legitimate Trivy install |
checkmarx/kics-github-action | GitHub Action | Compromised tags during 2026-03-23 exposure; Checkmarx later reissued clean releases | Malicious setup.sh logic executed inside CI |
checkmarx/ast-github-action | GitHub Action | Compromised during the same 2026-03-23 exposure window | Malicious pre-scan CI step |
litellm | PyPI package | 1.82.7, 1.82.8 | Import-time backdoor plus .pth startup hook in 1.82.8 |
telnyx | PyPI package | 4.87.1, 4.87.2 | Import-time credential stealer injected into telnyx/_client.py |
tpcp-docs, docs-tpcp | GitHub repositories | Attacker-created exfiltration repos named in public alert coverage | Fallback dead-drop when malware had GitHub access |
The public gap is also important: the July alert summaries do not publish a complete npm and PyPI package inventory for every Mini Shai-Hulud or Miasma propagation branch. For that broader package set, the safest way to scope exposure is to pair the alert with campaign-specific reporting such as our prior coverage of the TanStack worm wave, the GitHub workstation breach, and the Cemu Linux asset swap.
The common exploit path is “trusted automation reads attacker-controlled bytes”
Across the named incidents, TeamPCP keeps winning in one of four places:
- a mutable GitHub Action tag resolves to malicious code
- a trusted release pipeline publishes from compromised credentials
- a PyPI package executes at import time or Python startup
- a runner or workstation already holding secrets becomes the next publisher
Those surfaces look different operationally, but the code path is similar. The malicious step runs before the operator expects danger.
GitHub Actions: tag resolution before the real job
The Trivy and KICS incidents are strong examples. A workflow that appears to be “run a security scan” first resolves a tag like @v2.1.20 or @0.34.0, downloads attacker-controlled action content, and executes it on a privileged runner:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aquasecurity/trivy-action@0.34.0
with:
scan-type: fs
Once that tag is mutable, the real attack surface is no longer your repository. It is the Action’s fetched shell code. Aqua’s advisory says the malicious Trivy action dumped Runner.Worker process memory through /proc/<pid>/mem, swept filesystem locations for cloud and registry credentials, encrypted the results, and then fell back to creating a public tpcp-docs repository if direct exfiltration failed.
That is a very different trust failure from a classic package postinstall, but the effect on the CI runner is the same: privileged automation executes attacker-selected bytes before your build policy has a chance to reason about them.
PyPI: startup hooks and import-time side effects
LiteLLM and Telnyx show the Python side of the same playbook. The July alert summaries name LiteLLM and Telnyx as public TeamPCP examples, and both vendor advisories document execution edges that are easy to miss in ordinary dependency review.
LiteLLM 1.82.8 used a .pth file:
site-packages/
litellm_init.pth
litellm/proxy/proxy_server.py
That matters because .pth processing runs during Python startup, not only when the application explicitly imports the package. A simplified shape is:
import os
import subprocess
subprocess.Popen(
["python", "-c", "exec(downloaded_payload)"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
)
Telnyx 4.87.2 stayed closer to the traditional import path by injecting code into telnyx/_client.py, but the operational outcome was still “import equals code execution.” Its advisory describes detached subprocess launch, payload retrieval hidden inside a .wav response, credential harvesting, Kubernetes lateral movement attempts, and persistence.
For defenders, the lesson is that pip install is not the only dangerous moment. python -c 'import <package>', test collection, REPL startup, and application boot can all be the actual trigger.
Runner-memory theft is the throughline
The most important repeated primitive in the March incidents is not any single package name. It is memory and filesystem access on hosts that already contain CI, cloud, or publish secrets.
The public reporting around Trivy, KICS, LiteLLM, and Telnyx consistently describes collection targets such as:
Runner.Worker process memory
~/.aws
~/.config/gcloud
/var/run/secrets/kubernetes.io/serviceaccount/
~/.ssh
~/.docker/config.json
.env files
registry publish tokens
GitHub PATs and OIDC material
That explains why TeamPCP keeps showing up in ecosystems that look unrelated on paper. Once the attacker gets code execution on a sufficiently privileged runner or workstation, Go releases, GitHub Actions, PyPI packages, npm publishes, and GitHub Releases become interchangeable downstream targets.
The July alert also highlights account-recovery risk, not just CI risk
One of the more operationally useful details in the July 2 coverage is the mention of stale or expired recovery email domains for maintainer accounts. The failure mode is simple:
maintainer account -> password reset email -> decommissioned corporate domain
attacker registers expired domain -> receives reset mail -> regains publish path
That path matters because it bypasses some of the defenses teams added after earlier worms:
- immutable release tags do not help if the attacker can legitimately publish a new package version
- provenance only proves which workflow or account published, not whether the account itself was recovered by an attacker
- malware scanning of source diffs can miss PyPI-only or registry-only artifact swaps
This is why the July alert is useful even for teams that already patched their GitHub Actions hardening after TanStack and Trivy. Registry identity hygiene is still part of the software supply chain.
What to hunt for right now
Start with workflow references, lockfiles, and obvious dead-drop names.
Search CI configuration for mutable references to the named actions:
rg -n \
"aquasecurity/(trivy-action|setup-trivy)|checkmarx/(kics-github-action|ast-github-action)" \
.github/workflows
Search Python dependency manifests and caches for the known bad package versions:
rg -n \
"litellm(==|===)?1\\.82\\.(7|8)|telnyx(==|===)?4\\.87\\.(1|2)" \
requirements*.txt poetry.lock uv.lock Pipfile.lock
Search repositories and runner workspaces for TeamPCP IOC strings named in public reporting:
rg -n \
"tpcp-docs|docs-tpcp|scan\\.aquasecurtiy\\.org|models\\.litellm\\.cloud|83\\.142\\.209\\.(11|203)|45\\.148\\.10\\.212" \
.
And if you control GitHub organizations, review audit logs for:
- unexpected public repository creation with
tpcp-docs-style names - force-pushed tags on third-party action mirrors
- workflows that resolved mutable tags during the documented exposure windows
- PyPI or npm publishes from identities that do not match your expected CI path
Response guidance
If an affected Action tag, Trivy artifact, LiteLLM version, or Telnyx version executed in your environment, treat the host as a credential exposure event, not as a simple “dependency inventory” issue.
- Rotate all secrets reachable from the runner or workstation: GitHub, cloud, registry, SSH, Docker, database, and API credentials.
- Rebuild self-hosted runners and disposable CI images from known-good bases.
- Replace mutable GitHub Action tags with full commit SHAs, and replace mutable container tags with digests.
- Audit maintainer and publisher accounts for stale recovery emails, weak fallback flows, and unreviewed trusted-publisher bindings.
- Re-scope package exposure using the campaign-specific advisories, because the July alert gives strong operator attribution but not a full registry inventory.
The key lesson from the new TeamPCP alert is that “package compromise” is too narrow a phrase. The recurring exploit surface is the developer trust boundary itself: startup hooks, CI actions, release jobs, publish tokens, and recovery channels that still let an attacker turn one foothold into the next signed or trusted artifact.
References
- SafeBreach: TeamPCP supply chain attacks and FLASH-20260702-01 coverage
- Security Affairs: FBI says TeamPCP compromised developer tools
- Aqua advisory: Trivy ecosystem briefly compromised
- Wiz: TeamPCP attack on KICS GitHub Action
- LiteLLM security update for versions 1.82.7 and 1.82.8
- Telnyx advisory: malicious PyPI versions 4.87.1 and 4.87.2
- Checkmarx incident update
- CWE-506 Embedded Malicious Code