On November 25th, 2025, we were on a routine Slack huddle debugging a production issue when we noticed something strange: a PR in one of our internal repos was suddenly closed, showed zero changes, and had a single commit from... Linus Torvalds?
The commit message was just "init."
Within seconds, our #git Slack channel exploded with notifications. Dozens of force-pushes. PRs closing across multiple repositories. All attributed to one of our engineers.
We had been compromised by Shai-Hulud 2.0, a sophisticated npm supply chain worm that compromised over 500 packages, affected 25,000+ repositories, and spread across the JavaScript ecosystem. We weren't alone: PostHog, Zapier, AsyncAPI, Postman, and ENS were among those hit.
This is the complete story of what happened, how we responded, and what we've changed to prevent this from happening again.
No Trigger.dev packages were ever compromised. The @trigger.dev/* packages and trigger.dev CLI were never infected with Shai-Hulud malware. This incident involved one of our engineers installing a compromised package on their development machine, which led to credential theft and unauthorized access to our GitHub organization. Our published packages remained safe throughout.
The Attack Timeline
Time (UTC) Event Nov 24, 04:11 Malicious packages go live Nov 24, ~20:27 Engineer compromised Nov 24, 22:36 First attacker activity Nov 25, 02:56-05:32 Overnight reconnaissance Nov 25, 09:08-15:08 Legitimate engineer work (from Germany) Nov 25, 09:10-09:17 Attacker monitors engineer activity Nov 25, 15:17-15:27 Final recon Nov 25, 15:27-15:37 Destructive attack Nov 25, ~15:32 Detection Nov 25, ~15:36 Access revoked Nov 25, 16:35 AWS session blocked Nov 25, 22:35 All branches restored Nov 26, 20:16 GitHub App key rotated
The compromise
On the evening of November 24th, around 20:27 UTC (9:27 PM local time in Germany), one of our engineers was experimenting with a new project. They ran a command that triggered pnpm install . At that moment, somewhere in the dependency tree, a malicious package executed.
... continue reading