Skip to main content

pip-compile wrapper with CVE awareness

Project description

safe-pip-compile

PyPI Python License: MIT

safe-pip-compile is a drop-in pip-compile wrapper that avoids pinning Python packages with known CVEs.

pip-compile is excellent at resolving repeatable dependency sets, but it does not know whether a resolved version has a published vulnerability. safe-pip-compile adds that missing safety loop: compile, audit against OSV.dev, constrain vulnerable versions out of the result, and retry until the lock file is clean or the configured limit is reached.

Why use it?

  • Keep the familiar pip-compile workflow.
  • Block vulnerable package versions before they land in requirements.txt.
  • Use severity thresholds, allowlists, JSON reports, and CI-friendly exit codes.
  • Cache OSV results locally so repeated runs stay fast.
  • Pass normal pip-compile flags through when you need them.

Installation

pip install safe-pip-compile

Project page: https://pypi.org/project/safe-pip-compile/

Quick start

safe-pip-compile requirements.in -o requirements.txt

Input:

django
requests

Output:

# Generated by safe-pip-compile
# Vulnerable versions are excluded when OSV.dev reports a blocking CVE.
django==...
requests==...

How it works

requirements.in
  -> pip-compile
  -> parse resolved packages
  -> check local cache or query OSV.dev
  -> filter by severity and allowlist
  -> add temporary constraints for vulnerable versions
  -> repeat until clean, stuck, or max iterations is reached
  -> requirements.txt

When a vulnerable package is found, safe-pip-compile asks the resolver for a safe alternative by adding constraints such as django>=3.2.25. It keeps the dependency resolver in charge instead of hand-editing pinned output.

CLI flags

Flag Description Default
-o, --output-file PATH Output requirements.txt path requirements.txt
--min-severity LEVEL Only block CVEs at this level or above: critical, high, medium, low low
--allow-list PATH YAML file of accepted CVEs to skip none
--max-iterations INT Maximum compile/audit loops before stopping 10
--strict / --no-strict Exit with code 1 if unresolved CVEs remain --strict
--dry-run Preview actions without writing output files off
--json-report PATH Write a machine-readable JSON vulnerability report none
--cert PATH CA bundle for SSL verification behind corporate proxies auto-detect from env
--no-cache Disable the local CVE cache and always query OSV.dev cache enabled
--refresh-cache Clear cached data and re-fetch from OSV.dev off
-v, --verbose Increase output detail. Use -v or -vv quiet

All other flags after -- are passed through to pip-compile.

safe-pip-compile requirements.in -- --generate-hashes --allow-unsafe

Examples

Block only high and critical vulnerabilities:

safe-pip-compile requirements.in --min-severity high

Accept specific CVEs through an allowlist:

safe-pip-compile requirements.in --allow-list cve-allowlist.yaml

Generate a JSON report and fail CI on unresolved CVEs:

safe-pip-compile requirements.in --json-report audit.json --strict

Preview without writing files:

safe-pip-compile requirements.in --dry-run -v

Bypass or refresh the local cache:

safe-pip-compile requirements.in --no-cache
safe-pip-compile requirements.in --refresh-cache

Allowlist format

Create cve-allowlist.yaml when your team has reviewed and accepted a specific risk:

allowed_cves:
  - id: CVE-2024-12345
    reason: "Not applicable; we do not use the affected feature"
    expires: 2025-06-01

  - id: GHSA-xxxx-yyyy-zzzz
    reason: "Accepted risk, tracked in JIRA-789"

Allowlist entries are matched against the vulnerability ID and aliases such as CVE, PYSEC, and GHSA identifiers.

pyproject.toml config

[tool.safe-pip-compile]
max-iterations = 10
min-severity = "high"
allowlist = "cve-allowlist.yaml"
strict = true

CLI flags override pyproject.toml values.

Exit codes

Code Meaning
0 Clean result: no blocking CVEs found
1 Unresolved CVEs remain in strict mode
2 pip-compile resolution failed
3 Network or configuration error

Local CVE cache

Vulnerability data is cached in a local SQLite database to avoid repeated OSV.dev API calls.

Platform Cache path
Linux ~/.cache/safe-pip-compile/cache.db
macOS ~/Library/Caches/safe-pip-compile/cache.db
Windows C:\Users\Teja\AppData\Local\safe-pip-compile\Cache\cache.db

Cache behavior:

  • Fixed vulnerabilities are cached for 6 months.
  • Vulnerabilities without a fix are not cached permanently, so a newly published fix can be picked up on a later run.
  • The cache is stored per user and works across virtual environments.
  • SQLite WAL mode allows concurrent readers.

Corporate proxy and SSL

If your organization performs SSL inspection, OSV.dev requests may fail with a certificate verification error.

Use a custom CA bundle:

safe-pip-compile requirements.in --cert /path/to/corporate-ca-bundle.pem

Or set one of the standard certificate environment variables:

export SSL_CERT_FILE=/path/to/corporate-ca-bundle.pem
export REQUESTS_CA_BUNDLE=/path/to/corporate-ca-bundle.pem

Lookup order:

Lookup order: `--cert` flag > `SSL_CERT_FILE` > `REQUESTS_CA_BUNDLE` > `CURL_CA_BUNDLE` > system default.

Development

pip install -e ".[dev]"
python -m pytest tests -v

Author

Built and maintained by N Venkata Sai Teja.

For more projects, writing, and contact details, visit venkatasaiteja.in or connect on LinkedIn.

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

safe_pip_compile-0.1.4.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

safe_pip_compile-0.1.4-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file safe_pip_compile-0.1.4.tar.gz.

File metadata

  • Download URL: safe_pip_compile-0.1.4.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for safe_pip_compile-0.1.4.tar.gz
Algorithm Hash digest
SHA256 18512a1170e1bc83a0755c0d5b9eb773155109344dde16415bae4fe352acf4d4
MD5 3d7f29b048524c611cf779feca1be875
BLAKE2b-256 6f4b595f55efd762b8adc8826e2c3b908a4d9b24bb5b28d3879f714693275cdf

See more details on using hashes here.

Provenance

The following attestation bundles were made for safe_pip_compile-0.1.4.tar.gz:

Publisher: publish.yml on sai1027/safe-pip-compile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file safe_pip_compile-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for safe_pip_compile-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 2d726b8ac35d9b117d22f3a9722e5c4a69c9779b5e50aa139c9c400e0431a0aa
MD5 c20ab44fa9b2bd00d7867b1660054ed1
BLAKE2b-256 e60f05ba28dab86f823b6e2f3b13da9880ba51d4bc3d96351d475e22df2df1fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for safe_pip_compile-0.1.4-py3-none-any.whl:

Publisher: publish.yml on sai1027/safe-pip-compile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page