Why This Breach Is an NHI Story
On March 19, 2026, attackers compromised Aqua Security's Trivy vulnerability scanner by targeting the one thing that held it all together: its non-human identities. The aqua-bot service account, GitHub Actions tokens, and CI/CD pipeline secrets were the actual attack surface. Not a single human password was phished. Every stage of this attack was NHI-to-NHI.
The Blast Radius of One Compromised Bot
After gaining access to the aqua-bot service account, TeamPCP pushed malicious workflows to tfsec, traceeshark, and trivy-action; force-pushed 75 of 76 version tags to backdoored versions; and exfiltrated GPG keys, Docker Hub, Twitter, and Slack credentials. One NHI. Enterprise-wide damage.
What Happened: The Attack Chain
Wiz Research, in collaboration with industry partners, identified the attack shortly after it began on March 19, 2026. The threat actor TeamPCP executed a multi-stage supply chain compromise that weaponized Aqua Security's own CI/CD infrastructure against its downstream users.
Stage 1: Retained Access and Initial Compromise
The attack used access retained from an earlier incident that was only partially contained. TeamPCP spoofed commits as legitimate maintainers - pushing imposter commits attributed to rauchg (to actions/checkout) and DmitriyLewen (to aquasecurity/trivy). At 17:43:37 UTC, the malicious v0.69.4 tag was pushed, triggering an automated release pipeline that published backdoored binaries to GitHub Releases, Docker Hub, GHCR, and ECR.
Stage 2: Weaponizing the aqua-bot Service Account (NHI03 / NHI05)
TeamPCP compromised the aqua-bot service account - a non-human identity with broad write permissions across the Aqua Security GitHub organization. From this single NHI, attackers pushed malicious workflows to three repositories and stole GPG signing keys, Docker Hub tokens, Twitter credentials, and Slack tokens, exfiltrated via a Cloudflare Tunnel C2.
Stage 3: Credential Harvesting from Runner NHIs (NHI06 / NHI07)
The malicious GitHub Actions payload scraped the runner's GITHUB_TOKEN from process memory, then swept 50+ filesystem paths for AWS, GCP, and Azure credentials, Kubernetes tokens, SSH keys, and cryptocurrency wallets. Harvested data was encrypted with AES-256-CBC and RSA-4096 hybrid encryption then bundled for exfiltration. This is a direct harvest of non-human identities operating inside CI/CD pipelines.
Stage 4: Exfiltration via Typosquatted C2
Primary exfiltration went to the typosquatted domain scan.aquasecurtiy[.]org (note the misspelling), resolving to 45.148.10.212. As a fallback, stolen GITHUB_TOKENs created tpcp-docs repositories in each victim's GitHub organization and uploaded stolen credentials as release assets - weaponizing the victim's own NHI against them.
Stage 5: Developer Machine Persistence (NHI09)
On developer machines (detected by checking GITHUB_ACTIONS != "true"), the malicious Trivy binary installed persistence by writing a Python dropper to ~/.config/systemd/user/sysmon.py and registering it as a systemd unit. The dropper polled an ICP-hosted C2 canister and executed any payload it received.
The NHI Failures That Made This Possible
Every step of this breach maps to a known, preventable NHI governance failure. This is not a zero-day story. It is a governance story.
Overprivileged Service Accounts (NHI05)
The aqua-bot service account held write access across multiple repositories in the organization. A properly scoped NHI would have limited blast radius to a single repository. Instead, one compromised bot became a master key to the entire organization's CI/CD supply chain.
Long-Lived, Unrotated Tokens (NHI07)
TeamPCP's credential stealer specifically targeted long-lived secrets because they persist indefinitely and are rarely audited. Short-lived, ephemeral tokens would have limited the exposure window to minutes rather than days.
Unpinned Action References
75 of 76 trivy-action version tags were force-pushed to malicious versions. Every organization referencing a version tag automatically consumed the malicious payload on its next pipeline run. Tags are mutable. Pinning Actions to immutable full SHA commits would have completely prevented this vector for pinned users.
Unrestricted Default GITHUB_TOKEN (NHI08)
The GITHUB_TOKEN inside GitHub Actions runners defaults to write access. The malware harvested this token as a fallback exfiltration mechanism to create tpcp-docs repos inside victim organizations. Setting permissions: read-all as the organization default closes this vector.
What Security Teams Should Do Now
If your organization ran CI/CD pipelines consuming aquasecurity/trivy-action, aquasecurity/setup-trivy, or Trivy binaries between March 19-23, 2026, treat every secret in those pipelines as compromised.
Immediate: Audit Trivy Versions and Workflow Logs
Check whether your organization pulled or executed Trivy v0.69.4, v0.69.5, or v0.69.6 from any source. Review workflow run logs from March 19-23 for signs of compromise. Search for repositories named tpcp-docs in your GitHub organizations - their presence indicates successful exfiltration.
Immediate: Rotate All Secrets That Touched Affected Pipelines
Rotate any cloud credentials (AWS, GCP, Azure), Kubernetes tokens, SSH keys, and API tokens present in environments running the compromised Actions or Trivy binary. The TeamPCP stealer swept 50+ credential paths. Assume all were captured.
Short-Term: Pin All GitHub Actions to Full SHAs
Replace all version-tag references with immutable full commit SHA hashes. A version tag like @v0.69.0 can be silently redirected; a full SHA cannot be forged. Use tools like StepSecurity's Harden-Runner to automate SHA pinning across your organization's workflows.
Short-Term: Restrict Default GITHUB_TOKEN Permissions
Set permissions: read-all as your organization's default workflow permission. Grant explicit minimal write permissions only on specific jobs that require them. This prevents harvested tokens from being used to create repositories or publish release assets.
Long-Term: Govern Service Account Permissions with Least Privilege
Audit every bot, service account, and automation identity. Each should hold the minimum permissions for its specific function - scoped to a single repository and a narrow action set. Bot accounts with organization-level write access are supply chain attack force multipliers.
Long-Term: Implement Continuous NHI Monitoring
Human identity programs have MFA, conditional access, and risk scoring as table stakes. Non-human identities have none of these by default. Establish equivalent controls: detect anomalous credential usage, flag secrets unused for 90+ days, and alert on any NHI creating repositories or publishing to registries outside established behavioral baselines.
Supply Chains Are NHI Attack Surfaces
The Trivy / TeamPCP incident follows a pattern established by XZ Utils, the event-stream npm compromise, and SolarWinds: supply chain attacks are fundamentally NHI attacks. Attackers do not phish maintainers. They compromise the service accounts, deploy tokens, signing keys, and CI/CD identities that automate software delivery to millions of downstream consumers.
The attack surface is not the developer. It is the machine identity infrastructure the developer trusts implicitly and audits rarely. The question is not whether your supply chain uses non-human identities - it does. The question is whether you can see them, govern them, and detect when they behave outside their expected baseline.
Indicators of Compromise (IOCs)
Security teams can use the following indicators to hunt for signs of the TeamPCP supply chain attack within their environments.
Network Indicators (C2)
scan.aquasecurtiy[.]org(45.148.10.212)plug-tab-protective-relay.trycloudflare.comsys-mon.p-v.sh45.148.10.212
Host-Based Indicators
Filesystem Paths:
~/.config/systemd/user/sysmon.py~/.config/systemd/user/sysmon.service/tmp/.trivy_cache/.db_update_lock(if persistent)
Persistence Mechanism:
- Systemd user unit polling C2 every 3600 seconds.
Binary Hashes (Backdoored Trivy)
Linux (AMD64): 822dd269ec10459572dfaaefe163dae693c344249a0161953f0d5cdd110bd2a0
macOS (ARM64): 6328a34b26a63423b555a61f89a6a0525a534e9c88584c815d937910f1ddd538
macOS (AMD64): f1e2d3c4b5a69788d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2
GitHub Activity
- Creation of repositories named
tpcp-docs - Releases containing
credentials.zip.encorvault_export.bin - Workflow runs involving the
aqua-botidentity outside of normal schedules.
