Reachability analysis works on AI agent code for the paths it can trace, such as direct calls into a vulnerable library function. It is weaker where behavior is decided at runtime, such as which tool an agent chooses. Treat a "not reachable" verdict on agent code as a claim to test.
What reachability does
Reachability analysis asks whether your application can actually call the vulnerable part of a dependency. If a library has a flaw in one function and your code never calls it, the finding matters less. This is how teams cut noise from long lists of advisories.
It works best on conventional call graphs: function A calls function B calls the vulnerable function. Tools build that graph from source and decide whether a path exists.
Where agent code differs
Agents add choices made at runtime. A model decides which tool to call and with what arguments. That decision is not in the source as a fixed call. Three patterns make static graphs less certain.
- Dynamic tool dispatch. Code looks up a tool by name from a registry. The graph cannot know which names will occur.
- Plugin and skill loading. Components load at startup from configuration, not from imports.
- Reflection and evaluation of generated code. If the agent runs code it wrote, there is no source to analyze in advance.
None of this makes reachability useless. It means the verdict has a confidence level that depends on how the code is built.
What to ask the vendor
| Question | Why it matters |
|---|---|
| Which languages and frameworks does reachability support? | Support varies by language |
| How do you treat dynamic dispatch? | Conservative tools mark it reachable, aggressive ones may miss it |
| Can I see the path, not just the verdict? | A path is checkable by an engineer |
| Is "unknown" a separate state from "not reachable"? | Honest tools do not collapse the two |
| Does the verdict change when the code changes? | Reachability goes stale |
The fourth row is the important one. A "not reachable" verdict that really means "could not determine" is dangerous, because someone will suppress the finding.
A safe way to use it
Use reachability to order work, not to dismiss risk. A reachable critical issue goes to the top. An unreachable one drops in priority but keeps a review date. A finding in code that loads components dynamically stays visible until a human confirms.
Apply the same rule to an exploitability view. The exploitability demo shows how context changes the priority of a finding, which is exactly the kind of context you want to preserve.
Try it yourself
Open the demo and look at how the tool shows a path from application code to a vulnerable function. Ask whether you could produce that path for one of your agent's dependencies.
Click through it at your own pace, or open it full screen.
A test you can run
Write a small agent that calls a vulnerable library function in two ways: directly, and through a tool looked up by name. Run the vendor's analysis and see which call it finds. If it finds only the first, you know where its confidence ends. Our post on how to test a reachability analysis claim describes a longer version.
Safeguard offers reachability analysis alongside SBOM and dependency scanning. Run the free scan at gold.safeguard.sh/scan on a repository that includes agent code and read the paths it reports.
Quick check
Should we suppress findings marked not reachable?
Not permanently. Lower the priority, record the reason and set a review date, because code changes can make a path reachable later.
Does reachability cover model files?
No. It reasons about code paths in libraries. Model files need inventory and provenance checks instead.
Last reviewed: 19 October 2026.