A source scan covers the libraries you declared, but not necessarily what ended up in the frozen executable. The bundle also contains the Python interpreter and any modules the build tool discovered. To cover it, keep the build time dependency list and record the interpreter version alongside it.
What freezing does
The PyInstaller documentation explains that it bundles an application and its dependencies so users do not need to install any particular Python version or modules. It finds all the import statements in your script, locates the imported modules and looks in them for imports, building the list of what the program needs. It notes that the Python interpreter that executes PyInstaller is part of the bundle, and that output is specific to the operating system and Python version used.
So the distributed file includes a particular interpreter and a particular set of libraries, fixed at build time.
What a scan of the repository misses
| Item | In your repository scan | In the shipped executable |
|---|---|---|
| Declared libraries | Yes, if in lockfile | Yes |
| Libraries pulled in by discovery of imports | Maybe | Yes |
| The interpreter | Not usually | Yes |
| Native libraries bundled by those modules | No | Yes |
Because the bundle is built from imports found by analysis, it can include something your lockfile did not name directly. And because users cannot update the interpreter themselves, a flaw in it stays until you ship a new build.
How to get an accurate inventory
- Build from a locked environment, so the library set is known and recorded.
- Save the lockfile and the exact Python version with every release artifact.
- Generate an SBOM at build time from that environment and attach it to the release.
- Look at what the build tool reports as included, which most freezing tools can list, and compare with your lockfile.
- Treat the interpreter as a component with its own support lifecycle. See does a dependency scanner check Node, Python or the JDK.
The update problem
A normal service gets patched when you redeploy. A frozen desktop or command line tool lives on user machines. After an advisory, you must rebuild and redistribute. Plan for that: keep reproducible build scripts, and have an update channel if the tool is long lived.
Ask the right question
When an advisory lands, do not ask whether the repository uses the library. Ask whether any shipped build contains it, and which versions. The saved SBOM per release answers that quickly.
Safeguard offers SBOM and dependency scanning and a free scan at gold.safeguard.sh/scan. Keep one SBOM per shipped build, whatever tool makes it.
Quick check
Does freezing remove dependency risk?
No. It fixes the versions at build time, so risk remains until you rebuild.
Can I scan the executable directly?
Some tools can identify contents, with varying accuracy. A build time SBOM is more reliable.
Sources
Last reviewed: 19 October 2026.