Skip to content

uv Gets Built-In Vulnerability and Malware Scanning

Astral's uv package manager adds `uv audit` and optional install-time malware checks powered by OSV, closing supply-chain gaps that separate tooling can't easily address.

AI
DevClubHouse Curation
Jun 8, 2026 · 5 min read · 1 comments

Supply-chain security for Python projects just got a first-class seat at the table. Astral has shipped two new security features in uv: a uv audit command for scanning dependencies against known vulnerability databases, and an opt-in malware check that fires on every install operation before any malicious code can execute. Both are in preview, but they signal a clear architectural direction: security primitives baked into the package manager itself, not bolted on afterward.

What uv audit Does

uv audit is uv's native replacement for pip-audit and similar tools. It scans your locked dependency graph against known vulnerabilities and flags "adverse" project statuses — things like a package being deprecated or otherwise problematic. Because it operates directly on uv's already-resolved lockfile, it skips a lot of redundant work that standalone tools have to repeat from scratch.

The performance difference is measurable: Astral reports uv audit is 4x–10x faster than pip-audit on typical projects. That speedup comes from leveraging the same performant primitives already in uv — async networking, caching, and package resolution — rather than spinning up a separate process that has to re-derive the dependency graph.

Configuration lands where you'd expect it: uv.toml and pyproject.toml, so audit behavior travels with the project rather than living in a separate config file that's easy to drift or lose.

The Malware Problem Is Different

Vulnerability scanning and malware scanning sound similar, but the remediation profiles are meaningfully different, and that difference drives the architectural choice to handle them separately.

A CVE in a dependency is usually a passive concern: patch to a fixed version and move on, unless the vulnerability is being actively exploited in your environment. Malware is an immediate incident. Credential theft, exfiltration, and backdoor installation don't wait for your next sprint cycle. The moment malware runs, the damage may already be done.

There's also a subtler lockfile problem that makes standard index-level quarantine insufficient. When PyPI quarantines a malicious package, it's removed from the index — but a uv.lock file often points directly to the underlying object storage URL. That URL remains valid even after quarantine. A locked installer following the lockfile can still fetch and install the malicious distribution, completely bypassing the index-level protection that most users assume is sufficient.

This is why Astral built the malware check as an install-time operation rather than a discrete audit command. When UV_MALWARE_CHECK=1 is set, every uv add, uv sync, or other command that triggers a sync will query OSV for MAL advisories against the current locked resolution. If any package matches a known malware advisory, the sync is terminated before the malicious code has a chance to run.

Enabling Malware Checks

The malware check is opt-in for now. Set the environment variable to try it:

export UV_MALWARE_CHECK=1
uv sync

Astral says they'll evaluate making it the default in a future release. The preview status exists specifically to allow the team to iterate on design — the feature is considered unstable, and breaking changes are possible.

Why Build This Into uv at All?

Python already has pip-audit and safety. The argument for building auditing directly into uv comes down to two things: integration depth and context.

Standalone audit tools are either run as a discrete CI step — disconnected from the actual install flow — or they're noisy in the npm-install style, where you get a wall of vulnerability warnings at exactly the moment you don't want to deal with them. Neither experience is particularly good at actually changing developer behavior.

Building scanning into the package manager opens a third path. Astral sketches out two examples of where this could go:

  • Vulnerability-aware resolution: locking a resolution that also takes known vulnerability data into account, producing a result that preserves compatibility while minimizing vulnerability count and severity.
  • Per-addition alerts: uv add warns you about vulnerabilities only when they appear in a newly added dependency, rather than re-reporting the entire graph every time. This targets alert fatigue directly — you still get in-flow warnings, but only when you're actively making a dependency decision.

Neither of these is possible with a tool that doesn't have deep access to the resolver's internal state. That's the core case for integration.

What's Still Ahead

Astral flags improving finding precision as a future goal. Most vulnerability advisories affect specific APIs within a package — not every consumer of a dependency actually calls the vulnerable code path. Surfacing only the alerts that are relevant to your actual usage requires coordination between the vulnerability database, the package metadata, and static analysis of your code. That's a hard problem and one that the source acknowledges involves "three traditionally separate" components working together. No timeline is given, but naming it explicitly suggests it's on the roadmap.

For now, the practical takeaway is straightforward: if you're using uv, run uv audit in CI and set UV_MALWARE_CHECK=1 in environments where supply-chain risk matters. Both features are preview-quality — expect the API surface to change — but the underlying mechanics are solid enough to start building into your workflows today.

Discussion 1

Join the discussion

Sign in with GitHub to comment and vote.

Sign in with GitHub
Kat Sorensen @contrarian_kat · 49 minutes ago

i'm curious to see how the optional install-time malware checks will impact performance, especially for larger projects - will the benefits outweigh the potential slowdown?

Related Reading