@eurekadevsecops/radar 1.8.4 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- name: Eureka Radar
1
+ name: Radar CLI
2
2
 
3
3
  on:
4
4
  workflow_dispatch:
@@ -8,9 +8,9 @@ on:
8
8
  - main
9
9
 
10
10
  jobs:
11
- radar_scan:
11
+ scan:
12
12
  # Radar scanner repo: https://github.com/EurekaDevSecOps/radarctl
13
- name: Radar Scan
13
+ name: Scan
14
14
  runs-on: ubuntu-latest
15
15
  steps:
16
16
  - name: Checkout repo
package/README.md CHANGED
@@ -1,64 +1,331 @@
1
- <pre>
2
- _
3
- _ __ __ _ __| | __ _ _ __
4
- | '__/ _` |/ _` |/ _` | '__|
5
- | | | (_| | (_| | (_| | |
6
- |_| \__,_|\__,_|\__,_|_|
7
- </pre>
1
+ <div align="center" style="text-align:center;">
8
2
 
9
- # Introduction
3
+ <p align="center">
4
+ <img src="assets/radar.png" alt="Eureka Radar Logo" width="320"/>
5
+ </p>
10
6
 
11
- radarctl is a command-line interface for Radar, an open-source orchestrator of security scanners. Radar is part of the Eureka DevSecOps platform.
7
+ # Radar CLI
8
+ ### One command. Complete AppSec coverage.
9
+
10
+ <!-- ![Build](https://github.com/eurekadevsecops/radarctl/actions/workflows/test.yml/badge.svg) -->
11
+ ![Node](https://img.shields.io/badge/Node.js-22.x-blue?logo=node.js)
12
+ ![npm version](https://img.shields.io/npm/v/@eurekadevsecops/radar?color=2b82f6&label=NPM)
13
+ ![License](https://img.shields.io/github/license/eurekadevsecops/radarctl?color=green)
14
+
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## Overview
20
+
21
+ **Radar CLI** is a command-line tool that orchestrates multiple application security scanners — for code, dependencies, containers, and secrets — in one unified package. We've put a lot of effort into making Radar CLI easy to use for developers and easy to integrate into CI/CD pipelines. Check out our accompanying [GitHub Action for Radar CLI](https://github.com/EurekaDevSecOps/scan-action).
22
+
23
+ With Radar CLI, you can:
24
+ - Run **SAST**, **SCA**, **container**, and **secret scanning** locally or in CI/CD pipelines.
25
+ - Generate **unified SARIF reports** compatible with industry-standard security and vulnerability analysis tools.
26
+ - Optionally upload results to **Eureka ASPM** for centralized tracking, deduplication, and prioritization.
27
+
28
+ ---
29
+
30
+ Telemetry is **off by default** — nothing is uploaded unless you explicitly enable it.
31
+
32
+ ---
12
33
 
13
34
  ## Requirements
14
35
 
15
- - Node.js version 22.17.0 or higher
16
- - Docker
36
+ - **Node.js** 22.17.0 or higher
37
+ - **Docker** (for containerized scanners)
38
+
39
+ ---
17
40
 
18
41
  ## Installation
19
42
 
20
- Install the Radar CLI on the command-line using [NPM](https://npmjs.com):
43
+ Install globally using **npm**:
21
44
 
22
45
  ```bash
23
46
  npm i -g @eurekadevsecops/radar
47
+ ````
48
+
49
+ Verify the installation:
50
+
51
+ ```bash
52
+ radar --version
24
53
  ```
25
54
 
55
+ ---
56
+
26
57
  ## Getting Started
27
58
 
28
- Run the Radar CLI:
59
+ Run the CLI to view available commands:
29
60
 
30
61
  ```bash
31
62
  radar
32
63
  ```
33
64
 
34
- You will get a list of available commands:
35
- ```bash
36
- COMMANDS
37
- help display help
38
- scan scan for vulnerabilities
39
- scanners display available scanners
65
+ Example output:
66
+
67
+ ```
68
+ COMMANDS
69
+ help display help
70
+ scan scan for vulnerabilities
71
+ scanners display available scanners
40
72
  ```
41
73
 
42
- View help page for each command by using `help` on the command-line:
74
+ You can view help for any command:
43
75
 
44
76
  ```bash
45
- radar help
77
+ radar help scan
46
78
  ```
47
79
 
80
+ ---
81
+
48
82
  ## Running a Scan
49
83
 
50
- Run a scan on the source code in the current working directory:
84
+ To scan the current working directory:
51
85
 
52
86
  ```bash
53
87
  radar scan
54
88
  ```
55
89
 
56
- Refer to help for the `scan` command for more information.
90
+ You can also specify scanners to use:
57
91
 
58
92
  ```bash
59
- radar help scan
93
+ radar scan -s opengrep,gitleaks,grype
94
+ ```
95
+
96
+ Output a SARIF report:
97
+
98
+ ```bash
99
+ radar scan -s opengrep,gitleaks,grype -o report.sarif
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Supported Scanners
105
+
106
+ All scanners in Radar are fully containerized for consistency and isolation. When you run a scan, Radar CLI automatically launches the corresponding scanner inside a Docker container. This ensures clean, reproducible results without needing to install each scanner locally. A working Docker Engine is required to run Radar scanners, and the container images for all supported scanners are publicly available on the GitHub Container Registry.
107
+
108
+ | By Scanner | Categories | Description |
109
+ | --------------------------------------------------------------------------------- | ---------------------- | ----------- |
110
+ | [Dep-Scan](https://github.com/owasp-dep-scan/dep-scan) | **SCA** | OWASP dep-scan is a next-generation security and risk audit tool based on known vulnerabilities, advisories, and license limitations for project dependencies. Scan most application code - local repos, Linux container images, Kubernetes manifests, and OS - to identify known CVEs with prioritization. |
111
+ | [Gitleaks](https://github.com/gitleaks/gitleaks) | **Secrets** | Gitleaks is a tool for detecting secrets like passwords, API keys, and tokens. |
112
+ | [Grype](https://github.com/anchore/grype) | **SCA**, **Container** | Scans the contents of a container image or filesystem to find known vulnerabilities. Find vulnerabilities for language-specific packages and major operating system packages. Supports Docker, OCI and Singularity image formats. |
113
+ | [Opengrep](https://github.com/opengrep/opengrep) | **SAST** | Opengrep is an ultra-fast static code analysis engine to find security issues in code. Opengrep supports 30+ languages. |
114
+ | [Veracode SCA](https://www.veracode.com/products/software-composition-analysis/) | **SCA** | Effectively identify open-source risks with unmatched precision, ensuring secure and compliant code. Leverages a proprietary database to accurately and promptly detect new vulnerabilities. |
115
+
116
+ Scanners grouped by category:
117
+
118
+ | By Category | Description | Scanners |
119
+ | ----------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
120
+ | **SAST** | Detects insecure code patterns | [Opengrep](https://github.com/opengrep/opengrep) |
121
+ | **Secrets** | Finds hardcoded credentials | [Gitleaks](https://github.com/gitleaks/gitleaks) |
122
+ | **SCA** | Detects vulnerable package dependencies | [Veracode SCA](https://www.veracode.com/products/software-composition-analysis/), [Grype](https://github.com/anchore/grype), [Dep-Scan](https://github.com/owasp-dep-scan/dep-scan) |
123
+ | **Container** | Scans Docker, OCI, and Singularity image formats | [Grype](https://github.com/anchore/grype) |
124
+
125
+ Veracode SCA (formerly SourceClear) scanner requires the SRCCLR_API_TOKEN environment variable. If not present or valid, scanning with Veracode SCA will not work. Read more about it in [Veracode SCA online documentation](https://docs.veracode.com/r/Veracode_SCA_Agent_Environment_Variables#srcclr_api_token).
126
+
127
+ ---
128
+
129
+ ### More on the `radar scan` command
130
+
131
+ ```bash
132
+ USAGE
133
+ radar scan [OPTIONS] [TARGET]
134
+ ```
135
+
136
+ Scans your source code and dependencies for vulnerabilities.
137
+ If no target is specified, the current working directory is scanned.
138
+
139
+ **OPTIONS**
140
+
141
+ | Option | Description |
142
+ | ------------------ | --------------------------------------------------------------------------------------------------- |
143
+ | `-c, --categories` | List of scanner categories (e.g. `sast`, `sca`, `secrets`). |
144
+ | `-s, --scanners` | Comma-separated list of scanners to run. Use `radar scanners` to list available ones. |
145
+ | `-o, --output` | Output findings into a SARIF file. |
146
+ | `-d, --debug` | Log detailed debug info to stdout. |
147
+ | `-q, --quiet` | Suppress stdout logging (except errors). |
148
+ | `-f, --format` | Output format for severity display: `security` (high/moderate/low) or `sarif` (error/warning/note). |
149
+ | `-e, --escalate` | Treat specified lower severities as high (e.g. `--escalate=moderate,low`). |
150
+ | `-l, --local` | Run a local scan (don't upload scan findings to Eureka). |
151
+
152
+ **PARAMETERS**
153
+
154
+ | Parameter | Description |
155
+ | --------- | ------------------------------------------------------- |
156
+ | `TARGET` | (Optional) Path to scan. Defaults to current directory. |
157
+
158
+ #### Category and Scanner Selection
159
+
160
+ * `--categories` lets you run all scanners in one or more categories.
161
+ Example: `--categories=sca,sast`
162
+ * `--scanners` lets you choose specific scanners by name.
163
+ Example: `--scanners=opengrep,depscan`
164
+ * Both can be combined — Radar CLI will run scanners that match *both* filters.
165
+
166
+ #### Severity Formats
167
+
168
+ | Format | Example Severities |
169
+ | ---------- | ---------------------- |
170
+ | `security` | high / moderate / low |
171
+ | `sarif` | error / warning / note |
172
+
173
+ You can also **escalate severities**:
174
+
175
+ ```bash
176
+ # Treat moderates and lows as highs
177
+ radar scan -e moderate,low
178
+ ```
179
+
180
+ Or:
181
+
182
+ ```bash
183
+ # Treat warnings and notes as errors
184
+ radar scan -f sarif -e warning,note
185
+ ```
186
+
187
+ #### Exit Codes
188
+
189
+ An exit code of `0` means the scan passed with no issues. Any other code means the scan failed — either due to new vulnerabilities found or an error during the scanning process.
190
+
191
+ | Code | Meaning |
192
+ | ------- | --------------------------------------- |
193
+ | `0` | Clean and successful scan. |
194
+ | `1` | Invalid command, arguments, or options. |
195
+ | `8–15` | New vulnerabilities found. |
196
+ | `>=16` | Aborted due to unexpected error. |
197
+
198
+ #### Examples
199
+
200
+ Scan current directory:
201
+ ```bash
202
+ radar scan
60
203
  ```
61
204
 
62
- ## Contributing guide
205
+ Scan a specific path:
206
+ ```bash
207
+ radar scan /my/repo/dir
208
+ ```
209
+
210
+ Save findings into a SARIF file:
211
+ ```bash
212
+ radar scan -o report.sarif
213
+ ```
214
+
215
+ Run only dependency and code scanners:
216
+ ```bash
217
+ radar scan -c sca,sast
218
+ ```
219
+
220
+ Run specific scanners:
221
+ ```bash
222
+ radar scan -s depscan,opengrep
223
+ ```
224
+
225
+ Enable debug logs:
226
+ ```bash
227
+ radar scan --debug
228
+ ```
229
+
230
+ Quiet mode (errors only):
231
+ ```bash
232
+ radar scan --quiet
233
+ ```
234
+
235
+ Display findings in SARIF-style severities:
236
+ ```bash
237
+ radar scan -f sarif
238
+ ```
239
+
240
+ Treat moderates and lows as highs:
241
+ ```bash
242
+ radar scan -e moderate,low
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Example Workflows
248
+
249
+ ### Local Scan (no uploads)
250
+
251
+ Runs entirely on your machine — by default, Radar CLI doesn’t upload any findings. Your vulnerabilities stay local and private.
252
+
253
+ ```bash
254
+ radar scan -s opengrep,gitleaks,grype -o report.sarif
255
+ ```
256
+
257
+ ### Upload Findings to Eureka ASPM
258
+
259
+ See all findings in one place with deduplication, trend tracking, and risk prioritization. To upload results to **Eureka ASPM**, provide your API credentials via two environment variables: `EUREKA_AGENT_TOKEN` (your API token) and `EUREKA_PROFILE` (your profile ID). When these are set, Radar CLI automatically uploads results after each scan — letting you view your full scan history and all findings in the **Eureka ASPM Dashboard**.
260
+
261
+ ```bash
262
+ export EUREKA_AGENT_TOKEN=<your token>
263
+ export EUREKA_PROFILE=<your profile ID>
264
+
265
+ radar scan -s opengrep,gitleaks,grype
266
+ ```
267
+
268
+ NOTE: To prevent Radar CLI from uploading scan findings even when you have `EUREKA_AGENT_TOKEN` and `EUREKA_PROFILE` set, you can pass the `-l/--local` option on the command line.
269
+
270
+ ---
271
+
272
+ ## Why Upload Findings to Eureka ASPM?
273
+
274
+ **Eureka ASPM** extends Radar CLI with powerful visibility and collaboration features:
275
+
276
+ * **Single Source of Truth:** Aggregate findings from all scanners and repos in one place.
277
+ * **Less Noise, More Signal:** Automatically de-duplicate findings and prioritize risks contextually.
278
+ * **Faster Fixes:** See ownership, severity, and remediation guidance for each issue.
279
+ * **Track Progress:** View how your project’s security posture improves over time.
280
+ * **Free for Open Source:** Open source projects get full access at no cost.
281
+
282
+ **Sign up for a free account at [eurekadevsecops.com](https://eurekadevsecops.com)**
283
+
284
+ ---
285
+
286
+ ## Telemetry & Privacy
287
+
288
+ Telemetry is **off by default**.
289
+ Radar does **not** send any data externally unless you explicitly provide:
290
+
291
+ * `EUREKA_AGENT_TOKEN`
292
+ * `EUREKA_PROFILE`
293
+
294
+ When provided:
295
+
296
+ * Findings are securely uploaded to **Eureka ASPM**
297
+ * You gain **dashboards, trend analysis, and contextual prioritization**
298
+
299
+ When omitted:
300
+
301
+ * Scans remain **fully local**
302
+
303
+ ---
304
+
305
+ ## 🧰 Troubleshooting
306
+
307
+ | Issue | Cause | Solution |
308
+ | --------------------------------------------- | ----------------------------------- | --------------------------------------------------------- |
309
+ | ❌ `report.sarif` not found | Scan failed or invalid scanner list | Check scanner names and ensure Docker is running |
310
+ | ⚠️ No findings uploaded | Missing or invalid token/profile | Set `EUREKA_AGENT_TOKEN` and `EUREKA_PROFILE` |
311
+ | 🧱 `radar: command not found` | CLI not installed globally | Run `npm i -g @eurekadevsecops/radar` again |
312
+
313
+ ---
314
+
315
+ ## Contributing
316
+
317
+ Contributions are welcome!
318
+ See our [CONTRIBUTING.md](./CONTRIBUTING.md) for setup and development guidelines.
319
+
320
+ ---
321
+
322
+ ## License
323
+
324
+ Radar CLI is licensed under the terms of the **GPL v3 License** — © Eureka DevSecOps Inc.
325
+
326
+ ---
327
+
328
+ ## Support
63
329
 
64
- See [CONTRIBUTING.md](./CONTRIBUTING.md)
330
+ * Issues & feature requests: [GitHub Issues](https://github.com/eurekadevsecops/radarctl/issues)
331
+ * Security: [security@eurekadevsecops.com](mailto:security@eurekadevsecops.com)
Binary file
Binary file
@@ -0,0 +1,27 @@
1
+ # Run Radar CLI scan via Azure Pipelines
2
+
3
+ trigger:
4
+ - main
5
+
6
+ pool:
7
+ vmImage: ubuntu-latest
8
+
9
+ steps:
10
+ - task: NodeTool@0
11
+ inputs:
12
+ versionSpec: '22.x'
13
+ displayName: 'Install Node.js'
14
+
15
+ - script: npm i -g @eurekadevsecops/radar
16
+ displayName: Install Radar CLI
17
+
18
+ - script: radar && radar scanners
19
+ displayName: Verify Radar install
20
+
21
+ - script: radar scan -s gitleaks,grype,opengrep,veracode-sca
22
+ displayName: Run Radar scan
23
+ env:
24
+ EUREKA_AGENT_TOKEN: $(EUREKA_AGENT_TOKEN)
25
+ SRCCLR_API_TOKEN: $(SRCCLR_API_TOKEN)
26
+ VERACODE_API_KEY_ID: $(VERACODE_API_KEY_ID)
27
+ VERACODE_API_KEY_SECRET: $(VERACODE_API_KEY_SECRET)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eurekadevsecops/radar",
3
- "version": "1.8.4",
3
+ "version": "1.9.1",
4
4
  "description": "Radar is an open-source orchestrator of security scanners.",
5
5
  "homepage": "https://www.eurekadevsecops.com/radar",
6
6
  "keywords": [
@@ -0,0 +1,5 @@
1
+ name = "veracode-sca"
2
+ title = "Veracode SCA"
3
+ description = "Finds known vulnerabilities in dependencies. Requires SRCCLR_API_TOKEN."
4
+ categories = [ "SCA" ]
5
+ cmd = "${assets}/run.sh ${target} ${assets} ${output}"
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # Parameters:
6
+ # $1 - Path to the source code folder that should be scanned
7
+ # $2 - Path to the assets folder
8
+ # $3 - Path to the output folder where scan results should be stored
9
+ ###
10
+
11
+ # Expand relative paths
12
+ APP_DIR=$(cd $1; pwd)
13
+ CFG_DIR=$(cd $2; pwd)
14
+ OUT_DIR=$(cd $3; pwd)
15
+
16
+ docker run --rm \
17
+ -v "${APP_DIR}":/home/luser/app \
18
+ -v "${CFG_DIR}":/tmp/radar-input \
19
+ -v "${OUT_DIR}":/tmp/radar-output \
20
+ -e SRCCLR_API_TOKEN=${SRCCLR_API_TOKEN} \
21
+ ghcr.io/eurekadevsecops/radar-veracode-sca 2>&1
@@ -20,6 +20,7 @@ module.exports = {
20
20
  { name: 'DEBUG', short: 'd', long: 'debug', type: 'boolean', description: 'log detailed debug info to stdout' },
21
21
  { name: 'ESCALATE', short: 'e', long: 'escalate', type: 'string', description: 'severities to treat as high/error' },
22
22
  { name: 'FORMAT', short: 'f', long: 'format', type: 'string', description: 'severity format' },
23
+ { name: 'LOCAL', short: 'l', long: 'local', type: 'boolean', description: 'local scan (no upload of findings to Eureka)' },
23
24
  { name: 'OUTPUT', short: 'o', long: 'output', type: 'string', description: 'output SARIF file' },
24
25
  { name: 'QUIET', short: 'q', long: 'quiet', type: 'boolean', description: 'suppress stdout logging' },
25
26
  { name: 'SCANNERS', short: 's', long: 'scanners', type: 'string', description: 'list of scanners to use' }
@@ -60,6 +61,15 @@ module.exports = {
60
61
  'security' severity format. Findings can also be displayed as errors, warnings,
61
62
  and notes. This is the 'sarif' severity format.
62
63
 
64
+ Runs entirely on your machine — by default, Radar CLI doesn’t upload any findings.
65
+ Your vulnerabilities stay local and private. To upload results to Eureka ASPM,
66
+ provide your API credentials via two environment variables: 'EUREKA_AGENT_TOKEN'
67
+ (your API token) and 'EUREKA_PROFILE' (your profile ID). When these are set, Radar CLI
68
+ automatically uploads results after each scan — letting you view your full scan
69
+ history and all findings in the Eureka ASPM Dashboard. To prevent Radar CLI from
70
+ uploading scan findings even when you have 'EUREKA_AGENT_TOKEN' and 'EUREKA_PROFILE'
71
+ set, you can pass the LOCAL option on the command line.
72
+
63
73
  Exit codes:
64
74
  0 - Clean and successful scan. No errors, warnings, or notes.
65
75
  1 - Bad command, arguments, or options. Scan not completed.
@@ -76,6 +86,7 @@ module.exports = {
76
86
  examples: [
77
87
  '$ radar scan ' + '(scan current working directory)'.grey,
78
88
  '$ radar scan . ' + '(scan current working directory)'.grey,
89
+ '$ radar scan --local ' + '(run a local scan / no uploads to Eureka)'.grey,
79
90
  '$ radar scan -d' + '(turn debug mode on)'.grey,
80
91
  '$ radar scan --debug' + '(turn debug mode on)'.grey,
81
92
  '$ radar scan /my/repo/dir ' + '(scan target directory)'.grey,
@@ -144,9 +155,13 @@ module.exports = {
144
155
  if (!categories.length) throw new Error(`CATEGORIES must be one or more of '${availableCategories.join("', '")}', or 'all'`)
145
156
  if (!scanners.length) throw new Error('No available scanners selected.')
146
157
 
158
+ if (!telemetry.enabled || args.LOCAL) {
159
+ log(`INFO: Running a local scan.\n`)
160
+ }
161
+
147
162
  // Send telemetry: scan started.
148
163
  let scanID = undefined
149
- if (telemetry.enabled) {
164
+ if (telemetry.enabled && !args.LOCAL) {
150
165
  // TODO: Should pass scanID to the server; not read it from the server.
151
166
  try {
152
167
  const res = await telemetry.send(`scans/started`, {}, { scanners: scanners.map((s) => s.name) })
@@ -169,7 +184,7 @@ module.exports = {
169
184
  // Send telemetry: git metadata.
170
185
  const metadata = git.metadata(target)
171
186
  if (metadata.type === 'error') throw new Error(`${metadata.error.code}: ${metadata.error.details}`)
172
- if (telemetry.enabled && scanID) {
187
+ if (telemetry.enabled && scanID && !args.LOCAL) {
173
188
  let res = await telemetry.send(`scans/:scanID/metadata`, { scanID }, { metadata })
174
189
  if (!res.ok) log(`WARNING: Scan metadata (stage 1) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
175
190
  res = await telemetry.sendSensitive(`scans/:scanID/metadata`, { scanID }, { metadata })
@@ -186,7 +201,7 @@ module.exports = {
186
201
  catch (error) {
187
202
  log(`\n${error}`)
188
203
  if (!args.QUIET) log('Scan NOT completed!')
189
- if (telemetry.enabled) {
204
+ if (telemetry.enabled && !args.LOCAL) {
190
205
  const res = await telemetry.send(`scans/:scanID/failed`, { scanID })
191
206
  if (!res.ok) log(`WARNING: Scan status (not completed) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
192
207
  }
@@ -202,14 +217,14 @@ module.exports = {
202
217
  if (outfile) fs.writeFileSync(outfile, JSON.stringify(results.sarif, null, 2))
203
218
 
204
219
  // Send telemetry: scan results.
205
- if (telemetry.enabled && scanID) {
220
+ if (telemetry.enabled && scanID && !args.LOCAL) {
206
221
  const res = await telemetry.sendSensitive(`scans/:scanID/results`, { scanID }, { findings: results.sarif, log: results.log })
207
222
  if (!res.ok) log(`WARNING: Scan results telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
208
223
  }
209
224
 
210
225
  // Analyze scan results: group findings by severity level.
211
226
  let summary
212
- if (telemetry.enabled && scanID) {
227
+ if (telemetry.enabled && scanID && !args.LOCAL) {
213
228
  const analysis = await telemetry.receiveSensitive(`scans/:scanID/summary`, { scanID })
214
229
  if (!analysis?.findingsBySeverity) throw new Error(`Failed to retrieve analysis summary for scan '${scanID}'`)
215
230
  summary = analysis.findingsBySeverity
@@ -218,7 +233,7 @@ module.exports = {
218
233
  }
219
234
 
220
235
  // Send telemetry: scan summary.
221
- if (telemetry.enabled && scanID) {
236
+ if (telemetry.enabled && scanID && !args.LOCAL) {
222
237
  const res = await telemetry.send(`scans/:scanID/completed`, { scanID }, summary)
223
238
  if (!res.ok) log(`WARNING: Scan status (completed) telemetry upload failed: [${res.status}] ${res.statusText}: ${await res.text()}`)
224
239
  }
@@ -228,7 +243,7 @@ module.exports = {
228
243
  log()
229
244
  SARIF.visualizations.display_findings(summary, args.FORMAT, log)
230
245
  if (outfile) log(`Findings exported to ${outfile}`)
231
- SARIF.visualizations.display_totals(summary, args.FORMAT, log, telemetry.enabled && scanID)
246
+ SARIF.visualizations.display_totals(summary, args.FORMAT, log, telemetry.enabled && scanID && !args.LOCAL)
232
247
  }
233
248
 
234
249
  // Determine the correct exit code.