Dependency Cooldowns: Should You Wait Before Upgrading?
On October 21, seven wheels of litellm 1.107.0 landed on PyPI with a credential stealer that ran every time Python started on the machine, whether or not the program imported litellm. PyPI had quarantined them by 13:23 UTC, less than two hours after the upload. The day before, GitHub previewed a package firewall for Enterprise Cloud customers that by default blocks npm versions younger than one day. A dependency cooldown, a rule that your tools refuse any version until it has been public for a while, would have skipped those wheels.
1. A One-Day Dependency Cooldown Would Have Skipped 1.107.0
On machines that hold secrets, installing a version on the day it appears should be the exception, kept for security fixes, and a cooldown should be the default. LiteLLM 1.107.0 shows why. The poisoned wheels were quarantined on PyPI within two hours, so a Python resolver with a one-day rule would never have offered them. Docker tags are a different story (observation 5).
The strongest objection has two parts. A cooldown also delays the releases you want today, such as the Node.js security release we covered on October 25. And a cooldown only works because somebody else installs early and notices: if everyone waits a day, a patient payload simply runs a day later. Both points hold. Exemptions soften the first; nothing fixes the second, and section 4 comes back to it.
2. From a Leaked Key to a Poisoned Wheel
The timeline below comes from LiteLLM's own incident report and its later root cause analysis. Times are UTC.
- May 27: a config file holding an administrative key for an internal LiteLLM deployment was committed to a public repository. It was deleted three hours later; the key was never revoked.
- October 10: the attacker used that key to obtain an organization owner's GitHub CLI token, then ran CI workflows on throwaway branches that posted repository secrets to an outside endpoint.
- October 21, 10:08: a stolen owner token overrode branch protection to push a change that lets the release workflow build from another repository.
- 10:46: the workflow ran against a lookalike fork, Berri-AI/litellm.
- 11:11: a second stolen maintainer token approved the production gate.
- 11:39:51 to 11:40:13: seven malicious wheels uploaded to PyPI.
- 11:46:56: Docker images published under the v1.107.0, latest, main-latest and main-stable tags.
- 12:06: Lidor Machluf of Upwind Security opened issue #47826 describing the payload.
- 13:23: PyPI had quarantined the release.
- 14:20: the last affected Docker Hub tags were removed or repointed to clean images.
The attacker was inside LiteLLM's GitHub organization eleven days before the release, so the poisoned version came at the end of the attack. The window on PyPI was at most about 1 hour and 43 minutes. Today 1.107.0 is missing from the PyPI release history, while its release candidates rc1 and rc2 are still listed.
3. What a Cooldown Does and Does Not Cover
1. The window was shorter than every default
Dependabot already waits: its options reference says a new version is not considered for a version update until 3 days after its release, even with no cooldown configured, and pip and uv are on the list of supported ecosystems. GitHub's package firewall has a minimum package age that defaults to 1 day. The pnpm settings reference lists 1440 minutes as the default for minimumReleaseAge. All three outlast LiteLLM's window many times over. One caveat on the firewall: the preview announcement limits it to npm and to GitHub Enterprise Cloud, so it would not have touched a Python package or a team on the Free plan.
2. A cooldown on pull requests is not a cooldown on installs
Dependabot's rule decides when it opens a pull request. It has no say over a Dockerfile that runs an unpinned pip install litellm, or a CI job that resolves fresh versions on every run. For those, the rule has to live in the resolver. uv's exclude-newer setting accepts a duration and compares it with the upload time of each file. It is off by default, and we tested it with uv 0.11.32:
# pyproject.toml [tool.uv] exclude-newer = "3 days"
On October 29, uv lock resolved litellm to 1.106.4, uploaded on October 25, and left out 1.106.5 and 1.106.6, both younger than three days.
3. Write the security exemption before you need it
Dependabot's cooldown does not apply to security updates. Resolver-level rules need an exemption you write yourself: uv has exclude-newer-package, pnpm has minimumReleaseAgeExclude, and the firewall's block message links to an exception form. In uv, setting a package to false lifts the cooldown for every future version of it, next month's compromised one included. A date is narrower: it lets in this week's fix and nothing published after it.
# pyproject.toml
[tool.uv]
exclude-newer = "3 days"
exclude-newer-package = { litellm = "2026-10-29T00:00:00Z" }With uv 0.11.32 this pulled in litellm 1.106.6, uploaded the evening before, while the rest of the lockfile kept its three-day rule. Remove the line once you have upgraded.
4. The tag was clean; the wheel was not
LiteLLM's incident report says the v1.107.0 tag on GitHub does not contain the malicious files: the wheels and images were built from the attacker's lookalike repository. A review of the tagged source would have found nothing. The same goes for a release notification. GitWatchman checks the Latest release of each repository every two hours; it can tell you that a version exists, not that the file on PyPI was built from that tag. That is a limit of release notifications built on the source repository, ours included.
5. A cooldown depends on someone else reading new uploads
The issue went up about 27 minutes after the first upload. The cooldown did nothing about the eleven days the attacker spent inside LiteLLM's CI, and it would do little against a payload written to stay quiet for a week. Docker users had a sharper version of the same problem: a moving tag such as latest or main-stable pointed at the poisoned image until 14:20, so pulling it meant installing the newest build.
4. Who Should Install a Release in Its First Hour?
If cooldowns become the norm, and with Dependabot's three-day default they partly are, the first hours of a release belong to whoever opted out: early adopters, projects that test against the newest versions of their dependencies, and security scanners. LiteLLM 1.107.0 was flagged by a security researcher within half an hour. We don't know whether the next one will be caught as fast, and this incident alone says nothing about the average.
Machines that hold secrets (build servers with cloud credentials, developer laptops, production images) wait. A CI job can test against the newest version on day one if it runs with no credentials, no network access beyond the registry and no path into your release artifacts; under those conditions it has little to lose. The risk in that split is concentration: if only scanners and sandboxes install early, a payload that detects sandboxes or waits a week passes through all of them.
Knowing that a release exists is still useful under a cooldown, because the decision moves from "install now" to "read the notes, then decide whether this one skips the queue". That decision is what a release notification is for; an update bot's job is to open pull requests (more in GitWatchman vs Dependabot).
Frequently Asked Questions
What is a dependency cooldown?
A rule that refuses package versions younger than a set age. Dependabot calls it cooldown and counts in days, pnpm calls it minimumReleaseAge and counts in minutes, uv uses exclude-newer with a duration such as "3 days". It gives scanners and maintainers time to catch a bad release before your build installs it.
Does Dependabot apply a cooldown by default?
Yes, for version updates. According to the Dependabot options reference, a new version is not considered for a version update until 3 days after its release, even when cooldown is not configured. The default cooldown does not apply to security updates.
Which LiteLLM versions were compromised in October 2026?
Only 1.107.0. LiteLLM's incident report lists the seven 1.107.0 wheels on PyPI and the Docker Hub and GHCR images tagged v1.107.0, latest, main-latest and main-stable during the window on October 21, 2026. It recommends reinstalling 1.106.2 or another version published before the incident and rotating every credential the host could reach.
Will a cooldown delay security fixes?
Not by default in Dependabot, which exempts security updates from its cooldown. In uv you can exempt one package with exclude-newer-package, in pnpm with minimumReleaseAgeExclude, and GitHub's package firewall offers an exception request from the block message. In uv, prefer a date over false: false lifts the cooldown for every future version, including the next bad one.
Hear about a release, then decide when to install it
Follow up to 5 GitHub repositories for free during the beta. GitWatchman sends new releases by email, Slack, Discord or Telegram, or to your personal RSS feed.
Start tracking for free