Safeguard
AppSec

Semgrep SCA: How Reachability Changes Dependency Scanning

What Semgrep SCA (Supply Chain) does, how its reachability analysis cuts alert noise, where it fits, and how to run it in CI.

Yukti Singhal
Platform Engineer
6 min read

Semgrep SCA, marketed as Semgrep Supply Chain, is a software composition analysis tool whose defining feature is reachability analysis: instead of listing every known vulnerability in your dependencies, it determines whether your code actually calls the vulnerable function, so you can focus on the findings that matter. Traditional SCA tools generate a flat list of every CVE in every dependency, and most of those vulnerabilities live in code paths your application never touches. Semgrep SCA's approach is built to cut that noise, and Semgrep reports it can reduce irrelevant alerts by as much as 90 percent. This guide explains how it works and how to use it.

The problem Semgrep SCA is solving

A conventional dependency scan tells you a package has a vulnerability. It does not tell you whether your application uses the vulnerable part of that package. In practice, most reported vulnerabilities sit in functions you never import or call, which means most of a typical SCA report is technically accurate and practically irrelevant.

That gap between "present" and "exploitable" is why security teams stop reading their SCA dashboards. When 400 findings arrive and 380 are unreachable, the 20 that matter get lost. Semgrep SCA attacks this directly by asking a sharper question: is the vulnerable code reachable from your code?

How reachability analysis works

Reachability analysis determines whether the vulnerable part of a dependency is actually used by your application. Semgrep writes rules that describe the specific vulnerable function or code pattern for a given CVE. During a scan, it checks whether your codebase imports and calls that pattern. If there is a matching code path, the finding is flagged reachable; if not, it is unreachable.

Semgrep classifies findings into a few states:

  • Reachable — there is a code path in your application that matches the vulnerability's definition. Prioritize these.
  • Unreachable — the vulnerable function is not used, so exploitation is unlikely in your context.
  • Conditionally reachable — the vulnerability can be exploited only when additional conditions are met, such as a specific operating system or configuration.

For high-fidelity results, Semgrep goes beyond just "is the function called" to dataflow reachability, distinguishing reachable-but-safe paths from reachable-and-exploitable ones. That extra step removes false positives that even function-level matching would report. The tradeoff is that reachability requires per-CVE rule authoring, so coverage is strongest for critical and high-severity vulnerabilities in Semgrep's generally-available languages.

Language coverage and its limits

Reachability is not free to build; each supported language needs its own analysis and rules. Semgrep writes reachability rules for all critical and high CVE severities in its GA languages, and has extended coverage over time, for example bringing its Java reachability analysis to Kotlin while adding Kotlin-specific rules.

The practical implication: check that your primary language is a GA language for reachability before assuming you get the full benefit. For languages without reachability rules, Semgrep SCA still reports vulnerabilities, but without the reachable/unreachable classification that makes it distinctive. This is a fair question to ask in any evaluation, and it is where different SCA tools genuinely diverge.

Running Semgrep SCA

Semgrep Supply Chain runs through the same semgrep CLI and platform as its SAST rules. A dependency scan reads your lockfiles to build the dependency graph and then applies reachability analysis:

# Install
python3 -m pip install semgrep

# Authenticate to the Semgrep platform (Supply Chain runs there)
semgrep login

# Run a supply chain scan
semgrep ci --supply-chain

Semgrep relies on lockfiles (package-lock.json, poetry.lock, go.sum, and so on) to resolve exact transitive versions, so committing your lockfiles is a prerequisite for accurate results. Without them, the scanner cannot pin the versions it needs to match against advisories.

Fitting it into CI and triage

The reachability signal is most useful as a gating and triage input. A sensible policy fails the build on reachable critical and high findings while surfacing unreachable ones as informational rather than blocking:

- name: Semgrep Supply Chain
  run: semgrep ci --supply-chain
  env:
    SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

Because Semgrep runs SAST and SCA through one tool, teams often adopt it for both, which reduces the number of scanners in the pipeline. That said, reachability is a prioritization aid, not a license to ignore unreachable findings forever. An unreachable vulnerability becomes reachable the moment someone imports the affected function, so unreachable findings should still be tracked and re-evaluated as the code changes.

How it compares to other SCA approaches

Reachability-based scanning is one answer to alert fatigue; it is not the only one. Some tools prioritize with exploit intelligence (is there a known exploit in the wild?), others with EPSS probability scores, and others by whether a fix is available. The strongest programs combine several signals rather than trusting one.

When evaluating Semgrep SCA against alternatives, run it on a real repository and measure how many findings it marks reachable versus the raw count, then verify a sample of the "reachable" and "unreachable" calls by hand. That check tells you whether the reachability engine is accurate for your codebase, which matters more than the marketing percentage. If you are comparing scanners broadly, our vs-Snyk comparison and SCA product page lay out the criteria worth testing.

FAQ

What is Semgrep SCA?

Semgrep SCA, branded Semgrep Supply Chain, is a software composition analysis tool that scans your open-source dependencies for known vulnerabilities and adds reachability analysis to determine whether your code actually uses the vulnerable function, so you can prioritize findings that are genuinely exploitable.

How does Semgrep's reachability analysis reduce noise?

It matches per-CVE rules describing the vulnerable code pattern against your codebase and flags each finding as reachable, unreachable, or conditionally reachable. Because most vulnerabilities sit in unused code paths, filtering to reachable findings can cut irrelevant alerts substantially, by up to around 90 percent per Semgrep.

Does Semgrep SCA support every language?

No. Reachability rules exist for Semgrep's generally-available languages and cover critical and high-severity CVEs. Other languages still get vulnerability reporting but without the reachable/unreachable classification, so confirm your primary language is supported before relying on the reachability signal.

Should I ignore unreachable vulnerabilities that Semgrep SCA reports?

Not permanently. Unreachable means the vulnerable function is not currently called, but a future code change can make it reachable. Treat unreachable findings as lower priority and informational, but keep tracking them and re-evaluate as your code and dependencies evolve.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.