# Reachability Analysis with Jenkins

[Reachability Analysis](https://help.sonatype.com/en/reachability-analysis.html "Reachability Analysis") detects method signatures in the application code that contain components with potentially exploitable security vulnerabilities and are in the execution path. The policy violations occurring due to such components will be assigned the status of `Reachable` on the application report. Clicking on the policy violation gives the details of the implicated component.

This helps developers prioritize the remediation of such policy violations by replacing the vulnerable components that are reachable by executing the application.

This configuration is suitable for _Pipeline_, _Multi-branch Pipeline_, or any other build types that make use of the [Jenkins pipeline](https://www.jenkins.io/doc/book/pipeline/) (including using Jenkinsfile).

## Enabling Reachability Analysis

To enable Reachability Analysis for Java, install or update the Sonatype Jenkins plugin to version 3.23 or later on the Jenkins instance that runs your project pipelines. Using Reachability Analysis for JavaScript requires Sonatype Jenkins plugin version 3.26.2 or later. Using Reachability Analysis for .NET requires Sonatype Platform Plugin for Jenkins version 3.32 or later. In addition, .NET SDK 8.0 or later must be installed on the Jenkins agent where the build runs.

**Example Pipeline Script to Enable Reachability Analysis**

```
nexusPolicyEvaluation(
  iqScanPatterns: [
    [ scanPattern: '**/target/sonatype-clm/module.xml' ]
  ],
  reachability: [
    javaAnalysis: [
      enable: true
    ],
    // JS analysis supported from plugin v3.26.2+
    jsAnalysis: [
      enable: true
    ],
    // .NET analysis supported from plugin v3.32+
    dotNetAnalysis: [
      enable: true
    ]
  ]
)
```

**Note**

To enable Java, JavaScript, and .NET Reachability Analysis in the same evaluation step, populate the `javaAnalysis`, `jsAnalysis`, and `dotNetAnalysis` sections.

Starting with plugin version 3.26.0, when reachability is enabled, a dedicated UI displays all components with their vulnerable signatures and clearly marks the reachable ones.

## Using Java Reachability Analysis on Jenkins

**For Best Results with Reachability Analysis**

Results for Reachability Analysis depend on the strategy used to select the types of methods to scan and the selection of namespaces to narrow down the scan entry points.

**Reachability Evidence**

When Sonatype Jenkins runs a Java scan with reachability enabled, call path evidence is sent to IQ Server and displayed in the violation details view. See [Reachability Evidence](https://help.sonatype.com/en/reachability-analysis.html "Reachability Analysis") for details.

### Strategies for Enabling Reachability Analysis

1. **Minimal Configuration**  
   The example below shows using the Reachability Analysis with minimal configuration.
```
reachability: [
     javaAnalysis: [
       enable: true
     ]
]
```

2. **Selection of Namespaces**

Select the methods that should be considered as entry points (points in code where execution begins) for the analysis.

Namespaces are specified at the level of packages. All packages nested under a namespace are considered for entry point selection. If multiple namespaces are specified, all of them will be included.

Reachability Analysis will start with the namespaces specified and subsequently analyze all others in the execution path.

**Example:**  
   Consider the following project structure:
   
   ```
   src
   |---main
   |   |---java
   |   |   |---com
   |   |   |   |---example
   |   |   |   |   |---iq
   |   |   |   |   |   |---domain
   |   |   |   |   |   |   |---DomainClassOne.java
   |   |   |   |   |   |---application
   |   |   |   |   |   |---repository
   |   |   |   |   |---wrappers
   |   |   |   |   |   |---OktaLoginWrapper.java
   |   |   |   |   |---configs
   |---test
   |   |---java
   |   |   |---com
   |   |   |   |---example
   |   |   |   |   |---iq
   |   |   |   |   |   |---domain
   |   |   |   |   |   |   |---DomainClassOne.java
   |   |   |   |   |   |---application
   |   |   |   |   |   |---repository
   |   |   |   |   |---wrappers
   |   |   |   |   |   |---OktaLoginWrapper.java
   |   |   |   |   |---configs
   ```

The Reachability Analysis feature is configured as follows:
```
reachability: [
     javaAnalysis: [
       enable: true,
       entrypointStrategy: 'ACCESSIBLE_CONCRETE',
       namespaces: [
         [namespace: 'com.example.iq']
       ]
     ]
]
```

In the example above, the namespaces property specifies the namespace `'com.example.iq'`, which will be considered as the entry point for the analysis. This namespace has `domain`, `application`, and `repository` packages under its scope. Methods belonging to `DomainClassOne.java` class (under the domain package in the `'com.example.iq'` namespace) will be analyzed before other methods in the package classes. Similarly, methods belonging to classes under other applications and repository packages will be analyzed at the start of the analysis for the package.

Packages of type wrappers, with namespace `'com.example.wrappers'` and config packages with namespace `'com.example.configs'` will be omitted when an entry point for the analysis is being established. Similarly, methods belonging to the `OktaLoginWrapper` class with namespace `'com.example.wrappers.OktaLoginWrapper.java'` will be omitted when establishing an entry point.

**Notes:**
   
   - An entry point is any method signature that aligns with the selected strategy. For example, for `JAVA_MAIN` strategy, all entry point methods have `public static void main` as method signature.
   - You can use regular expressions when specifying the namespace.
     Example: For `org.foo.example`, you can use regular expressions with `'/'` at the start and end of the string as `/^org\.+.*\.example`. 
   - Specify at least one namespace (prefer your app’s root package, e.g., `org.foo.example`). For initial setup, a temporary catch-all like `/.*/` (some teams use `.+`) can unblock the pipeline, though it may be slower.
   - If namespaces are omitted, reachability attempts to derive them from Lifecycle [Proprietary Component Configuration](https://help.sonatype.com/en/proprietary-component-configuration.html "Proprietary Component Configuration") (Package/Regex). If nothing is defined there, a warning is logged, no entry-points are discovered, and the run fails with "At least one entry-point required".

3. **Using the Parameter Includes**

Multi-module projects could have several .jar files when built. Many of these .jar files are dependencies of another .jar file, which could be the one containing the main application. By specifying the path to this specific .jar when running reachability analysis, you can avoid multiple evaluations of the same .jar files, which would occur when:
   
   - .jar files are evaluated separately.
   - .jar files are evaluated when invoked by the main application.

The includes parameter specifies a target path for the artifacts to be analyzed. It limits the scope of the analysis, resulting in better precision and reducing the utilization of system resources.

**Example:**
   
   ```
   reachability: [
     javaAnalysis: [
       enable: true,
       entrypointStrategy: 'ACCESSIBLE_CONCRETE',
       includes: [
         // NOTE: 'target' here is just an example (Maven default). Adjust the pattern so it matches
         // your application binary and its dependencies (i.e. jar, war, ear files).
         [pattern: 'target/**/*.jar']
       ]
     ]
   ]
   ```

If `includes` is omitted, the target location for the analysis will be the same as specified in the `iqScanPatterns` of the `nexusPolicyEvaluation` in the Jenkins file. This may increase the scope of the target analysis, leading to reduced precision.

4. **Entrypoint Strategy**

When Reachability Analysis is enabled in Jenkins, you can choose one of the following strategies:
   
   - `JAVA_MAIN`: Selects all methods matching `public static void main(String[] args)`
   - `PUBLIC_CONCRETE`: Selects public non-abstract/synthetic methods from non-interface/annotation classes
   - `ACCESSIBLE_CONCRETE`: Selects public/protected non-abstract/synthetic methods from non-interface/annotation classes.
   - `CONCRETE`: Selects all non-abstract/synthetic methods from non-interface/annotation classes. This is the default entrypoint strategy.
   - `ALL`: Selects all methods from all non-interface/annotation classes.

You can enable the Reachability Analysis feature with the minimal configuration as below:
   
   **Example:**
   
   The example below shows how to enable the Reachability Analysis feature with the `ACCESSIBLE_CONCRETE` strategy.
   
   ```
   reachability: [
        javaAnalysis: [
          enable: true,
          entrypointStrategy: 'ACCESSIBLE_CONCRETE'
        ]
   ]
   ```

5. **Analysis Algorithm**

These are the supported algorithms for Java reachability analysis:
   
   - `CHA` (Class Hierarchy Analysis): A static call analysis that considers all methods in all possible loaded subclasses.
   - `RTA` (Rapid Type Analysis): Similar to CHA, but improves precision by analyzing only classes instantiated during program execution.
   - `RTA_PLUS`: Sonatype’s version of RTA, offering even greater precision and serving as the default algorithm.

**Note**

Sonatype recommends keeping the default (`RTA_PLUS`). Do not change this setting unless directed by Sonatype Support.

### Error Handling

By default, Jenkins will mark the pipeline as `FAILURE` if there are any error conditions in executing Reachability Analysis.

To avoid a pipeline `FAILURE`, set the `failOnError` parameter to `false` (`true` by default). If it is set to `false`, Jenkins will not change the build outcome on reachability analysis failures.

```
reachability: [
  failOnError: false,
  logLevel: 'DEBUG',
  javaAnalysis: [
    enable: true,
    entrypointStrategy: 'ACCESSIBLE_CONCRETE'
  ]
]
```

### Expected Outputs

Reachability Analysis yields different outputs for a wide range of scenarios. The outputs depend on the type of artifacts analyzed, strategies used, and fine-tuning using the performance-enhancing parameters described above.

Reachability Analysis output is logged within the IQ Policy Evaluation log and can be found at the stage where policy evaluation is called within your pipeline.

Here are descriptions to a few sample outputs:

**Sample output 1**: Policy violations labeled as Reachable

On successful execution of Reachability Analysis, the number of "Reachable" components found will be logged as:
```
2024-07-25 15:08:32 GMT-05:00  [INFO] CallflowReachableMethodsCommand - Found 2 reachable methods
```
To view the actual method signatures of reachable methods, the **logLevel** should be set to `DEBUG`. However, this may lead to a lot of logging text and make the logs unreadable.

The _Application Report_ will show the policy violations for components (belonging to the Maven ecosystem) that contain vulnerable method signatures.

**Sample output 2**: Policy violations labeled as "Not Reachable"

This occurs when Reachability Analysis does not find any "Reachable" methods. This means that there are no vulnerable components in the execution path of the analyzed application.

This scenario will appear in the log as:
```
2024-07-25 15:39:21 GMT-05:00 [INFO] CallflowReachableMethodsCommand - Found 0 reachable methods
```

**Sample output 3**: Reachability Analysis analysis skipped

This occurs when there are no vulnerable components found during the policy evaluation. Reachability Analysis is skipped.

This is logged in the pipeline log as:
```
2024-07-25 15:38:03 GMT-05:00 [INFO] Skipping callflow analysis; missing vulnerable component method data
```

**Warning**

The absence of "Reachable" methods does not guarantee safety. The analysis may not have been able to detect these methods due to misconfiguration of the feature. We recommend checking these configurations thoroughly, at the start of the analysis.

### Other Considerations While Running Reachability Analysis

- **Running in multi-module projects**

For a project that has multiple modules and produces multiple artifacts, Reachability Analysis should be configured with one of the strategies described above, for accurate results.

If a project produces two different artifacts, for example, one .jar file for a client service and one .jar file for a server, each of these .jar files should be evaluated separately. We recommend setting up a separate pipeline in Jenkins, one that produces the client .jar and one that produces the server .jar. This way you can use the includes parameter to specify the artifact you want to analyze on each pipeline.

If a multi-module project has modules that are meant to be used as a library for other projects, using `JAVA_MAIN` will not produce any "Reachable" methods. This is because none of the modules will have the methods with the signature **public static void main**. In such cases, it is best to use `ACCESSIBLE_CONCRETE` or `PUBLIC_CONCRETE` in the strategies section above.

- **Execution Times**

Reachability Analysis can be a time and memory intensive process, depending upon the size of the project that is being analyzed. The execution involves going through all entry points specified, creating a call graph, and processing the code to detect vulnerable methods in the execution path. This could be a huge overhead if your project has millions of lines of code, lots of dependencies, and entry points.

To reduce the execution times, here are some recommendations:

1. If your project has a releaseable main branch, run Reachability Analysis on the main branch instead of all the feature branches on each new commit.
2. If you have changes in the project manifest, run Reachability Analysis in the feature branches. This is a trade-off between build time and the extra analysis step due to Reachability Analysis.
3. Run Reachability Analysis at fixed times, for example, on nightly builds.
4. If you have multi-module projects, separate the projects before running Reachability Analysis.

## Using JavaScript Reachability Analysis on Jenkins

JavaScript Reachability Analysis is currently supported only by the Sonatype Platform Plugin for Jenkins integration, which also offers fine‑grained configuration for the feature.

### Minimal Configuration

To add JavaScript Reachability Analysis to an existing pipeline, add a `jsAnalysis` clause to the reachability section, enable it, and specify the project source file (Ant‑style glob patterns are supported). These source files serve as the starting point for the analysis. All paths or patterns are relative to the workspace directory. **Do not** include any files from `node_modules`; those are project dependencies, not source files. We also recommend omitting file extensions in your patterns, since the analyzer recognizes common JavaScript and TypeScript extensions.

The example below shows using the Javascript Reachability Analysis with a minimal configuration:

```
reachability: [
  jsAnalysis: [
    enable: true,
    sourceFiles: [
      [pattern: 'src/**/*']
    ]
  ]
]
```

### Optional Parameters

1. **Node.js Executable**

Reachability Analysis requires a Node.js executable (v16+) on the pipeline’s `PATH`. This could be achieved via the Jenkins NodeJS plugin, which allows multiple versions to be configured as global tools in Jenkins. If no Node executable is on the pipeline's `PATH`, an absolute path can be explicitly specified as below:

```
reachability: [
     jsAnalysis: [
       enable: true,
       node: [
         executable: '/path/to/node/exec' // absolute path expected; may include env. vars. e.g. "${env.WORKSPACE}/path/to/node"
       ],
       sourceFiles: [
         [pattern: 'src/**/*']
       ]
     ]
]
```

2. **File Exclusion**

If your project contains other JavaScript files (e.g. tests) that shouldn’t be included in Reachability Analysis, they can be excluded in the same way as `sourceFiles`, via an `excludeFiles` section:

```
reachability: [
     jsAnalysis: [
       enable: true,
       sourceFiles: [
         [pattern: 'src/**/*']
       ],
       excludeFiles: [
         [pattern: 'test/**/*']
       ]
     ]
]
```

3. **Project Directory**

By default, reachability analysis considers the workspace root where `package.json` lives as the project directory. If your source lives elsewhere, set `projectDirectory` relative to the workspace:

```
reachability: [
     jsAnalysis: [
       enable: true,
       projectDirectory: 'app/root',   // relative to the workspace directory
       sourceFiles: [
         [pattern: 'src/**/*']
       ]
     ]
]
```

## Using .NET Reachability Analysis on Jenkins

.NET Reachability Analysis is available in the Sonatype Platform Plugin for Jenkins version 3.32 and later, for both Freestyle jobs and Pipeline scripts.

### Freestyle Job Configuration

1. In your Jenkins job configuration, add the _Invoke Sonatype Policy Evaluation_ build step.
2. Configure the IQ Instance, Stage, and Application as you normally would.
3. Expand the _Reachability Analysis_ section at the bottom of the build step.
4. Under _.NET Analysis_, check the _Enable_ checkbox.
5. Configure the .NET-specific options:

| Field | Description |
| --- | --- |
| **Enable** | Check to enable .NET reachability analysis. |
| **Algorithm** | Callflow algorithm: `CHA`,`RTA`, or`RTA_PLUS`(default). |
| **Entrypoint Strategy** | Controls how entry points are identified. Options:`CONCRETE`(default),`PUBLIC_CONCRETE`,`ACCESSIBLE_CONCRETE`,`DOTNET_MAIN`,`ALL`. |
| **Namespaces** | One or more namespace prefixes or regex patterns to filter entry points. Click _Add_ to add entries. Prefix matching is the default; enclose a pattern in `/` to use regex. |
| **.NET Runtime → dotnet executable path** | Absolute path to the `dotnet` executable. If not specified, assumes `dotnet` is available on `PATH`. Requires .NET 8 SDK or runtime. |

The **Other Options** section within **Reachability Analysis** provides settings shared across all language analyses:

| Field | Description |
| --- | --- |
| **Log Level** | Controls verbosity: `INFO` (default), `DEBUG`, `TRACE`. Use `DEBUG` or `TRACE` for troubleshooting. |
| **Fail on analysis errors** | If checked, a reachability analysis failure causes the build to fail. If unchecked, the build is marked unstable instead. |

### Entrypoint Strategy

The entrypoint strategy determines which methods in the application are treated as starting points for call graph analysis.

| Strategy | Description |
| --- | --- |
| `CONCRETE` | (Default) All non-abstract, non-synthetic methods in non-interface classes. |
| `PUBLIC_CONCRETE` | Public, non-abstract, non-synthetic methods. Recommended for web applications and library projects. |
| `ACCESSIBLE_CONCRETE` | Public or protected, non-abstract, non-synthetic methods in non-interface classes. |
| `DOTNET_MAIN` | Static methods matching the standard .NET `Main` signatures (C#, VB.NET, F#). Does not match C# 9+ top-level statement entry points; use `PUBLIC_CONCRETE` with namespace filtering for those projects. |
| `ALL` | All methods in non-interface classes, including abstract methods. |

Use the **Namespaces** field to further restrict entry points to specific namespaces and improve precision.

### Pipeline Configuration

In Jenkins Pipeline scripts, configure .NET reachability via the `dotNetAnalysis` parameter of the `nexusPolicyEvaluation` step.

#### Examples

**Basic Example**

Enable .NET reachability with default settings:
```
nexusPolicyEvaluation(
    iqApplication: manualApplication('my-dotnet-app'),
    iqInstanceId: 'iq-server',
    iqStage: 'build',
    reachability: [
        dotNetAnalysis: [
            enable: true
        ]
    ]
)
```

**With Entrypoint Strategy and Namespaces**

Use `PUBLIC_CONCRETE` strategy with namespace filtering for a web application:
```
nexusPolicyEvaluation(
    iqApplication: manualApplication('my-dotnet-app'),
    iqInstanceId: 'iq-server',
    iqStage: 'build',
    reachability: [
        dotNetAnalysis: [
            enable: true,
            entrypointStrategy: 'PUBLIC_CONCRETE',
            namespaces: [[namespace: 'MyApp.Controllers'], [namespace: 'MyApp.Services']]
        ]
    ]
)
```

**With Custom dotnet Path and Algorithm**

Specify a custom dotnet executable path and algorithm:
```
nexusPolicyEvaluation(
    iqApplication: manualApplication('my-dotnet-app'),
    iqInstanceId: 'iq-server',
    iqStage: 'build',
    reachability: [
        dotNetAnalysis: [
            enable: true,
            algorithm: 'RTA_PLUS',
            entrypointStrategy: 'CONCRETE',
            dotNetConfig: [dotnetPath: '/usr/local/share/dotnet/dotnet']
        ]
    ]
)
```

**Full Example in Declarative Pipeline**
```
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'dotnet publish -c Release -o ./publish'
            }
        }
        stage('Security Scan') {
            steps {
                nexusPolicyEvaluation(
                    iqApplication: manualApplication('my-dotnet-app'),
                    iqInstanceId: 'iq-server',
                    iqStage: 'build',
                    iqScanPatterns: [[scanPattern: 'publish/**/*.dll']],
                    reachability: [
                        dotNetAnalysis: [
                            enable: true,
                            entrypointStrategy: 'PUBLIC_CONCRETE',
                            namespaces: [[namespace: 'MyApp']]
                        ],
                        logLevel: 'INFO',
                        failOnError: false
                    ]
                )
            }
        }
    }
}
```

**Note**

`iqScanPatterns` controls which files are sent for component analysis only. The reachability analyzer independently scans the entire workspace for .dll files (`**/*.dll`). To limit which assemblies are analyzed for reachability, use namespace filtering rather than scan patterns.

### Pipeline Parameter Reference

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `dotNetAnalysis.enable` | Boolean | `false` | Enable .NET reachability analysis. |
| `dotNetAnalysis.algorithm` | String | `RTA_PLUS` | Callflow algorithm: `CHA`, `RTA`, or `RTA_PLUS`. |
| `dotNetAnalysis.entrypointStrategy` | String | `CONCRETE` | Entry point strategy: `CONCRETE`, `PUBLIC_CONCRETE`, `ACCESSIBLE_CONCRETE`, `DOTNET_MAIN`, `ALL`. |
| `dotNetAnalysis.namespaces` | List | `[]` | Namespace filters, each entry as `[namespace: 'value']`. |
| `dotNetAnalysis.dotNetConfig.dotnetPath` | String | `''` | Path to the `dotnet` executable. |
| `logLevel` | String | `INFO` | Log level: `INFO`, `DEBUG`, `TRACE`. |
| `failOnError` | Boolean | `false` | Fail build on reachability errors. |
| `timeout` | String | None | Maximum time to wait for analysis before aborting (e.g. 5m, PT5M) |

**Tip**

Use the **Pipeline Syntax** generator in Jenkins (available at `/pipeline-syntax/`) to generate the `nexusPolicyEvaluation` step with .NET reachability options via a UI form.

### Differences from CLI Configuration

| Feature | CLI | Jenkins Plugin |
| --- | --- | --- |
| Enable .NET reachability | `-radn` flag | **Enable** checkbox |
| Entrypoint strategy | `-resdn` flag | **Entrypoint Strategy** dropdown |
| Namespace filtering | `-rndn` flag (multiple) | **Namespaces** repeatable field |
| dotnet path | `-rdnp` flag | **.NET Runtime → dotnet executable path** |
| Algorithm | Server-side only | **Algorithm** dropdown (per-job override) |
| Results file | `-rr` flag | Not available (results are sent directly to IQ Server) |
| Log level | `-X` / `--debug` | **Log Level** dropdown in Other Options |
| Fail on errors | Server-side config | **Fail on analysis errors** checkbox |

**Note**

In the Jenkins plugin, the algorithm can be configured per job via the Algorithm dropdown, whereas in the CLI the algorithm is always determined by the IQ Server configuration.
