The Trivy Supply Chain Compromise: What Happened and Playbooks to Respond
On March 19, 2026, a threat actor known as TeamPCP compromised Aqua Security's Trivy vulnerability scanner - the most widely adopted open-source scanner in the cloud-native ecosystem. The attacker poisoned GitHub Actions, release binaries, and Docker Hub images simultaneously, injecting a credential stealer into official distribution channels. Exposure windows ranged from 3 to 12 hours depending on the component.
Trivy is embedded in thousands of CI/CD pipelines, running as a GitHub Action on every PR, every merge, every deployment. It runs with access to pipeline secrets by design. Compromise Trivy, and you don't just get code - you get cloud credentials, SSH keys, Kubernetes tokens, and everything else the pipeline touches.
If your organization runs Trivy, the question isn't whether you should investigate - it's how quickly you can. This post covers what happened, how the payload worked, and which versions are affected. We've also published open-source remediation playbooks that can get you from "are we affected?" to "we're locked down" in minutes - drop them into your AI coding assistant and let it do the work.
What happened?
The attack exploited credentials that were not fully revoked following a prior, distinct security incident. Aqua Security confirmed that the earlier containment was incomplete, giving TeamPCP residual access to Trivy's release infrastructure. With that access, the attacker launched a coordinated strike across multiple distribution channels at once.
At 17:43 UTC on March 19, the attacker force-pushed 76 of 77 version tags in [aquasecurity/trivy-action] and all 7 tags in [aquasecurity/setup-trivy] to point at malicious commits. The payload was injected into entrypoint.sh and executed before the legitimate Trivy scan - pipelines appeared to work normally while the stealer ran silently underneath. The imposter commits spoofed legitimate maintainer identities, and GitHub flagged them with:
"This commit does not belong to any branch on this repository."
Less than an hour later, at 18:22 UTC, a rogue commit (1885610c) modified the actions/checkout SHA to point to an orphaned malicious commit (70379aad) and added --skip=validate to disable integrity checks during the build process. The result was a weaponized Trivy binary published as v0.69.4 across every distribution channel - GitHub Releases, GHCR, Docker Hub, ECR Public, deb/rpm repositories, and get.trivy.dev. The malicious binary was removed roughly three hours later, and the trivy-action tags were remediated by 05:40 UTC on March 20 - but the damage window was open.
Three days later, on March 22, the attacker pushed additional malicious Docker Hub images - v0.69.5, v0.69.6, and latest - this time using separately compromised Docker Hub credentials, bypassing all GitHub-based controls entirely. This extended the exposure by another ~10 hours before the images were pulled. On the same day, using a stolen service account token (Argon-DevOps-Mgt) that bridged both GitHub organizations, TeamPCP defaced all 44 repositories in Aqua Security's aquasec-com GitHub org, renaming them with tpcp-docs- prefixes and exposing proprietary source code.
How did the payload work?
The injected malware - self-described as "TeamPCP Cloud Stealer" - was methodical.
- It started by scanning
/proc/*/environacross all runner processes, extracting SSH keys and environment-level secrets. - Then came the critical technique: a base64-encoded Python payload located the
Runner.Workerprocess and read its memory directly via/proc/<pid>/mem, targeting values markedisSecret: true.
This bypassed GitHub Actions' built-in secret masking - secrets that would normally appear as***in logs were extracted in plaintext from process memory. - From there, the stealer swept over 50 filesystem paths, harvesting SSH keys, AWS/GCP/Azure tokens, Kubernetes configs, Docker configs, Terraform state files, Git credentials, cryptocurrency wallets, and shell history.
- All collected data was encrypted with AES-256-CBC + RSA-4096 hybrid encryption and exfiltrated via HTTPS POST to
scan[.]aquasecurtiy[.]org- a typosquatted domain mimicking Aqua Security's name, resolving to45.148.10.212in Amsterdam. - The payload also included a fallback mechanism: if the C2 server was unreachable and a GitHub PAT was present in the environment, the malware created a public repository named
tpcp-docsand uploaded the stolen data as release assets - turning GitHub itself into the exfiltration channel.
Which versions are affected?
|
Component |
Affected Versions |
Exposure Window |
Safe Versions |
|
trivy binary |
v0.69.4 |
~3h (Mar 19) |
v0.69.3 or earlier |
|
trivy (Docker Hub) |
v0.69.5, v0.69.6, latest |
~10h (Mar 22–24) |
v0.69.3 or earlier |
|
trivy-action |
Tags 0.0.1–0.34.2 |
~12h (Mar 19–20) |
v0.35.0 ( |
|
setup-trivy |
All releases |
~4h (Mar 19) |
v0.2.6 ( |
This is tracked as CVE-2026-33634 with critical severity (GHSA-69fq-xp46-6x23) The attacker also attempted to publish a malicious v0.70.0 release that was stopped before the tag was pushed - treat any v0.70.0 reference in your logs as suspicious. Additionally, mirror.gcr.io may still serve cached malicious images, so use digest-pinned references.
What should your team do now?
Any secret accessible to a workflow that ran a compromised version during the exposure windows should be considered compromised. That means rotating GitHub tokens, cloud provider credentials, registry tokens, SSH keys, and database passwords. Update to safe versions immediately: trivy binary v0.69.3 or earlier, trivy-action v0.35.0 (commit 57a97c7), setup-trivy v0.2.6 (commit 3fb12ec).
Pin all GitHub Actions to full commit SHAs going forward - mutable version tags can be force-pushed, and this attack proved it at scale. Block the C2 domain scan[.]aquasecurtiy[.]org and IP 45.148.10.212 at the network level, and review your logs for any historical connections. Audit for secondary compromise: stolen credentials may already have been used to create unauthorized repositories, trigger unexpected workflow runs, or modify infrastructure. Search your GitHub org for any repositories named tpcp-docs - their presence means the fallback exfiltration mechanism was triggered successfully.
Automate your response with our open-source playbooks
Most organizations using Trivy run it across dozens or even hundreds of repositories. Manually auditing every workflow, every image pull, and every credential scope across an entire GitHub org takes days - time you don't have when stolen credentials may already be in use.
To help the community respond quickly, we've open-sourced ready-to-run remediation playbooks that compress that work into minutes. Drop them into your AI coding assistant (Claude Code, Cursor, GitHub Copilot), provide your org name, and get a complete picture of your exposure - or a fully hardened pipeline - without writing a single script yourself.
The Detection & Response playbook gives you a clear answer: were we exposed, and if so, what exactly needs to be rotated?
The Hardening & Prevention playbook goes further - it locks down your pipelines against this entire class of supply chain attack, not just Trivy, but the underlying patterns that made it possible.
Indicators of compromise
|
Category |
Indicator |
|
C2 domain |
|
|
C2 IP |
|
|
Rogue trivy commit |
|
|
Malicious checkout commit |
|
|
Compromised setup-trivy commit |
|
|
Exfiltration artifact |
Public repos named |
|
Commit indicator |
"This commit does not belong to any branch on this repository" |
|
Compromised trivy-action tags |
76 tags across versions 0.0.1–0.34.2 |
Key takeaways
- Mutable tags are a liability. The 76 hijacked trivy-action tags prove that
@v0.34.0is a pointer, not a contract. The only safe reference is a full commit SHA. - Credential rotation must be atomic. The gap between "compromised" and "fully revoked" was the window that enabled this entire attack.
- Your security tools are part of your attack surface. Trivy runs with privileged access to CI secrets by design. That same privileged position makes it an ideal target.
- Supply chain attacks are multi-channel. This wasn't a single poisoned package - it hit GitHub Actions, binaries, Docker Hub, and package repos simultaneously. Defense in depth is the only posture that survives a coordinated attack like this.
Have you started your assessment? We'd like to hear how your team is responding.
Download our new whitepaper.