A supply chain attack compromises software you trust, a package, a GitHub Action or a build pipeline, so that its next update delivers the attacker's code to everyone downstream. In March 2026 it happened to Trivy, LiteLLM and axios within two weeks. Every link in that chain ran on credentials that had leaked and were still valid.
- On March 19, 2026, a group calling itself TeamPCP poisoned Trivy's GitHub Actions with a credential stealer. Secrets stolen from pipelines that ran it opened LiteLLM's PyPI publishing five days later.
- Trivy itself fell because a credential rotation after an earlier incident was incomplete. Aqua's own words: the process "wasn't atomic."
- axios was a separate campaign the same month. Attackers hijacked a maintainer's account and published two malicious versions of a package with over 100 million weekly downloads.
- None of these started with a vulnerability in the product's code. They started with a credential an attacker could reach. That is an external attack surface problem, and you can test for it.
What is a supply chain attack?
A supply chain attack is when an attacker compromises something you depend on instead of attacking you directly. You install the update, your build runs the action, your site loads the script, and the attacker's code runs with your permissions.
In software, the "something" is usually one of four things:
| Link in the chain | What the attacker takes over | 2026 example |
|---|---|---|
| A maintainer's account | The npm or PyPI identity that publishes the package | axios (npm), LiteLLM (PyPI) |
| A CI/CD pipeline | A GitHub Action or workflow that runs with secrets | Trivy's trivy-action and setup-trivy |
| A package name | An internal name nobody reserved on the public registry | Dependency confusion (our finding below) |
| A hosted asset | The bucket or CDN that serves JavaScript to your pages | A retail CDN (our finding below) |
A software supply chain attack is the same idea applied to code: the target is the path code travels from a developer's keyboard to production. It pays well for one reason. You compromise one project and get every organization that trusts it.
What happened in March 2026?
Two campaigns hit at least five widely used projects in 13 days. Here is the timeline, using only what the affected vendors and the researchers who caught it published:
| Date (2026) | What happened | Source |
|---|---|---|
| Late February | An attacker exploits a misconfiguration in Trivy's GitHub Actions and extracts a privileged access token. | Aqua |
| March 1 | Trivy discloses the incident and rotates credentials. The rotation is not complete. | Aqua |
| March 19 | Using credentials that survived, TeamPCP force-pushes 76 of 77 version tags of trivy-action and all 7 tags of setup-trivy to a credential stealer, and publishes a malicious Trivy v0.69.4. | Trivy advisory |
| March 21 | The same group compromises Checkmarx's KICS GitHub Action. | Datadog, Aqua |
| March 24 | Malicious LiteLLM 1.82.7 and 1.82.8 appear on PyPI, published with credentials stolen through the Trivy pipeline. | LiteLLM, Elastic |
| March 27 | Two backdoored versions of the telnyx PyPI package follow. | Datadog, Elastic |
| March 31 | A hijacked maintainer account publishes axios 1.14.1 and 0.30.4. The malicious versions are live for about three hours. | Datadog, CISA |
| April 20 | CISA publishes an alert on the axios compromise. | CISA |
Two details matter. First, Trivy and KICS are security scanners. Teams run them inside CI with access to secrets because that's their job. Second, Datadog assessed with reasonable confidence that axios was a different actor from TeamPCP. It was suspected to be a DPRK operation. Same month, different crews, and the same way in.
How did TeamPCP get from Trivy to LiteLLM?
Through secrets that one pipeline handed to the next. The malicious trivy-action ran its stealer before the real scan, so every build looked normal. Per Aqua's advisory, it dumped the GitHub runner's memory, swept more than 50 file paths for SSH keys and cloud, Kubernetes and Docker credentials, encrypted the haul and shipped it out.
LiteLLM used Trivy in its CI security scanning workflow. LiteLLM's own post says the compromise originated there. Elastic is more direct: TeamPCP stole LiteLLM's PyPI publishing credentials through the poisoned Trivy pipeline and pushed malicious versions that harvested SSH keys, cloud credentials, API keys and wallet data. Those versions were live for about 40 minutes before PyPI quarantined them.
Now go back one step. Why did Trivy fall on March 19 at all? Aqua answered it in public, which I respect: "Our containment of the first incident was incomplete. We rotated secrets and tokens, but the process wasn't atomic." The attacker held a valid token during the rotation window and could read the new secrets as they were issued.
"The Trivy to Litellm to Telnyx cascade happened because stolen creds weren't rotated quickly enough."
That's Joe Desimone of Elastic, the researcher who caught axios, summing up the whole month in one line.
Was the axios attack part of the same chain?
No, but it came in through the same kind of door. On March 31 an attacker published axios 1.14.1 and 0.30.4. The code was identical to the clean release except for one new dependency, plain-crypto-js, a lookalike of crypto-js. Its postinstall script downloaded a remote access trojan for macOS, Windows or Linux, then deleted itself and swapped in a clean package.json to hide the hook.
How did they get in? Not through axios's code. The maintainer later explained that attackers social-engineered him through a fake company Slack workspace and a Teams call, and had him install an "update" that was a RAT. That gave them his npm credentials. Datadog's analysis of the registry metadata shows the rest. The clean 1.14.0 was published through GitHub Actions trusted publishing. The malicious 1.14.1 was published straight from the account, with the email changed to a ProtonMail address. The maintainer said the 1.x line used trusted publishing but 0.x still relied on a long-lived npm token, which he revoked afterwards.
The scale is why this one made CISA's list. Datadog counts more than 100 million weekly downloads and 174,000 dependent packages. Anyone who ran npm install with a caret range during those three hours could have pulled the RAT, including through transitive dependencies and third-party GitHub Actions they never looked at.
What do all of these attacks have in common?
A credential that was reachable from outside and still worked. Put the March incidents next to the one LiteLLM published in October, and the pattern is hard to miss:
| Incident | What the attacker used | Where it came from | Rotated in time? |
|---|---|---|---|
| Trivy (Mar 19) | A privileged token from the February foothold | A misconfigured GitHub Actions workflow | No. Rotation "wasn't atomic" |
| LiteLLM (Mar 24) | PyPI publishing credentials | Stolen from CI by the poisoned Trivy action | No |
| axios (Mar 31) | The maintainer's npm credentials | A RAT planted on his machine through social engineering | Revoked after the release. The 0.x line still ran on a long-lived token |
| LiteLLM (Oct 21) | An administrative key to an internal agent platform | A config file committed to a public repo on May 27 | No. "Nobody followed through on revoking" it |
That last row is my favorite, and not in a good way. LiteLLM deleted the file about three hours after the commit. The commit stayed in the repo's public history. On October 10 the attacker used the key, pulled a GitHub token belonging to an organization owner out of the platform's agent configuration, and eleven days later shipped a malicious release. LiteLLM wrote that the incident "has provided a strong illustration of the risks associated with failing to rotate a potentially exposed key."
The code in these products has a million eyes on it. The external attack surface around them has none. Nobody runs a code review on a token sitting in git history.
What does a supply chain attack look like from the outside?
Exactly like the March chain, only nobody has found it yet. At Cylent we test our clients' external attack surface with agents, with permission, and an operator validates every path before it reaches the client. Supply chain paths come up more than anything else. Three examples, names removed:
A retail platform's public Android app shipped a plaintext source-control password. It opened 232 private repositories. In the git history of one of them sat a cloud service-account key that someone had deleted from the code in 2018 and never rotated. It still worked. It had write access to the storage bucket that serves checkout-page JavaScript, including a payment SDK, to 156 live retail sites. One write, and a card skimmer runs on all of them at once. We confirmed write permission without changing a single file and reported it through Israel's National Cyber Directorate.
Two public GitHub workflows used pull_request_target, checked out the pull request's code and ran yarn install on it, behind an "authorize" gate whose environment had no protection rules. Any GitHub user could open a pull request and run code with production secrets loaded. We proved each link up to a publish workflow that reached the npm publish step with the deploy token in place, then stopped. The full write-up is on Cylent Labs.
A global identity-verification provider had public repositories declaring internal, unscoped npm package names that were never registered on the public registry. We published a benign package under one of those names. It reached about 274 weekly downloads, and real machines called back from inside node_modules.
Different entry points, one lesson. In each case the attacker's first step needed no exploit. It needed something exposed: a password in an app, a workflow trigger, a name in a package.json. That is what a continuous external red team looks for, and it's why we judge findings by whether they're exploitable, not just present.
How do you defend against a software supply chain attack?
Make stolen credentials expire faster than attackers can use them, and stop pulling new code blindly. This week:
- Add a package cooldown. CISA recommends
min-release-age=7in.npmrc. pnpm, Yarn and uv have equivalents. Datadog found that half of organizations use third-party libraries within a day of release. axios was live for three hours. - Pin third-party GitHub Actions to full commit SHAs. Version tags are mutable. TeamPCP rewrote 76 of 77 of them on one action. Trivy's own advisory now says SHA pinning is the protection that holds.
- Grep your workflows for
pull_request_target. If it checks out the pull request's code, treat it as an open door. Add apermissions:block andpersist-credentials: false, and put real protection rules on any environment that gates secrets. - Rotate like the attacker is watching. Revoke the old credential, issue the new one, then confirm the old one fails. If a compromised version ran in a pipeline, rotate every secret that run could see.
- Retire long-lived publish tokens. Move package publishing to trusted publishing (OIDC) and revoke the tokens left on older release lines. axios had both side by side.
- Set
ignore-scripts=truewhere your builds allow it, so apostinstallhook can't run on install. - Reserve your internal package names on public registries, or move them under a scope you own.
- Look for your own credentials from the outside. Public repos and their full history, app bundles, front-end JavaScript, employees' personal GitHub accounts. Deleting a commit doesn't remove it from history. Only revoking the key ends it.
The last item is the one most teams skip, because no single tool owns it. It's also where every chain in this article started. If you want to see how fast that window closes, look at how quickly vulnerabilities get exploited in 2026, and at what happens when a swarm of AI agents finds exposed tokens first.
FAQ
What is a supply chain attack?
An attack on software or a service you depend on, rather than on you. The attacker compromises a package, a build pipeline, a maintainer account or a hosted script, and the next update delivers malicious code to everyone who trusts it.
What is TeamPCP?
A threat group that compromised Trivy's GitHub Actions on March 19, 2026, then used credentials stolen from CI pipelines to compromise Checkmarx's KICS action, LiteLLM and Telnyx within days. Aqua notes the malware labels itself "TeamPCP Cloud stealer."
Was the axios supply chain attack part of TeamPCP?
Datadog assessed with reasonable confidence that it was not. axios was compromised on March 31, 2026 through a hijacked maintainer account, and Elastic reported presumed attribution to DPRK state actors.
Which axios versions were malicious?
axios 1.14.1 and 0.30.4, published March 31, 2026 and removed after about three hours. CISA advises downgrading to 1.14.0 or 0.30.3, deleting node_modules/plain-crypto-js/, and rotating any credentials exposed on affected systems or pipelines.
What is a package cooldown?
A setting that makes your package manager skip versions newer than a set age, such as seven days. Compromised releases are usually caught within hours or days, so a cooldown keeps most of them out of your builds. npm calls it min-release-age.
The bottom line
March 2026 didn't need a single new vulnerability class. A misconfigured workflow, a rotation that missed a token, a maintainer who installed a fake update, a key deleted from a file but not revoked. Each one was reachable from outside. Each one was cheap to use. The attackers simply got there before the owners did.
So here's my question: if someone went through your public repos, your app bundles and your CI configuration tonight, how many working keys would they find, and how many of those did someone on your team already "delete"?
Sources
- Aqua Security, Trivy supply chain attack: what you need to know (March 22 – April 1, 2026)
- Aqua Security, GHSA-69fq-xp46-6x23: Trivy ecosystem supply chain temporarily compromised
- Aqua Security, Trivy security incident 2026-03-19, discussion #10425 (March 20, 2026)
- LiteLLM, Security Update: Suspected Supply Chain Incident (March 24, 2026)
- LiteLLM, The attack chain behind the v1.107.0 LiteLLM release (October 23, 2026)
- Elastic Security Labs, How we caught the Axios supply chain attack (April 2, 2026)
- Datadog Security Labs, Compromised axios npm package delivers cross-platform RAT (April 3, 2026)
- Datadog Security Labs, LiteLLM and Telnyx compromised on PyPI: Tracing the TeamPCP supply chain campaign (March 2026)
- CISA, Supply Chain Compromise Impacts Axios Node Package Manager (April 20, 2026)
- Snyk, Trivy GitHub Actions Supply Chain Compromise (March 2026)
- Cloud Security Alliance, TeamPCP: CI/CD Kill Chain from Trivy to the EU (April 3, 2026)
- GitHub Docs, Secure use reference: using third-party actions
- Cylent Labs, One pull request to own the supply chain