critical

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 packageTypeConfirmed malicious versions or exposureWhat executed
github.com/aquasecurity/trivyGo project / release artifactsv0.69.4 release artifacts; Docker Hub images v0.69.5 and v0.69.6Trojanized Trivy binaries and images distributed through normal release channels
aquasecurity/trivy-actionGitHub ActionAny non-immutable tag before 0.35.0 during the March exposure windowMalicious entrypoint.sh ran before the intended scan
aquasecurity/setup-trivyGitHub ActionReplaced tags v0.2.0 through v0.2.6 before cleanup; safe tag later recreated as v0.2.6Malicious setup step ran before legitimate Trivy install
checkmarx/kics-github-actionGitHub ActionCompromised tags during 2026-03-23 exposure; Checkmarx later reissued clean releasesMalicious setup.sh logic executed inside CI
checkmarx/ast-github-actionGitHub ActionCompromised during the same 2026-03-23 exposure windowMalicious pre-scan CI step
litellmPyPI package1.82.7, 1.82.8Import-time backdoor plus .pth startup hook in 1.82.8
telnyxPyPI package4.87.1, 4.87.2Import-time credential stealer injected into telnyx/_client.py
tpcp-docs, docs-tpcpGitHub repositoriesAttacker-created exfiltration repos named in public alert coverageFallback 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:

  1. a mutable GitHub Action tag resolves to malicious code
  2. a trusted release pipeline publishes from compromised credentials
  3. a PyPI package executes at import time or Python startup
  4. 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.

  1. Rotate all secrets reachable from the runner or workstation: GitHub, cloud, registry, SSH, Docker, database, and API credentials.
  2. Rebuild self-hosted runners and disposable CI images from known-good bases.
  3. Replace mutable GitHub Action tags with full commit SHAs, and replace mutable container tags with digests.
  4. Audit maintainer and publisher accounts for stale recovery emails, weak fallback flows, and unreviewed trusted-publisher bindings.
  5. 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