Nov 21, 2025 Tags: oss, security
TL;DR: Dependency cooldowns are a free, easy, and incredibly effective way to mitigate the large majority of open source supply chain attacks. More individual projects should apply cooldowns (via tools like Dependabot and Renovate) to their dependencies, and packaging ecosystems should invest in first-class support for cooldowns directly in their package managers.
“Supply chain security” is a serious problem. It’s also seriously overhyped, in part because dozens of vendors have a vested financial interest in convincing your that their framing of the underlying problem1 is (1) correct, and (2) worth your money.
What’s consternating about this is that most open source supply chain attacks have the same basic structure:
An attacker compromises a popular open source project, typically via a stolen credential or CI/CD vulnerabilty (such as “pwn requests” in GitHub Actions).
The attacker introduces a malicious change to the project and uploads it somewhere that will have maximum effect (PyPI, npm, GitHub releases, &c., depending on the target).
At this point, the clock has started, as the attacker has moved into the public.
Users pick up the compromised version of the project via automatic dependency updates or a lack of dependency pinning.
Meanwhile, the aforementioned vendors are scanning public indices as well as customer repositories for signs of compromise, and provide alerts upstream (e.g. to PyPI).
Notably, vendors are incentivized to report quickly and loudly upstream, as this increases the perceived value of their services in a crowded field.
Upstreams (PyPI, npm, &c.) remove or disable the compromised package version(s).
End-user remediation begins.
The key thing to observe is that the gap between (1) and (2) can be very large2 (weeks or months), while the gap between (2) and (5) is typically very small: hours or days. This means that, once the attacker has moved into the actual exploitation phase, their window of opportunity to cause damage is pretty limited.

We can see this with numerous prominent supply chain attacks over the last 18 months3:
| Attack | Approx. Window of Opportunity | References |
|---|---|---|
| xz-utils | ≈ 5 weeks4 | Source |
| Ultralytics (phase 1) | 12 hours | Source |
| Ultralytics (phase 2) | 1 hour | Source |
| tj-actions | 3 days | Source |
| chalk | < 12 hours | Source |
| Nx | 4 hours | Source |
| rspack | 1 hour | Source |
| num2words | < 12 hours | Source |
| Kong Ingress Controller | ≈ 10 days | Source |
| web3.js | 5 hours | Source |
(Each of these attacks has significant downstream effect, of course, but only within their window of opportunity. Subsequent compromises from each, like Shai-Hulud, represent new windows of opportunity where the attackers regrouped and pivoted onto the next set of compromised credentials.)
My takeaway from this: some windows of opportunity are bigger, but the majority of them are under a week long. Consequently, ordinary developers can avoid the bulk of these types of attacks by instituting cooldowns on their dependencies.
A “cooldown” is exactly what it sounds like: a window of time between when a dependency is published and when it’s considered suitable for use. The dependency is public during this window, meaning that “supply chain security” vendors can work their magic while the rest of us wait any problems out.
I love cooldowns for several reasons:
They’re empirically effective, per above. They won’t stop all attackers, but they do stymie the majority of high-visibiity, mass-impact supply chain attacks that have become more common.
They’re incredibly easy to implement. Moreover, they’re literally free to implement in most cases: most people can use Dependabot’s functionality, Renovate’s functionality, or the functionality build directly into their package manager5.
This is how simple it is in Dependabot:
1
2
3
4
5
6
7
8
9
version: 2
# update once a week, with a 7-day cooldown
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
(Rinse and repeat for other ecosystems as needed.)
Cooldowns enforce positive behavior from supply chain security vendors: vendors are still incentivized to discover and report attacks quickly, but are not as incentivized to emit volumes of blogspam about “critical” attacks on largely underfunded open source ecosystems.
In the very small sample set above, 8/10 attacks had windows of opportunity of less than a week. Setting a cooldown of 7 days would have prevented the vast majority of these attacks from reaching end users (and causing knock-on attacks, which several of these were). Increasing the cooldown to 14 days would have prevented all but 1 of these attacks6.
Cooldowns are, obviously, not a panacea: some attackers will evade detection, and delaying the inclusion of potentially malicious dependencies by a week (or two) does not fundamentally alter the fact that supply chain security is a social trust problem, not a purely technical one. Still, an 80-90% reduction in exposure through a technique that is free and easy seems hard to beat.
Related to the above, it’s unfortunate that cooldowns aren’t baked directly into more packaging ecosystems: Dependabot and Renovate are great, but even better would be if the package manager itself (as the source of ground truth) could enforce cooldowns directly (including of dependencies not introduced or bumped through automated flows).