A technical breakdown of the TeamPCP campaign that turned a trusted vulnerability scanner into a credential theft weapon, and a defense-forward playbook for securing your CI/CD pipelines.
TeamPCP weaponized Trivy against the pipelines it was built to protect.
On March 19, 2026, threat actors operating under the name TeamPCP weaponized one of DevSecOps’s most trusted tools, Aqua Security’s Trivy vulnerability scanner, against the very pipelines it was designed to protect. 75 of 76 release tags of aquasecurity/trivy-action were force-pushed to malicious commits. The malicious Trivy binary (v0.69.4) was live for approximately three hours. Compromised GitHub Actions tags remained active for up to 12 hours. The blast radius: every secret accessible to affected CI/CD pipelines.
When the Scanner Becomes the Weapon
There is something particularly concerning about a security tool being turned against you. Trivy is not some obscure open-source project. It is one of the most widely adopted vulnerability scanners in cloud-native DevSecOps, trusted daily by thousands of engineering teams to scan container images, Kubernetes clusters, infrastructure-as-code, and filesystems. It sits at one of the most privileged positions in a CI/CD pipeline, with full access to runtime secrets, environment variables, and cloud credentials.
That trust is exactly what TeamPCP exploited.
This is not just another supply chain incident. The Trivy attack of March 2026 is a masterclass in how adversaries think about developer toolchains: find the thing that everything trusts, compromise it quietly, and harvest the keys to every kingdom downstream.
Trivy is a popular security scanner that helps identify vulnerabilities, misconfigurations, and exposed secrets across containers, Kubernetes environments, code repositories, and cloud infrastructure. Because developers and security teams commonly use it, it is a high-value target for attackers to steal sensitive authentication secrets.
If your organization runs Trivy in any CI/CD pipeline, this blog is your definitive resource: the full attack chain, forensic indicators, immediate remediation steps, and the long-term architectural changes that make incidents like this detectable, or preventable.
The Anatomy of the Attack: From Incomplete Containment to Full Supply Chain Weaponization
Incident 1: The Seed (February 28, 2026)
To understand the March 19 attack, you must understand what happened on February 28, 2026.
How the breach happened
- AI bot hackerbot-claw exploited a
pull_request_targetmisconfiguration in Trivy’s GitHub Actions workflows - This allowed it to steal a Personal Access Token (PAT) and achieve a full repository takeover
- Attacker privatized the repo and deleted all GitHub Releases from v0.27.0 to v0.69.1
- A suspicious artifact was pushed to the Trivy VSCode extension on Open VSX marketplace
Where Aqua’s response fell short
- Aqua rotated secrets and tokens after the March 1 disclosure, but the rotation was not atomic
- Not all credentials were revoked simultaneously, leaving a multi-day overlap window
- Attacker likely used a still-valid token to capture newly rotated secrets during that window
- This retained access is what enabled the March 19 attack
Critical lesson: A non-atomic credential rotation is functionally equivalent to no rotation at all if an adversary is watching in real time.
This is a textbook illustration of why incident response must be zero-trust, zero-gap. A non-atomic credential rotation is functionally equivalent to no rotation at all if an adversary is watching the rotation in real time.
Incident 2 — The March 19 Campaign: TeamPCP Strikes
Wiz Research, in concert with other industry parties, identified a multi-faceted supply chain attack targeting Aqua Security’s Trivy. The attack compromised multiple components of the Trivy project: the core scanner, the trivy-action GitHub Action, and the setup-trivy GitHub Action. The threat actor, self-identifying as TeamPCP, made impersonation commits pushed to actions/checkout (while spoofing user rauchg) and to aquasecurity/trivy (while spoofing user DmitriyLewen).
The campaign hit three vectors simultaneously:
| Vector | Scope | Duration |
|---|---|---|
| trivy v0.69.4 Malicious binary release | ~3h exposure window | |
| trivy-action GitHub Action — tags poisoned | ~12h exposure window | |
| setup-trivy GitHub Action — all tags hit | ~4h exposure window |
With over 10,000 workflow files on GitHub referencing this action, the potential blast radius was enormous.
Deep Dive: How GitHub Actions Became a Credential Theft Vector
Step 1: Tag Hijacking via Force-Push (The Silent Weapon)
The most important technical detail in this attack is not the malware itself; it’s the delivery method. The attacker force-pushed 75 existing tags in aquasecurity/trivy-action to new malicious commits. Any GitHub Actions workflow referencing a tag like aquasecurity/[email protected] automatically resolved to whatever commit that tag pointed to at runtime.
This is the fundamental design weakness that was exploited. Most teams reference actions by tag (e.g., @0.24.0 or @v2). Tags are human-readable and easy to update. But in Git, tags are mutable, they can be silently repointed to a different commit without any visible change to the release page, the tag name, or the published dates.
The attacker didn’t create anything new – they silently altered what already existed, weaponizing trust itself. Every pipeline referencing any of the affected tags silently started executing attacker-controlled code with zero visible changes to their own codebase.
Step 2: Credential Abuse and Impersonation Commits
- Attacker pushed commit
1885610cswapping theactions/checkoutreference to an imposter commit70379aad - The imposter commit downloaded malicious Go source files from a typosquatted domain,
scan.aquasecurtiy[.]org(note: “securtiy” not “security”), resolving to45.148.10.212 - Backdoored binaries were simultaneously published to GitHub Releases, Docker Hub, GHCR, and ECR
Step 3: The Forensic Concealment
The impersonation was meticulous. The malicious commit’s metadata, author name, commit message (“Upgrade trivy to v0.53.0 (#369)”), and timestamps (2024-07-09), all mirror a legitimate prior commit. Git allows setting arbitrary author and committer dates via GIT_AUTHOR_DATE and GIT_COMMITTER_DATE environment variables, so these cannot be trusted.
But there was one forensic tell: each malicious commit claimed a timestamp from the original release year (2021, 2022, etc.) but had a parent commit dated March 2026, a physical impossibility in real git history. Additionally, the malicious commits modified only entrypoint.sh, whereas original commits typically touched multiple files. Any team diffing a tag against HEAD would have caught this. Most don’t.
Step 4: The Three-Stage Infostealer
The injected 204-line entrypoint.sh executed malicious operations before the legitimate Trivy scan, hiding in plain sight. Self-labeled “TeamPCP Cloud Stealer”, it ran in three stages:
Stage 1 – Reconnaissance & Credential Harvesting
- Profiled the host: hostname, network interfaces,
whoami,uname - Swept the filesystem for:
- SSH private keys
- AWS, GCP, Azure credentials
- Kubernetes service account tokens (
/var/run/secrets/kubernetes.io/) - Docker registry credentials (
~/.docker/config.json) - Database connection strings and passwords
- npm auth tokens (
.npmrc) - TLS private keys and shell history
- Solana keypairs and cryptocurrency wallet files
- On GitHub-hosted Linux runners: used passwordless
sudoto dumpRunner.Workerprocess memory, extracting secrets directly from the heap
Stage 2 – Encryption
- Collected data compressed into
tpcp.tar.gz - Encrypted using AES-256-CBC + RSA-4096 hybrid scheme — computationally infeasible to decrypt without the attacker’s private key
Stage 3 – Dual Exfiltration Channels
- Primary: HTTPS POST to
scan.aquasecurtiy[.]org - Fallback (if primary returns non-2xx): used stolen
GITHUB_TOKENorINPUT_GITHUB_PATto create a public repo namedtpcp-docsin the victim’s own GitHub account and upload data as a release asset - The fallback is deliberate — if your network blocks the C2 domain, the attacker uses your own GitHub infrastructure as the dead drop
Step 5: Persistence on Developer Machines
- Checks if
GITHUB_ACTIONS != "true"— if outside CI, assumes it’s on a developer machine - Drops a Python payload at
~/.config/systemd/user/sysmon.py - Registers it as a systemd user service with
Restart=always - Sleeps for 5 minutes on first run (to outlast sandbox analysis timeouts)
- Then polls a remote C2 server every ~50 minutes, fetching and executing new payloads dropped at
/tmp/pglogas a detached process with all output suppressed
Step 6: Lateral Compromise of Aqua’s Infrastructure
- TeamPCP used retained credentials to compromise the
aqua-botservice account - Pushed malicious workflows to three additional Aqua repositories:
tfsec,traceeshark, andtrivy-action - Additional credentials exfiltrated: GPG keys, Docker Hub, Twitter, and Slack credentials
- All sent to Cloudflare Tunnel C2:
plug-tab-protective-relay.trycloudflare.com
Attackers also published additional malicious Trivy images (v0.69.5, v0.69.6) to Docker Hub.
Step 7: The GitHub “Immutable” Badge Problem
Perhaps the most alarming discovery: GitHub’s release UI displays an “Immutable” badge next to each tag on the releases page of the compromised action. Immutable releases refer to a newer GitHub feature enforcing that release versions, once published, cannot be altered or deleted. The attacker might have deliberately published immutable releases when poisoning the tags, effectively locking in the malicious state and making it harder for maintainers to restore the original tag targets.
This is a critical finding: a trust mechanism intended to prevent tampering was itself weaponized to cement the attack. Organizations and downstream users should not rely solely on the “Immutable” indicator to verify tag integrity.
Who Is TeamPCP?
TeamPCP, also tracked as DeadCatx3, PCPcat, and ShellForce, is a documented cloud-native threat actor known for exploiting misconfigured Docker APIs, Kubernetes clusters, Ray dashboards, and Redis servers. The group has been linked to worm-driven ransomware, data exfiltration, and cryptomining campaigns, and was profiled by Flare and reported on by The Hacker News in February 2026. Prior campaigns had compromised an estimated 60,000 or more servers.
The Trivy compromise represents TeamPCP’s first confirmed expansion into developer toolchain supply chain operations. The sophistication gap between their earlier opportunistic server attacks and the precision of the Trivy campaign is notable. Impersonating specific GitHub maintainers, timing the attack for maximum exposure window, deploying hybrid-encrypted exfiltration with AES-256+RSA-4096, and leveraging blockchain-based C2 infrastructure represent a meaningful escalation in operational capability.
The CanisterWorm Follow-on Campaign
The campaign expanded. Using npm tokens stolen during the Trivy compromise, TeamPCP launched CanisterWorm, a self-spreading npm worm that operated via npm’s postinstall hook mechanism, automatically executing credential-harvesting and self-propagation code the moment a developer or CI pipeline ran npm install. It planted a persistent backdoor via a systemd user service disguised as PostgreSQL tooling (pgmon.service).
The worm’s command-and-control infrastructure was built on an Internet Computer Protocol (ICP) canister, a tamperproof smart contract on the ICP blockchain. Because there is no single host or provider, this C2 cannot be taken down through a conventional takedown request. This marks the first publicly documented abuse of an ICP canister as a malware dead-drop resolver, and it represents a deliberate infrastructure choice by TeamPCP: the decentralized architecture was selected specifically for its resistance to takedown.
More than 50 npm packages were infected, spanning scopes including @EmilGroup, @opengov, @teale.io/eslint-config, @airtm/uuid-base32, and @pypestream/floating-ui-dom. A subsequent self-propagating variant automated full worm behavior from a single compromised install.
Indicators of Compromise (IOCs)
Organizations should search for the following across their environments, logs, and developer workstations:
MITRE ATT&CK Mapping
- T1195.002: Supply Chain Compromise: Compromise Software Supply Chain (Force-pushed GitHub Action tags)
- T1552.004: Unsecured Credentials: Private Keys (Harvesting SSH and TLS keys)
- T1005: Data from Local System (Archiving to tpcp.tar.gz)
- T1543.002: Create or Modify System Process: Systemd Service (Dropping Python payload at ~/.config/systemd/user/sysmon.py)
What You Must Do Right Now: Immediate Response Checklist
If your CI/CD pipelines ran any of the affected versions between 17:43 UTC March 19 and 05:40 UTC March 20, 2026, treat your environment as fully compromised.
- Check Trivy version exposure. Determine whether your organization pulled or executed Trivy v0.69.4, v0.69.5, or v0.69.6 from any source. Remove any affected artifacts immediately.
- Audit trivy-action and setup-trivy references. Review all workflows referencing these actions. If you used a version tag rather than a full commit SHA, check workflow run logs from March 19–20 for signs of compromise.
- Hunt for tpcp-docs in your GitHub organization. The presence of such a repository is definitive evidence that the fallback exfiltration mechanism executed and secrets were successfully stolen.
- Scan for persistence artifacts. Hunt for file creation events matching tpcp.tar.gz or sysmon.py across all developer workstations and CI/CD runner nodes. Check for pgmon.service in systemd.
- Rotate all secrets atomically. Any pipeline that executed a poisoned tag should be treated as fully compromised. Rotate all credentials simultaneously — cloud credentials (AWS, GCP, Azure), Kubernetes service account tokens, SSH keys, Docker registry credentials, API tokens, database passwords, and npm authentication tokens.
- Pin GitHub Actions to full commit SHAs. Replace every uses: action@version with uses: action@<40-char-sha>. The safe commit SHA for trivy-action is 57a97c7e7821a5776cebc9bb87c984fa69cba8f1.
- Block C2 infrastructure at your network perimeter. Block scan.aquasecurtiy[.]org, 45.148.10.212, and plug-tab-protective-relay.trycloudflare.com.
- Rebuild compromised runners. Do not attempt to clean the infostealer manually. Rebuild affected developer workstations and self-hosted runners from known-good base images.
The Structural Problem: What This Attack Reveals About CI/CD Security
The Trivy incident is not a story about one vendor’s failure. It is a structural diagnosis of how the industry has built CI/CD pipelines. Three root causes made this attack possible at scale:
GitHub Actions version tags are mutable by design. Nothing in the GitHub Actions documentation highlights this prominently. The ecosystem is built around the ergonomic convenience of uses: action@version, which most teams interpret as “pin to this version.” It is not. It is “use whatever this tag points to right now.” The delta between those two things is an attack surface.
Credential rotation must be atomic. Rotated secrets that aren’t all revoked simultaneously create a window during which an attacker holding existing credentials can capture newly issued ones. Aqua Security’s incomplete rotation following the February incident is what made March 19 possible. This is not an uncommon failure mode, it is simply a costly one.
Trusted security tools receive maximum pipeline privileges. Vulnerability scanners, by the nature of what they do, need access to the things they scan. That access:- to credentials, to environment variables, to secrets, to cloud APIs, is precisely what makes them high-value targets. The more trusted the tool, the more dangerous its compromise.
This incident exposes an uncomfortable truth in modern DevSecOps: your security tools run with the highest privileges in your pipeline, and most of them are sourced from mutable, community-maintained open-source repositories. Treat your security tooling like any other dependency. Apply the same supply chain scrutiny to Trivy, Snyk, Semgrep, and similar tools that you apply to application dependencies, pin versions, verify checksums, and monitor runtime behavior.
How Cy5’s ion Cloud Security Platform Defends Against Supply Chain Attacks Like This
The Trivy compromise didn’t just steal credentials, it exploited the gap between pipeline trust and runtime visibility. This is precisely the gap that Cy5’s ion Cloud Security Platform is architecturally designed to eliminate. The only teams that detected the March 19 attack in real time were those whose CI/CD runners were monitored by behavioral security tools. Log-based detection after the fact is not enough when secrets are exfiltrated within the first few minutes of execution.
1. Real-Time, Event-Driven Threat Detection, Not Batch Scanning
The Trivy attack was live for up to 12 hours. Organizations relying on periodic security scans would never have caught it in time. Ion uses an event-driven architecture for real-time detection, a serverless security data lake for contextual correlation, and an integrated SIEM engine that surfaces “toxic combinations” of misconfigurations, identities, and vulnerabilities that represent genuine attack paths, delivering refined, high-fidelity alerts with 85–96% noise reduction.
When a CI runner suddenly initiates an outbound POST to an unrecognized domain, or when a process begins dumping Runner.Worker memory, ion’s event-driven pipeline detects that behavioral anomaly in real time, not at the next scheduled scan.
2. Cloud Workload and Container Credential Monitoring
TeamPCP’s payload specifically targeted cloud credentials for AWS, GCP, and Azure, plus Kubernetes service account tokens. Ion identifies and secures 100+ resource types across AWS, GCP, and Azure instantly. If stolen credentials are then used for lateral movement, new API calls from unexpected geolocations, privilege escalations on IAM roles, unusual Kubernetes API server activity, ion’s contextual correlation engine links those signals into a coherent attack narrative, enabling SOC teams to cut off the attacker before they can weaponize the credentials.
3. Kubernetes Security Posture Monitoring (KSPM)
The malware explicitly targeted Kubernetes tokens and service account credentials. Ion’s KSPM scans Kubernetes clusters in read-only mode, correlating K8s metadata with cloud infrastructure context to detect risks like containers with command execution privileges, overly permissive roles, or elevated runtime privileges that, when combined with network exposure, represent critical attack vectors.
4. Integrated SIEM with IOC Auto-Enrichment
Responding to the Trivy compromise requires cross-referencing IOCs across your entire environment. Cy5’s SIEM auto-enriches alerts with 90+ live IOCs/TTPs, contextualizing attacks using global threat actor insights. The TeamPCP IOCs listed above can be ingested into ion’s detection rules within minutes, automatically hunting across cloud audit logs, network telemetry, and endpoint data.
5. Attack Path Visualization – Seeing What Stolen Credentials Can Reach
The most dangerous question after a credential theft isn’t “what was stolen?” It’s “what can the stolen credential access?” Cy5’s ion Cloud Security platform addresses this through its contextual correlation engine, which automatically maps relationships between cloud configurations, identities, network paths, and workload vulnerabilities to highlight “toxic combinations” that represent genuine attack vectors.
If a compromised CI/CD pipeline’s AWS IAM role has overprivileged access to production S3 buckets or RDS databases, ion maps that blast radius immediately, giving your team the ability to contain impact before the attacker moves laterally.
6. Policy-as-Code Guardrails for CI/CD
Platforms like Cy5 provide policy-as-code guardrails and real-time feedback that guide developers toward secure patterns without slowing velocity. By enforcing SHA-pinned Action references at the policy layer and flagging any workflow that uses mutable tags, ion helps prevent the very attack surface that TeamPCP exploited.
Long-Term Prevention: Hardening Your Pipeline Architecture
1. Pin All GitHub Actions to Full Commit SHAs. This is the single most impactful change. aquasecurity/trivy-action@57a97c7e… is immutable. aquasecurity/[email protected] is a promise that can be broken. There is no middle ground. Tags can be rewritten; commit SHAs cannot.
2. Enforce Least-Privilege, Ephemeral CI/CD Tokens. Implement strict ephemeral, least-privilege tokens for CI/CD pipelines (e.g., OIDC) to limit the blast radius of future supply chain attacks. Never use long-lived Personal Access Tokens in automation accounts. The default GITHUB_TOKEN in most pipelines has far more permissions than individual workflow steps require, scope permissions explicitly using the permissions block.
3. Verify Security Tool Integrity Independently. Build from source or verify against sigstore signatures. Chainguard’s Factory builds Trivy directly from application source code without consuming pre-built upstream artifacts. Because the Trivy application source code itself was not compromised, only the build and release workflow was, Chainguard’s independent build pipeline produced a clean image. This zero-trust-by-default model for dependency consumption is the gold standard.
4. Audit Every pull_request_target Workflow. Any workflow using this trigger that also checks out PR code creates a privilege escalation path from external contributor to CI credential access. Either eliminate the trigger or strictly separate trusted workflow execution from untrusted code checkout.
5. Deploy Runtime Monitoring on CI Runners. Your CI runners are compute. Treat them with the same security rigor you apply to production servers. Monitor for unexpected process creation, memory dumping, and outbound network connections. The only teams that detected this attack in real time had behavioral monitoring on their runners.
6. Atomic, Simultaneous Credential Rotation. If you’re ever breached, rotate all credentials simultaneously. A rolling rotation with a multi-day window is an open door. Revoke all credentials before issuing new ones, never the reverse.
7. Network Egress Controls for Build Environments. Restrict outbound network access from CI runners to known-good domains only. The C2 domain scan.aquasecurtiy[.]org would have been blocked by any allowlist-based egress policy.
Schema-Optimized FAQ: Trivy Supply Chain Attack
No. The Trivy application source code was not modified. The compromise targeted the build and release pipeline, specifically the GitHub Actions workflows and the binary release artifacts. Organizations building Trivy from source were not affected.
Check your GitHub Actions workflow run logs from March 19–20, 2026. If any run referenced aquasecurity/trivy-action by version tag (not SHA) or used Trivy v0.69.4/v0.69.5/v0.69.6, assume compromise. Additionally, check for any repository named tpcp-docs in your GitHub organization.
The malware harvested GitHub tokens, AWS/GCP/Azure cloud credentials, SSH keys, Kubernetes service account tokens, Docker registry credentials, database connection strings, GPG keys, npm authentication tokens, TLS private keys, shell history, and cryptocurrency wallet data.
Wiz Research continues to track TeamPCP activity. The threat actor has expanded operations to the npm ecosystem via CanisterWorm leveraging stolen publish tokens. The campaign is evolving, continued monitoring is essential.
Ion provides event-driven real-time detection of anomalous credential usage across AWS, Azure, GCP, and Kubernetes; contextual correlation that maps blast radius from compromised credentials; integrated SIEM with auto-IOC enrichment for rapid threat hunting; policy-as-code guardrails to enforce SHA-pinned Action references; and KSPM to detect lateral movement via stolen Kubernetes tokens.
Conclusion: Trust Is Not a Security Control
The Trivy supply chain attack is a reminder that in cloud-native security, trust is not a control; it is a risk. Every tool you trust implicitly in your pipeline is a potential attack vector if its release mechanism is compromised. The more trusted the tool, the more valuable the compromise.
Analysis covered 767 repositories and confirmed that 45 repositories had at least one workflow run using a compromised version of trivy-action or setup-trivy during the compromise window. These are confirmed exposures. The actual number across private repositories that cannot be publicly analyzed is almost certainly far higher.
The teams that emerged unscathed share common traits: they pinned dependencies to immutable references, they monitored runtime behavior on CI infrastructure, and they had cloud security architecture capable of detecting anomalous credential usage downstream of any potential theft.
Supply chain attacks are not going to become less sophisticated. TeamPCP’s evolution from attacking exposed APIs to compromising trusted developer toolchains, and then deploying a self-spreading blockchain-C2 worm as a follow-on, is a trajectory, not an isolated event. The security posture that stopped this attack is the one worth building.
Is your CI/CD pipeline
still exposed?
If your pipelines referenced aquasecurity/trivy-action during the compromise window, treat every secret they touched as stolen. Cy5’s security team can assess your exposure — and the ion Cloud Security Platform delivers the runtime visibility this attack proved is non-negotiable.
referencing poisoned action
confirmed exposure
in the wild



