close

Full Application Reachability

Full application Reachability enhances the precomputed reachability by filtering out CVEs that affect functions never called in both the application source code and the dependency code.

📘

See Reachability Analysis for an overview of all Reachability Analysis capabilities in Socket. This page is about just one of the reachability techniques that Socket offers.

The Precomputed reachability allows Socket to remove up to 60% of vulnerabilities by looking at how packages in your dependency graph call into other packages in your dependency graph.

Full application reachability uses the same underlying reachability analysis engine, but it scans both the application source code and the dependency code. This allows the full application reachability to flag around 80% of vulnerabilities as irrelevant. For some ecosystems, the noise reduction rate is above 90%.

The benefits of full application reachability analysis include:

  • Excellent noise reduction – Up to 90% of all vulnerability alerts can be flagged as irrelevant.
  • Powerful triaging support – Provides a precise list of function calls from your application source code that lead to reachable vulnerabilities, making it easier to assess impact and severity.
  • On-premise analysis – While the analysis reads your application’s source code, it runs entirely on-premise (on your machine) and does not share any source code with Socket.
  • Phantom dependency detectionphantom dependencies are automatically detected and considered in the reachability analysis.

There are a few caveats to using the full application reachability analysis. It requires a small amount of manual configuration per repository and can be compute-intensive, depending on the programming language(s) and the size of the application.

Based on your organization’s security needs, you may choose to enable full application analysis for select repositories, while using precomputed reachability analysis for others.

When to use Full Application Reachability

Full application reachability is designed to be used selectively. Most customers start with precomputed reachability across their repositories and enable full application reachability only for a small number of production-critical or high-noise services where maximum precision is required.

Because full application reachability performs deep static analysis across both application code and dependencies, it is more compute-intensive by design. This trade-off allows Socket to deliver significantly higher signal and noise reduction, but it is not required to get value from reachability analysis overall.

Running the Reachability Analysis

Full application reachability is run through the Socket CLI. It is available in both the Node CLI (the socket command) and the Python CLI (the socketcli command).

📘

Full application reachability requires an Enterprise plan (Enterprise trials qualify) and an API token.

The analysis runs on your machine and is performed by an analysis engine that needs the build toolchain for each language in your project — for example, a JDK for Java, Kotlin, and Scala, the Go toolchain for Go, or .NET for C# (see the language-specific requirements below). The engine checks for the required tools when it runs and reports any that are missing; you can skip these checks with --reach-disable-external-tool-checks.

Separately, the Python CLI (socketcli) requires npm, npx, and uv on your PATH and exits early if any are missing; the Node CLI has no such pre-check (it bundles the analysis engine).

There are also some requirements that depend on the programming language(s) used in the project scanned by the reachability analysis.

Language-specific Requirements

  • Python
    • Python 3.11 or newer. PyPy is recommended, as it can speed up the analysis 2-3x
    • uv version 0.6.8 or newer
  • Nuget (C#)
    • .NET 6 or newer
  • Go
    • Same version as used to build to project

For any project built with Gradle, sbt, or Maven, we recommend adding --dynamic-sbom-inference to your reachability scans with the Node CLI:

socket scan create --reach --dynamic-sbom-inference

--dynamic-sbom-inference has your build tool generate a Socket facts file (.socket.facts.json) as part of the scan, covering every Gradle, sbt, and Maven build under the scan target rather than only the one at the scan root. That gives you two things:

  • Per-subproject analysis — reachability for those builds is analyzed and reported per subproject rather than as a single unit. This applies to a single multi-module build as much as to a repository containing several independent builds, and on large repositories it is also considerably faster (see Project structure under Factors Affecting Performance).
  • More accurate results — the dependency graph comes from the build tool that resolves it, and it records where each dependency actually lives, so the analysis can reliably install the dependencies it needs.

Note: The flag applies to the maven ecosystem only — Socket's name for the JVM ecosystem, covering Gradle, sbt, and Maven builds alike. Your npm, PyPI, Go and other dependencies are unaffected and behave exactly as they would without the flag, both in the scan and in the reachability analysis.

For those builds, reachability then works from the generated files rather than the manifest files in your project (pom.xml, gradle.lockfile, or libs.versions.toml), so you don't need --reach-use-only-pregenerated-sboms to get that effect for them. Any per-project defaults you've configured in a socket.json file are applied to each build; for a repository with several builds, the socket manifest setup --dynamic-sbom-inference wizard configures them one build at a time.

If no Gradle, sbt, or Maven build is found anywhere under the target, the scan stops with an error rather than continuing silently — either you are not scanning the intended directory (use --cwd), or this repository has no JVM build and the flag should be dropped.

The Python CLI (socketcli) has no equivalent flag. You can still get the accurate per-build dependency graphs by pre-generating the files with the Node CLI's socket manifest dynamic-sbom-inference before running socketcli --reach; the per-subproject analysis is Node CLI only.

⚠️ Without --dynamic-sbom-inference, a dependency manifest must be generated before the reachability analysis runs for any sbt project, or any Gradle project without a gradle.lockfile or libs.versions.toml. You can pre-generate the manifests yourself by running socket manifest dynamic-sbom-inference (or socket manifest gradle / socket manifest scala for a single build) before the scan; learn how on this page. Note that libs.versions.toml has some limitations — for the most accurate reachability results, generate a Socket facts file (or, if you prefer a committed file, use a gradle.lockfile).

To create a scan with reachability information, run the CLI from your project directory (with the Node CLI on a Gradle, sbt, or Maven project, add --dynamic-sbom-inference as described above):

Node CLI

socket scan create --reach

Python CLI

export SOCKET_SECURITY_API_TOKEN=<your-token>
socketcli --reach

Both commands run the analysis locally and then submit a full scan to Socket. The Python CLI derives your organization from the API token and auto-detects the repository and branch from git; the Node CLI uses the organization configured by socket login (or --org).

During analysis, the reachability results are written to a .socket.facts.json file in the analyzed directory (your current working directory by default). The Node CLI (socket) deletes this file once the scan completes successfully; pass --reach-retain-facts-file to keep it for inspecting or debugging the reachability output.

⚠️

Warning: If you retain the .socket.facts.json file, delete it before running a fresh full application reachability scan. A stale .socket.facts.json left in the analyzed directory is picked up as a pre-generated input and silently overrides fresh analysis, so the new scan's results will not be reliable.

Command-line flags

The reachability flags used in the examples below (such as --reach-analysis-timeout, --reach-analysis-memory-limit, --reach-concurrency, and --exclude-paths) work the same way in both CLIs. A few flags are available in only one of them:

PurposeNode CLI (socket)Python CLI (socketcli)
Minimum CVE severity to report(not available)--reach-min-severity
Reachability output file(always .socket.facts.json)--reach-output-file
Per-build SBOM generation for Gradle, sbt, and Maven--dynamic-sbom-inference(not available — pre-generate with socket manifest dynamic-sbom-inference)

For the complete, up-to-date flag list, see each CLI's reference: the Node socket scan create reference and the Python CLI reference.

Resource and Performance Requirements

Full application reachability analysis is compute-intensive, with resource requirements varying by ecosystem and project size. This section provides guidance on memory allocation and expected analysis times.

Factors Affecting Performance

Several factors influence the resource requirements and duration of the reachability analysis:

Language type

Dynamically typed languages such as JavaScript, Python, and Ruby are computationally more expensive to analyze than statically typed languages such as Java and Rust. Static type information allows the analysis to more precisely determine which functions may be called, reducing the amount of code that needs to be considered.

Program size

Larger programs require more resources. Program size includes not only your application code but also the size of your dependencies. A small application with many large dependencies may take longer to analyze than a large application with few dependencies.

Number of CVEs

The number of CVEs in your dependency graph affects performance. More CVEs typically means the analysis must consider a larger fraction of the codebase to determine reachability for each vulnerability.

Project structure

Splitting applications into smaller subprojects or workspaces typically results in better performance than having everything in a single project. For example, a JavaScript project with 5 million lines of code can be very computationally intensive to analyze as a single unit. However, if those 5 million lines are split across 100 workspaces, the analysis can process each workspace independently, which is typically much faster overall.

Memory Requirements

All ecosystems require a minimum of 8 GB of memory. The recommended memory allocation depends on the ecosystem and project size:

EcosystemMinimum MemoryRecommended Memory
npm8 GB32 GB (64 GB for very large projects)
Python8 GB32 GB
Ruby8 GB32 GB
Go8 GB16 GB
Maven8 GB16 GB
NuGet8 GB16 GB
Cargo8 GB16 GB

Expected Analysis Time

The table below shows expected analysis times across different ecosystems. Times are reported as percentiles across all scanned projects.

EcosystemP50 (Median)P90P99
npm1 min10 min40 min
Python1 min3 min30 min
Ruby1 min3 min30 min
Go1 min3 min30 min
Maven1 min3 min20 min
NuGet1 min3 min20 min
Cargo1 min3 min20 min
📘

The reported times are per-project. If scanning a repository containing multiple subprojects (a monorepo), you need to multiply by the number of subprojects. Using the --reach-concurrency flag may be beneficial in this scenario.

Troubleshooting Analysis Timeouts

If the reachability analysis is running slower than expected or is timing out, consider the following options:

Increase the analysis timeout

Use --reach-analysis-timeout to extend the analysis timeout beyond the default of 10 minutes. Specify the duration as a number followed by a s, m, or h unit (for example 90s, 10m, or 1h). When increasing the timeout, it is recommended to also allocate additional memory—approximately 10 GB of extra memory per additional 10 minutes of timeout.

socket scan create --reach --reach-analysis-timeout 20m

Increase analysis memory

Use --reach-analysis-memory-limit to increase the maximum available memory to the analysis (default is 8GB). Specify the memory as a number followed by an MB or GB unit (for example 512MB or 8GB). If running in CI, remember to consider if you need to use a larger runner.

socket scan create --reach --reach-analysis-memory-limit 32GB

Enable parallel workspace processing

Use the --reach-concurrency flag to process multiple workspaces in parallel. This is useful for projects that contain multiple subprojects or workspaces, such as projects using npm workspaces or monorepos with subprojects located in different subdirectories.

socket scan create --reach --reach-concurrency 4
⚠️

The --reach-analysis-memory-limit flag applies to each concurrent instance. For example, if you allocate 16 GB of memory per instance and run 4 concurrent instances, you should run the analysis on a machine with at least 64 GB of memory.


How Full Application Function-level Reachability Works

1. Invoking the scan

The analysis is started using the Socket CLI as described above. You can set up the scan to run at regular intervals in your CI system or be triggered by other events depending on policy.

2. Scanning for CVEs

The analysis identifies all manifest files (package.json, go.mod, Gemfile, pom.xml, build.gradle, and others) in your application. From these files, a complete list of direct and transitive dependencies, along with the dependency graph that connects them, is extracted.

Socket scans for CVEs in the dependency graph using a standard vulnerability scan.

3. Computing Vulnerability Reachability

For every detected CVE, a static analysis is performed to check the reachability of the affected functions (You can learn more about Socket's static reachability analysis here).

This step involves constructing a model of your application called a call graph, which represents which functions call other functions throughout the application. Depending on the size and complexity of your codebase, this process may require significant memory and CPU resources, and can take up to a few minutes to complete for some CVEs.

4. Reachable vs Unreachable CVEs

If the affected function(s) are unreachable, the CVE is marked as unreachable. Unreachable CVEs are safe to ignore, as the vulnerable code cannot be invoked at runtime.

If the CVE is reachable through one or more paths, the vulnerability is flagged as reachable. For reachable CVEs, Socket shows the list of function calls in your dependencies that may trigger the vulnerability.

Limitations

See the Static Reachability Analysis for more information about what the static reachability analysis can and cannot detect.

FAQ

How does Socket determine which functions are affected by a CVE?

Socket records this in a reachability specification for each vulnerability. By default, only human-verified specifications are used; organizations can opt in to also use AI-generated specifications for broader coverage, at a slightly higher risk of an incorrect result. You can learn more about how the Socket team identifies functions affected by vulnerabilities in the FAQ section of the Static Reachability Analysis page.

How does Full Application Reachability compare to Precomputed Reachability

Precomputed reachability analysis considers only the code within your dependencies, whereas the full application analysis also scans your application’s own source code. While the full application analysis provides better noise reduction and richer context for triaging reachable vulnerabilities, it comes with some trade-offs: it requires manual setup and is generally slower, as the static analysis is compute-intensive.


Did this page help you?