How to Protect Against Python Supply Chain Attacks with uv
Malicious packages uploaded to PyPI are usually caught and yanked within hours or days. A dependency cooldown tells uv to ignore packages published within a recent window, so compromised versions get removed before they ever reach your environment.
Set a dependency cooldown
The exclude-newer setting accepts durations and timestamps. For security hardening, durations are the right choice because they create a rolling window that moves forward with the current date.
On the command line
uv lock --exclude-newer "7 days"
uv sync --exclude-newer "7 days"In project configuration
Add the setting to pyproject.toml or uv.toml so it applies to every uv lock and uv sync in the project:
# pyproject.toml
[tool.uv]
exclude-newer = "7 days"# uv.toml
exclude-newer = "7 days"In user-level configuration
Apply the cooldown to all projects on a machine by adding it to the user-level uv.toml:
# ~/.config/uv/uv.toml
exclude-newer = "7 days"Accepted duration formats
| Format | Example | Equivalent |
|---|---|---|
| Friendly duration | "24 hours", "1 week", "30 days" | Rolling window from now |
| ISO 8601 duration | "PT24H", "P7D", "P30D" | Rolling window from now |
| RFC 3339 timestamp | "2026-03-20T00:00:00Z" | Fixed point in time |
Durations are resolved to a fixed number of seconds assuming 24-hour days (DST is ignored). Calendar units like months and years are not allowed.
Choose a cooldown period
The right window depends on how fast a project needs new releases versus how much risk it can tolerate.
7 days is a practical default. Most malicious uploads are detected within this window, and most projects can wait a week for new dependency versions. The litellm supply chain attack in March 2026 was discovered and yanked within hours, so a 7-day buffer would have been more than enough.
30 days suits production deployments and internal tooling where stability matters more than access to recent releases.
Caveats
Silent exclusion. When exclude-newer filters out a package version, uv does not mention it in error messages. If resolution fails because the only matching version was published too recently, the error will say no compatible version exists. Keep this in mind when debugging resolution failures.
Index compatibility. The cooldown relies on the upload-time field defined in PEP 700. PyPI supports this field. Custom or private indexes may not, in which case exclude-newer has no effect for packages hosted there.
Tip
A cooldown protects the moment when new versions enter the dependency tree. A lockfile pins the exact versions that were resolved. Use both together.
Learn more
--exclude-newerfor reproducible environments- LiteLLM supply chain attack and securing Python dependencies
- uv documentation on dependency cooldowns
Also Mentioned In
Get Python tooling updates
Subscribe to the newsletter