To test transitive depth in a scanner proof of concept, pick one direct dependency with a deep tree, list the full tree with your package manager, and check that the scanner reports packages at every level, with a path back to the direct dependency. Missing deep packages mean missing vulnerabilities.
What transitive means
A direct dependency is one you declare. A transitive dependency is one your dependency needs, or one that dependency needs in turn. Maven's documentation puts it plainly: it avoids the need to discover and specify the libraries your dependencies require by including transitive dependencies automatically, by reading the project files of your dependencies.
Most of what runs in a modern app arrived this way. If a scanner stops at level one, it sees only the part you chose on purpose.
The depth test
- Choose a direct dependency known to pull in many others, such as a web framework.
- Ask your package manager for the full tree. Examples: npm ls --all, mvn dependency:tree, a dry run resolver report for pip, or the equivalent for your stack.
- Record the deepest chain and the total package count under that one dependency.
- Run the scanner and export its inventory for the same repo.
- Count how many of those packages the scanner lists, and at what depth.
Aim for a table like this.
| Level | In your tree | In scanner output | Gap |
|---|---|---|---|
| Direct | Count | Count | Should be zero |
| Level 2 | Count | Count | Should be zero |
| Level 3 and deeper | Count | Count | Explain every gap |
Why gaps happen
- The scanner reads only the manifest, not a resolved tree.
- It resolves versions with its own rules, which differ from your build's rules.
- Optional or platform specific packages are skipped. Your tree may include them on some operating systems and not others.
- Shaded or bundled libraries inside a jar never appear in the package manager's tree at all.
Each is a legitimate finding. Write down which one applies, because it changes how you read the scanner's "no vulnerabilities" result.
The path matters as much as the package
A finding for a package four levels down is only actionable if you can see which direct dependency brought it in. That is how you decide what to upgrade. In the PoC, pick three deep findings and ask a developer: from the scanner output alone, can you tell what to change? If the answer is no, the output is incomplete even if the detection is right.
Duplicates and multiple versions
The same package can appear at several versions in one tree. Check that the scanner reports each version separately and does not collapse them. A vulnerable copy hiding behind a patched copy is a classic miss.
What good looks like
A pass is: every package in your resolved tree appears in the inventory, with the right version, a depth or path, and a link to the direct parent. A partial pass is acceptable if each gap has a clear reason you can live with, such as platform specific optional packages you do not ship.
Try it yourself
Open the demo and expand the dependency list to see how deeper packages are tied back to the dependency that brought them in.
Click through it at your own pace, or open it full screen.
Quick check
Does depth matter if the vulnerable function is not called?
Presence and use are different questions. Test depth first for completeness, then use reachability analysis to judge which deep findings matter.
How deep is deep enough to test?
Use your own deepest chain. If your tree goes seven levels, test seven.
Sources
Safeguard offers SBOM and dependency scanning with reachability analysis, and you can try a free scan at gold.safeguard.sh/scan before you plan a longer test. The CLI, desktop app and IDE extensions are listed on safeguard.sh/download.
Last reviewed: 19 October 2026.