OS packages are fixed by refreshing the operating system layers, language packages by updating your lockfile, and compiled binaries by rebuilding with a patched toolchain. Each type has a different source and owner, so split a scan report by package type and send each group to the right team.
The map
| Package type | Example location | Comes from | Fix | Typical owner |
|---|---|---|---|---|
| OS package | System package database | Base image or install step | Rebuild with fresh pull, or update step | Platform or app team |
| Language package | A lockfile managed directory | Package manager in your build | Update version, regenerate lockfile | App team |
| Runtime binary | Under a local prefix | Base image build | Newer image tag | App team |
| Compiled app binary | Your app directory | Your compile step | Rebuild with patched toolchain | App team |
| Bundled library in a jar | Inside an application jar | Your build tool | Update dependency in build | App team |
| Vendored copy of a library | In your source tree | Copied code | Update the copy by hand | App team |
How to tell them apart in a report
Look at the path or package type column. Debian's Python policy shows how system installed modules sit in a distribution managed directory, separate from a local prefix used for modules an administrator installs, and Python's site documentation describes site-packages under the interpreter prefix. The same split exists in other ecosystems: the OS manages its own directory, and your package manager manages another.
If the report lacks a type column, check the package URL or ecosystem identifier. Standard package identifiers include the ecosystem in their prefix, which is why SBOM based scanners can separate types cleanly.
Why mixing them wastes work
An OS refresh will not touch a lockfile. A lockfile update will not touch the OS. If a single ticket covers both, the OS team marks it done after a rebuild and the app findings remain. See does patching the OS fix app dependencies.
Where each fix lands in the image
Because layers are immutable and stack in order, an OS change near the bottom forces later layers to rebuild, while a lockfile change near the top rebuilds fewer. This is one reason to order Dockerfile steps from slowest changing to fastest changing, and to fix base layers first.
A routing rule you can adopt
- Export findings with package type and path.
- Group by type.
- Open one ticket per group per service, or one per base image for OS findings.
- Track closure by group, so a half fixed service is visible.
For the OS group, grouping by base image removes duplicates across services.
Where Safeguard fits
Safeguard's SBOM and dependency scanning identifies components by ecosystem, which supports this split, and policies can apply different rules per type. Free scan: gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how components are grouped by ecosystem.
Quick check
Does a vendored library show up in a scan?
Often not, since it has no package metadata. Source scanning and code review are needed to find copies.
Can one rebuild fix every type?
A rebuild with updated inputs can, provided each input changed: fresh base, new lockfile, patched toolchain.
Sources
Last reviewed: 19 October 2026.