To use pip hash checking, pin every requirement with == and add a hash for each, then install with the require hashes option. pip will refuse any package whose hash differs from the file. It protects against tampering and surprise releases, but it only works if every dependency, including transitive ones, is listed.
What hash checking does
The pip documentation describes hash checking mode as using local hashes embedded in a requirements.txt file to protect against remote tampering and network issues. Each requirement gets a hash option. Specifying a hash on any requirement turns the mode on for the whole install.
For a client project this is a cheap guarantee. A build next year installs the same bytes you tested today, or it fails.
The rules pip enforces
- Hashes are required for all requirements. A partially hashed file could let an unhashed package through, so pip errors if a dependency is missing from the file.
- Requirements must be pinned with ==, or to a URL or file path. Loose specifiers could cause a hash mismatch the moment a new release appears.
- Hashes shown by the package index as a URL fragment do not count. They catch corrupted downloads, but they come from the remote source, so they are not a local check.
- Local directories and VCS URLs do not mix well with enforced hashes. Since pip 26.2 there is an option to disable enforcement, so hashes are checked only where given. Check your own pip version's documentation.
Steps
- Pin direct dependencies in a requirements.in file.
- Generate a fully pinned file with hashes using a tool such as pip-tools.
- Commit the generated requirements.txt.
- Install in CI and deploys with hash enforcement on.
pip install --require-hashes -r requirements.txt
The documentation also notes the option is a handy way to bootstrap your list, since pip shows the hashes of packages it fetched.
The same page suggests disallowing source distributions with the only binary option for a stricter install. Be aware that some packages are only published as source, so test before you make it a policy.
Where it fits for agencies
Use it on projects that will be rebuilt by someone else. Hashes mean the client does not need to trust that nothing moved. Add an update routine, because pinned files age. A tool that regenerates the file on a schedule and opens a pull request keeps it fresh.
Hash checking proves the package matches what you recorded. It does not prove the package is free of vulnerabilities or malice at the time you recorded it. Scan the pinned set separately.
Quick check
Can I hash only my direct dependencies?
No. pip requires hashes for all requirements, including transitive ones, once hash checking is on.
Does hash checking stop a malicious package?
Not if the malicious version was already pinned. It stops later swaps, not bad choices at pin time.
Sources
Last reviewed: 19 October 2026.