Secure Installs
Installing Python packages securely is a best practice recommended by pip. This page describes how to apply these practices when installing MLflow and its dependencies.
Hash-Checking Mode
pip's hash-checking mode verifies that every downloaded package matches a known SHA256 hash, protecting against tampering and man-in-the-middle attacks.
Generating Hashed Requirements
Use pip-compile to resolve all dependencies and generate hashes:
pip install pip-tools
pip-compile --generate-hashes --output-file=requirements.txt requirements.in
Where requirements.in pins your direct dependencies:
mlflow==3.10.1
The generated requirements.txt will include hashes for every package:
mlflow==3.10.1 \
--hash=sha256:abc123... \
--hash=sha256:def456...
numpy==2.2.4 \
--hash=sha256:789abc...
Installing with Hash Verification
pip install --require-hashes -r requirements.txt
All packages (including transitive dependencies) must be pinned with == and have at least one hash. A partially-hashed requirements file is rejected by pip to prevent a malicious package from slipping through an unhashed entry.
Disabling Source Distributions
To further reduce risk, use --only-binary :all: to prevent pip from running arbitrary build code (e.g., via setup.py or PEP 517 build backends) during installation:
pip install --require-hashes --only-binary :all: -r requirements.txt
Filtering by Upload Time
Both pip and uv support filtering packages by their upload date, ensuring that dependency resolution only considers packages published before a known point in time. This protects against newly published malicious versions and enables reproducible builds.
Use an absolute timestamp set to the last date you audited or verified your dependencies. This ensures reproducible installs. Relative durations like "7 days" are convenient for rolling policies but produce different results over time.
pip
pip's --uploaded-prior-to option accepts an ISO 8601 datetime:
# Replace with a date you trust (e.g., the last date you verified your dependencies)
pip install --uploaded-prior-to="2026-03-01T00:00:00Z" mlflow
This only applies to packages from remote indexes (not local files or VCS requirements), and the index must provide upload-time metadata (PyPI does).
uv
uv provides the equivalent exclude-newer setting:
# Absolute timestamp - best for reproducible builds (replace with your own trusted date)
uv pip install --exclude-newer "2026-03-01T00:00:00Z" mlflow
# Relative duration - useful for rolling policies (e.g., always exclude packages newer than 7 days)
uv pip install --exclude-newer "7 days" mlflow
For one-off tool invocations with uvx:
# Absolute timestamp - best for reproducible builds (replace with your own trusted date)
uvx --exclude-newer "2026-03-01T00:00:00Z" mlflow server
# Relative duration - useful for rolling policies (e.g., always exclude packages newer than 7 days)
uvx --exclude-newer "7 days" mlflow server