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.3.tar.gz (25.9 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.3-py3-none-any.whl (28.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: safe_pip_compile-0.1.3.tar.gz
  • Upload date:
  • Size: 25.9 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.3.tar.gz
Algorithm Hash digest
SHA256 44709ca3e1fff966f51e28f97c0ab1f5688ab96003d269495085ac944b40e23d
MD5 48807744727997c5a1c271937b0f483d
BLAKE2b-256 a591a7476bcd90101119c29b2c9bb4d835e9086027749d04102d73bafa407021

See more details on using hashes here.

Provenance

The following attestation bundles were made for safe_pip_compile-0.1.3.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.3-py3-none-any.whl.

File metadata

File hashes

Hashes for safe_pip_compile-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1addbaab70cfb7aa3be4b51e4eaaab7d3780d6ee1d60663843eff891753d61d8
MD5 a235ac71455fa09861d1b576f30392c5
BLAKE2b-256 d98fcd3ee652acaabbd0aa0117bf48f2ec2ec065d4c94626a34212b1e8c38c31

See more details on using hashes here.

Provenance

The following attestation bundles were made for safe_pip_compile-0.1.3-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