Safeguard
Developer Tools•

Why are Python dependencies missing from my SBOM, and how do I fix it?

Dependencies declared solely in setup.py may not be fully listed by GitHub's dependency graph. Commit a lock or requirements file for a complete SBOM.

Safeguard Security Team
4 min read

Python dependencies can be missing from an SBOM when they are declared solely inside a setup.py file, because static tools cannot always evaluate that code. GitHub's documentation warns about this. The fix is to commit a requirements file or a lock file with resolved versions, or generate the SBOM from an installed environment.

Why setup.py is hard to read

A setup.py file is a program. Dependency lists in it can be built from variables, conditions or function calls. A tool that merely reads the file text cannot always work out what the final list would be. GitHub's documentation on supported ecosystems says that if you list your Python dependencies within a setup.py file, it may not be able to parse and list every dependency in your project.

It lists several Python formats that it reads more reliably, including requirements.txt, pipfile and pipfile.lock, and poetry.lock with pyproject.toml.

Which file gives the most complete inventory

FileWhat it recordsReliability for an SBOM
setup.py with install_requiresVersion ranges, sometimes computedLow to medium
requirements.txt with loose rangesRangesMedium
requirements.txt with pinned versionsExact versions for direct packagesGood
Lock file such as poetry.lock or pipfile.lockExact versions including transitive packagesStrongest
Installed environmentWhat is actually presentStrongest for a built artifact

Steps to fix it

  1. Decide how your project is installed in production: from a lock file, a requirements file or a built container.
  2. Generate a lock file with your package manager and commit it. For pip based projects, a compiled requirements file with pinned versions and hashes serves a similar role.
  3. Check the dependency graph or your SBOM tool again and compare the package count to the installed environment.
  4. Install the project in a clean virtual environment and list installed packages. Differences point to missing entries.
  5. If you ship a container, scan the image too, since that includes system packages that no Python file lists.
  6. Regenerate the SBOM in CI on every release so it stays in step.

Libraries versus applications

A library published for others usually leaves ranges open on purpose, so its users can resolve versions. An application should pin. If your repository holds both, keep a pinned file for the deployed application and say clearly in the data room which one the SBOM describes.

How to check for gaps quickly

Count the lines in your pinned requirements file and compare with the component count in the SBOM. They should be close for direct packages. Spot check three transitive packages, such as a library that your framework pulls in, and confirm they appear.

What to tell the reader

"The SBOM for the analytics service was generated on 19 October from a clean install of the lock file. It lists 142 Python packages. Build time tools are excluded." Replace the numbers with your own. State exclusions so nobody thinks the file is claiming more.

Try it yourself

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

Look for how transitive packages appear beside direct ones, the part a loosely declared setup.py hides.

Safeguard generates SBOMs and scans dependencies for Python and other ecosystems. A free scan shows what one repository produces.

Quick check

Is pip freeze good enough?

It records what is installed in one environment, which is useful, but make sure it was run in a clean environment that matches production.

Do I need to rewrite setup.py?

No. Keep it for packaging and add a lock or pinned file for deployment.

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.