pip-audit compares an environment, requirements file, or lockfile with known-vulnerability sources. It can identify affected versions and available fixes, but it does not analyze application logic or prove that a package is safe.
Audit a project
Install the tool in isolation with pipx:
pipx install pip-audit
pip-audit .
pip-audit --locked .
The command exits nonzero when it reports vulnerabilities, making it suitable for CI. Use JSON output for machine processing.
Do not apply --fix without reviewing the change. An upgrade may fix an advisory while breaking compatibility. Reproduce installation, run tests, and confirm the remediated version reaches production. The uv and lockfile guide explains deterministic resolution.
Read each advisory, evaluate whether the vulnerable path is reachable, and prioritize actual impact. If no fix exists, record ownership, mitigation, and a review date. Keep any ignored vulnerability specific and justified.
Public databases cannot cover unknown flaws, system libraries, or malicious behavior without an advisory. Combine auditing with source review, pinned dependencies, tests, and code analysis.
The official pip-audit repository, accessed July 22, 2026, documents data sources, lockfile support, output formats, and its security model. Treat it as a continuous control, not a security certificate.
What the audit covers
Results depend on resolved versions. An open constraint such as requests>=2 does not identify the release installed in production. Audit a deployable environment or a current, reproducible lockfile. Transitive dependencies matter too: another package may introduce a vulnerable library even when application code does not import it directly.
pip-audit maps package names and versions to published advisories. A finding usually includes an identifier and known fixed versions. It tells you whether a version appears in a database, not whether execution reaches the vulnerable path. It also does not inspect first-party code, complete container images, system libraries, or external services.
Select the correct input
For a prepared virtual environment, run pip-audit and record how it was built. For requirements, select the deployment input. When supported metadata and a lockfile exist, audit the locked project to avoid resolving a graph different from the tested one.
pip-audit
pip-audit -r requirements.txt
pip-audit --locked .
Do not merge results from different environments as if they represented one release. Python version, platform, and markers can change the graph. CI should use the same major version and relevant dependency groups as production. Development tools also deserve review because they run with access to source and credentials.
Triage a finding
Start with the original advisory and maintainer fix. Confirm package, version, affected behavior, and preconditions. Identify which direct dependency introduced it and whether your use reaches the vulnerable feature. External exposure, confidentiality impact, code execution, and exploitation difficulty influence priority.
An apparently unreachable path is not a permanent exemption. Record analysis, evidence, owner, and review date. Future changes can make it reachable. When a compatible fix exists, upgrading is usually more sustainable than maintaining a long exception.
Remediate without guessing
Learn why the package is present. For a direct dependency, update its constraint and regenerate the lockfile. For a transitive dependency, seek an updated parent. Forcing a child release may violate constraints or create an unsupported combination.
Rebuild the environment from scratch, run unit and integration tests, and validate affected flows. Audit the resolved artifact again. Removing an alert from an edited input does not prove that production received the fixed release.
--fix can accelerate editing, but it does not understand functional compatibility. Use it on a reviewable branch, inspect the diff, and regenerate derived files. The uv project management guide explains a lockfile's role.
Integrate with CI
Install the tool through a controlled process and pin it according to internal policy. Run it after resolution, preserve readable output, and use its exit status so a new finding cannot disappear unnoticed.
- name: Audit Python dependencies
run: |
python -m pip install pip-audit
pip-audit -r requirements.txt
JSON output can support history and dashboards, but reports must not expose private names or sensitive architecture. Schedule audits even without commits because new advisories appear for unchanged versions.
Give exceptions an expiry
A vulnerability without a fix may need temporary mitigation. Disable the affected feature, restrict input, or isolate the component when evidence supports it. Record the exact identifier, rationale, compensating control, owner, and deadline. A broad suppression can hide future findings.
If a finding does not apply, preserve the technical analysis. Review the exception after an upgrade, architecture change, or advisory update. Without a deadline, a temporary decision becomes invisible debt.
Use complementary controls
Version auditing cannot detect a malicious package without an advisory, typo-squatting, exposed credentials, or insecure application code. Restrict sources, review new dependencies and maintainers, use hashes or lockfiles where appropriate, and protect installation credentials. Static analysis, tests, and code review cover other classes.
Inventory what reaches production and remove unused dependencies. A smaller surface reduces updates and investigations. The goal is not an empty report at any cost, but traceable decisions and fixed releases deployed to the real environment.
Checklist for each release
Confirm that the lockfile was generated with the expected tool and version, no derived files were forgotten, and the environment was rebuilt without stale packages. Compare the report with the previous release and identify new, removed, and still-exempted findings.
For each remediation, connect the change to relevant tests and record which artifact will be deployed. After deployment, verify the effective production version when the process allows it. A green pipeline that audited a different environment gives misleading assurance.
Assign ownership for advisories published outside the release cycle. Measure time to triage and remediation rather than only alert count. Avoid targets that reward suppression. A mature process explains why risk was accepted, when it will be reviewed, and how the team proved that the fixed dependency reached its destination.
Store the exact command and tool version beside the result so another engineer can reproduce it. Record the Python version, platform, input file, and dependency groups too. This context separates a database update from a genuine graph change.
When a fixed release is unavailable, monitor upstream rather than repeatedly rediscovering the same fact. Link the exception to the maintainer issue when appropriate, but do not expose internal details publicly. Recheck whether the dependency can be removed or replaced, and verify that compensating controls still match the deployed architecture.