Skip to content

How to Verify Dependencies with Hashes in uv

Dependency hashes let uv verify that every downloaded artifact matches what was resolved, catching tampering before anything gets installed.

Hashes in uv.lock

uv.lock includes SHA-256 hashes for every distribution by default. After running uv lock or uv add, each entry in the lockfile contains hashes for both sdists and wheels:

[[package]]
name = "certifi"
version = "2026.2.25"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "...", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7" }
wheels = [
    { url = "...", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa" },
]

When uv sync or uv run installs packages, it checks each downloaded artifact against these hashes. If a hash does not match, installation fails.

Hashes in requirements.txt

Some deployment workflows use requirements.txt instead of uv.lock. Two commands produce requirements files with hashes.

uv pip compile with the --generate-hashes flag:

uv pip compile pyproject.toml --generate-hashes -o requirements.txt

This produces output like:

certifi==2026.2.25 \
    --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \
    --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7

uv export includes hashes by default:

uv export -o requirements.txt

To omit hashes, pass --no-hashes.

What hashes protect against

Hash verification guards against artifacts that have been altered after resolution. This covers tampering in transit (man-in-the-middle attacks) and corrupted or malicious mirrors and caches.

Important

Hashes do not protect against a malicious package uploaded directly to PyPI. If an attacker publishes a compromised version through legitimate channels, the hashes will match because they were generated from the compromised artifact itself. For that threat, consider using --exclude-newer to avoid installing recently published versions.

Hash pinning works best alongside other supply-chain protections. A lockfile pins exact versions, while dependency cooldowns add a time-based filter against recently published packages.

Get Python tooling updates

Subscribe to the newsletter
Last updated on

Please submit corrections and feedback...