What Actually Happened
On May 22, 2026, between 05:52 and 06:01 UTC, someone pulled roughly 170 private GitHub repositories belonging to CrowdSec — the open-source threat intelligence company known for its community-driven intrusion detection system. The download originated from an IP in Toronto, Canada, tied to a machine with its timezone set to UTC-4. The credentials used were an OAuth token belonging to a developer who had recently left the company.
That sounds clean and simple in short. It wasn't. The OAuth token wasn't phished or brute-forced. It was harvested by malware — specifically the Shai-Hulud implant distributed through 42 backdoored npm packages published as part of the TanStack ecosystem. The developer's laptop ran an infected npm install, the malware swept every credential it could reach, and one of those credentials happened to still have read access to CrowdSec's entire private source tree.
CrowdSec published their full incident analysis on September 18, 2026. TanStack issued a postmortem on May 11. Socket tracked the broader "Mini Shai-Hulud" campaign across multiple ecosystems. Stitching these together reveals a supply-chain compromise that exploited not one vulnerability, but a chain of trust assumptions that most organizations still hold.
The TanStack Compromise: Cache Poisoning as Attack Primitive
The TanStack supply-chain attack deserves its own section because the mechanism was genuinely novel.
On May 10 at 17:16 UTC, an attacker created a fork of TanStack/router deliberately named zblgg/configuration — the renaming was intentional to evade fork-list search tools. The next day, a commit authored by a fabricated identity (claude <[email protected]>) introduced a ~30,000-line bundled JavaScript payload called vite_setup.mjs into the fork.
Here's the clever part. The bundle-size.yml GitHub Actions workflow used the pull_request_target trigger. This trigger runs with the permissions of the base repository and bypasses the first-time-contributor approval gate. The attacker opened PR #7378, force-pushed the malicious commit to it, and the workflow auto-ran without any maintainer ever clicking approve.
During that execution, the workflow wrote a 1.1 GB poisoned cache entry to GitHub Actions cache under the main branch scope. The attacker then immediately force-pushed the PR back to a benign diff, closed it, and deleted the branch. To anyone watching the PR list, nothing happened.
When the next legitimate release workflow ran on May 11, it restored that poisoned cache. The vite_setup.mjs payload executed during the build step, harvested credentials, and — critically — self-published 42 backdoored packages to the npm registry by minting its own OIDC token using the workflow's id-token: write permission. The official Publish step had been skipped because tests failed. The malware published independently.
This distinction matters. The OIDC trusted-publisher binding for TanStack/router release.yml looked legitimate to npm's registry. The packages came from the expected GitHub repository and the expected workflow file. Only the execution path was hijacked.
AI Cybersecurity Threats in the Supply-Chain Context
This attack belongs to a broader category of AI cybersecurity threats that exploit the velocity assumptions baked into modern CI/CD pipelines. The term "AI" here doesn't refer to a large language model writing malware — though that's coming. It refers to threats that specifically target the automated decision-making that AI-assisted development relies on: the cache that builds restore, the OIDC token that publishes, the trusted-publisher binding that makes a package legitimate.
TeamPCP (tracked as UNC6780) demonstrated sophistication that mirrors agentic tooling's own attack surface. The malware fingerprints its execution environment across three dimensions, CI platform, operating system, and JavaScript runtime, before initiating any malicious behavior. This gating prevents noisy credential requests in environments where they would fail or trigger alerts. It's an attacker's equivalent of the "minimum viable footprint" that any well-architected AI agent aims for.
The Mini Shai-Hulud campaign didn't stop at TanStack. Socket confirmed compromised artifacts across Mistral AI's npm and PyPI packages, OpenSearch, Guardrails AI, and UiPath within 48 hours. The [email protected] package on PyPI downloads a remote Python artifact from git-tanstack.com/transformers.pyz, a domain deliberately chosen to look like part of the TanStack ecosystem, and executes it without integrity verification. It was a reminder that npm registry abuse is a sustained theater of operations, not a one-off: Amazon's attribution of a wave of npm attacks to North Korean Sapphire Sleet showed the same ecosystem under persistent, well-resourced pressure.
How CrowdSec's Repositories Walked Out the Door
The developer who left CrowdSec did so on good terms. He retained GitHub organization membership because he wanted to finalize some work. This is a practice that feels humane and costs nothing, until it does.
The TanStack malware harvested OAuth tokens from common locations: environment variables, the gh CLI config, .git-credentials files, and ~/.npmrc. On that developer's machine, at least one of those locations contained a token with GitHub repository read access. The malware then exfiltrated over the Session messenger file-upload network (filev2.getsession.org), which uses end-to-end encryption. There's no attacker-controlled C2 domain to block. Network-level mitigation requires blocking the entire messenger infrastructure, which most organizations won't do.
Once TeamPCP had the token, they cloned all accessible repositories in a nine-minute window. No commits. No code modifications. Pure exfiltration. It is the same failure mode that let a third-party OAuth flaw expose LastPass CRM data: a token living on a trusted path that nobody thought to revoke in time.
CrowdSec revoked the developer's GitHub access on May 25, three days after the theft. They kept the account alive because they'd parted amicably and he intended to finish work. In hindsight, this was a reasonable human decision with a terrible security consequence.
Exfiltration Infrastructure and Self-Propagation
The Shai-Hulud implant doesn't just steal, it spreads. After harvesting credentials, it enumerates other packages the victim maintains by querying registry.npmjs.org/-/v1/search?text=maintainer:<user> and republishes each one with the same injection. One compromised developer becomes a vector into every project they publish.
Socket identified two persistence mechanisms that make simple npm uninstall insufficient for remediation: malicious optionalDependencies that trigger postinstall scripts, and a second vector through VS Code's workspace task auto-run feature. The attacker gets a foothold that survives the removal of the initial compromised package. The ecosystem's answer is arriving at the registry level: npm v12 will require explicit approval for install scripts and non-registry dependencies, closing the exact postinstall channel this campaign abused by default.
Defenses That Would Have Blunted This
Drawing from the TanStack postmortem and Socket's analysis, several concrete practices emerge:
Restrict OIDC token scopes. Set permissions: id-token: none in every workflow that doesn't explicitly need to publish packages. Pin id-token: write only to the specific publishing job. This single change prevents a cache-poisoned build from minting publish tokens.
Audit pull_request_target usage. This workflow trigger runs with elevated permissions. Any workflow using it that also performs caching or has write access to the registry is a target. Pin third-party action refs to commit SHAs rather than mutable tags.
Treat Sigstore provenance badges skeptically. The TanStack incident demonstrates that an attacker with code execution in GitHub Actions can generate valid Sigstore attestations for malicious packages. A provenance badge proves the package was built in CI, not that the CI was uncontaminated.
Revoke organization membership at separation, not after. "He wanted to finish some work" is a reasonable sentiment. A scoped service account with an explicit deadline is the safe version of that sentiment — the same discipline behind hunting ghost credentials in the cloud, applied to departing humans rather than orphaned machine identities. The same discipline is exactly what defenders are now building for machine actors too: the push for identity control planes that gate what autonomous agents can access applies just as much to a lingering human account as to an AI agent.
Monitor for anomalous git clones. The nine-minute bulk download of 170 repositories is statistically distinguishable from normal developer behavior. GitHub's API exposes git activity in windows that most organizations never query. CrowdSec only got this data because they asked GitHub support after the fact.
What This Means for Securing Software Supply Chains in 2026
The CrowdSec incident isn't a cautionary tale about bad actors being clever. It's a structural warning about the gaps between human organizational practices and machine-speed attack automation. A developer leaving on good terms. A workflow that caches aggressively. A publishing identity trusted by a package registry. An end-to-end encrypted messenger used for exfiltration. Each system behaved as designed — and the combination produced a breach.
As AI agents increasingly write, test, and publish code autonomously, these trust boundaries become more consequential. An agent with access to package registries, GitHub Actions, and cloud secrets can reproduce this exact attack pattern at machine speed. Securing AI development workflows requires treating every cache, token, and automated identity as a potential exfiltration path — and building controls that assume compromise rather than trust the happy path.