Safeguard
Developer Tools•

How do you generate an SBOM for a Python project?

Python SBOM options: scan the installed environment, a Poetry or Pipenv lockfile, requirements.txt, or export from uv. What each covers and misses.

Safeguard Security Team
3 min read

Generate a Python SBOM from the most complete source you have. For most teams that is the installed virtual environment or a lockfile, not a loose requirements file. The cyclonedx-bom package reads environments, requirements, Pipenv and Poetry, and uv can export CycloneDX straight from its lockfile.

Pick the source first

SourceTool pathStrengthWeakness
Installed environmentcyclonedx-py environmentShows exactly what is installedOnly as good as that environment
Poetry manifest and lockcyclonedx-py poetryReproducible from the repoNeeds the lockfile committed
Pipenv manifest and lockcyclonedx-py pipenvSameSame
requirements.txtcyclonedx-py requirementsWorks for legacy projectsOnly as complete as the file
uv lockfileuv export with the cyclonedx1.5 formatNo extra installPreview feature, may change

The cyclonedx-bom documentation says environment mode is the main route for PDM, uv and conda environments, because it does not list their manifests or lockfiles as supported inputs.

Steps

  1. Build the environment the way production does, in a clean virtual environment.
  2. Install cyclonedx-bom with pip, pipx or uv tool install. It needs a current Python 3.
  3. Run the matching subcommand.
cyclonedx-py environment > sbom.cdx.json
  1. For uv projects, export from the lockfile.
uv export --format cyclonedx1.5 --output-file sbom.json
  1. Validate and store the file with the build.

The requirements.txt problem

A requirements file often lists only your direct packages. If it is not a full pin of the tree, the SBOM misses transitive dependencies. Pip freeze prints every installed package pinned, but it omits pip itself, and on older Python versions setuptools and wheel, unless you ask for all. If those matter in your image, include them.

What uv adds

The uv export is lockfile based and, per its documentation, marked as preview. It carries custom properties for environment markers and for workspace paths. Treat the format as subject to change and pin your uv version in CI.

One more habit pays off. Record the Python version and the platform the environment was built on, either in the file's metadata or in your release notes. Some packages install different dependencies on different platforms or Python versions, so two environments built from the same requirements can produce different SBOMs. If you ship to more than one platform, generate one file per platform and label each clearly.

Try it yourself

Click through it at your own pace, or open it full screen.

Compare direct and transitive entries. If your file only shows the direct ones, your source is too thin.

Quick check

Is requirements.txt enough for an SBOM?

Only if it pins the full tree. Otherwise scan the installed environment or a lockfile.

Does the Python tool sign the SBOM?

No. The project says signing must be done externally.

Safeguard's SBOM and dependency scanning works from manifests and lockfiles, and a free scan is available at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.