Safeguard
Application Security•

In what order should you set up reachability analysis in CI/CD?

Start with a plain dependency scan, run reachability in report-only mode, then gate only on reachable and actively exploited findings. A six step order.

Safeguard Security Team
4 min read

Set up reachability in CI/CD in this order: get clean lockfile-based scanning first, add reachability in report-only mode, compare verdicts with what your team knows, then gate builds only on reachable findings that are also exploited in the wild. Add runtime evidence last.

What is reachability analysis, briefly?

Reachability asks whether your code can actually reach the vulnerable code in a dependency. Safeguard's docs describe three methods: static analysis builds a call graph from source, lockfile and bytecode; dynamic analysis uses a runtime collector to record which functions production workloads load and call; configuration analysis reads framework configuration to see whether code is wired in at all.

The verdicts are reachable, conditionally reachable, unreachable and unknown. Unknown is marked conservatively as potentially reachable.

Why does order matter?

If you start by blocking builds on reachability verdicts, the first noisy week costs you the team's trust. If you start with clean inputs and a quiet reporting phase, you earn the right to enforce.

The order

Step 1: a baseline scan with no gate. Run a dependency scan in CI that reads lockfiles. With the Safeguard CLI the docs give safeguard scan --dir . --output out/ after installing it with the checksum-verifying installer. Record results, change nothing yet. This shows how many findings you have and whether the scanner reads your ecosystems correctly. The docs list GA static and dynamic support for Java, Kotlin, Scala, Python, JavaScript, TypeScript, Go, Rust, C, C++ and C#, with Ruby and PHP static support in preview and Swift and Objective-C in preview. Check your languages against that list.

Step 2: reachability, report only. Turn on reachability and publish verdicts next to findings without failing builds. Let it run for a couple of weeks.

Step 3: compare with human knowledge. Pick twenty findings marked unreachable and have an engineer who knows the code confirm them. Pick twenty marked reachable and confirm those too. Write down disagreements. This is how you learn the tool's blind spots for your codebase.

Step 4: handle unknowns on purpose. Unknown comes from reflection, eval and unsafe dynamic dispatch. Decide the rule: unknowns stay on the list and get reviewed by an owner. Do not suppress them in bulk. The docs say Safeguard does not suppress those findings.

Step 5: a narrow gate. The docs describe a guardrail policy that blocks reachable vulnerabilities listed in CISA's Known Exploited Vulnerabilities catalog in production. Start there: reachable and known-exploited is a small set that nobody can dispute. Widen later to reachable and high severity.

Step 6: runtime evidence. If you run production workloads, add the runtime collector so verdicts reflect what actually executes. The docs flag vulnerable paths that never run as cold.

What are the honest limits?

Per Safeguard's docs, data-driven vulnerabilities can be exploitable even when static analysis finds them unreachable, and paths that depend on configuration the analyzer cannot enumerate may be missed. The docs recommend leaning on KEV, EPSS and runtime observation in those cases. So keep exploit data alongside reachability and never treat unreachable as safe forever. A refactor can create a path.

The docs also note that the /v1 REST endpoints are not yet available and that there is no CLI command yet for querying findings by priority. Plan your gate around what the CLI outputs today; the docs show a jq check against the scan's vuln.json file for critical severity as an example, and say the steps are plain shell so they port to GitLab CI, Jenkins and others.

Open the full demo at /demos/ci-cd-actions.

What to do

  1. Run the baseline scan in CI with no gate, and save the output.
  2. Check that your languages are supported at the level you need.
  3. Enable reachability in report-only mode for two weeks.
  4. Verify forty verdicts by hand and record misses.
  5. Write the rule for unknown verdicts.
  6. Gate only on reachable plus known-exploited findings first.
  7. Add runtime evidence for production services.

Quick check

Should unreachable findings be closed automatically?

Not forever. Lower their priority, and review when code changes or when exploit data rises, since a new call path can make them reachable.

Why not gate on all high severity findings from day one?

It blocks builds on findings the team cannot act on, which burns trust. A narrow gate on reachable, exploited findings is easier to defend and still stops the worst cases.

Sources

Last reviewed: 18 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.