Export the environment to a pinned list, then audit that list. For pip packages, pip-audit scans environments and requirements files against the Python Packaging Advisory Database. For Conda, export the pip portion and audit it, and check Conda packages separately because pip-audit only covers Python packages.
What pip-audit does
The pip-audit project says it scans Python environments, requirements files and project dependency trees for packages with known vulnerabilities. By default it uses the Python Packaging Advisory Database through the PyPI JSON API. It can also query OSV. It supports output as columns, JSON, CycloneDX JSON or XML, and markdown.
Two limits from its own documentation matter for labs. It is not a static analyzer or a defense against malicious packages. And it does not flag vulnerabilities in non Python libraries that a package depends on.
Exit codes are simple: 0 means no known vulnerabilities were found, 1 means at least one was.
Steps for a pip environment
pip-audit
pip-audit -r requirements.txt
pip-audit -f cyclonedx-json -o env-sbom.json
The first line audits the active environment. The second audits a file. The third writes a CycloneDX inventory you can keep with the project.
If the file has exact versions, tell the tool not to resolve dependencies again, which makes the result match what you actually run.
Steps for a Conda environment
The conda list command can produce a record of what is installed. Its export option prints explicit, machine readable requirement strings, and the explicit option lists installed packages with their URLs and can add hashes. Keep one of those with your project.
For vulnerability matching:
- Run pip freeze inside the environment to capture pip installed packages.
- Audit that list with pip-audit.
- For Conda packages, compare names and versions against advisories, or scan the environment inside a container image with a tool that reads installed packages.
The OSV-Scanner documentation lists many lock file types but does not list Conda among them, so do not assume it reads a Conda environment file directly.
What a good routine looks like
| Frequency | Action |
|---|---|
| Every new project | Export a pinned list, commit it |
| Each term or release | Audit and update |
| Before sharing code | Audit again, then publish the pinned list |
| After a major advisory | Rerun against stored lists, no need to rebuild |
Common surprises
Editable installs of lab code can be skipped if you pass the skip editable option, so your own package may not be audited. Dependencies pulled in by notebooks at run time may not be in any file. If an install happens in a notebook cell, record it.
Reading the output
Each finding names a package, the installed version, an advisory identifier and, where available, a fixed version. Start with findings that have a fix, since those are quick to apply, and check whether the fixed version is compatible with the rest of the environment before updating. For findings with no fix, note them and consider whether the package is needed at all. A one line decision per finding is enough.
Where Safeguard fits
Safeguard can inventory dependencies from repositories and match them to known advisories, which helps when many lab projects share the same libraries. Try the free scan on one repository first.
Quick check
Does pip-audit change my environment?
Not unless you ask it to fix things. A dry run option shows what it would collect without auditing.
Is a clean result proof the environment is safe?
No. It means no known vulnerabilities were found in the packages it checked.
Sources
Last reviewed: 19 October 2026.