socketsecurity 2.4.11__tar.gz → 2.4.13__tar.gz

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.
Files changed (151) hide show
  1. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/CHANGELOG.md +26 -0
  2. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/PKG-INFO +1 -1
  3. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/docs/cli-reference.md +14 -5
  4. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/docs/troubleshooting.md +1 -1
  5. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/pyproject.toml +1 -1
  6. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/__init__.py +1 -1
  7. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/__init__.py +18 -18
  8. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/tools/reachability.py +35 -9
  9. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_reachability.py +48 -0
  10. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/uv.lock +1 -1
  11. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/CODEOWNERS +0 -0
  12. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  13. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  14. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  15. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  16. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/actions/setup-docker/action.yml +0 -0
  17. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/actions/setup-hatch/action.yml +0 -0
  18. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/actions/setup-sfw/action.yml +0 -0
  19. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/dependabot.yml +0 -0
  20. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/dependency-review.yml +0 -0
  21. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/docker-stable.yml +0 -0
  22. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/e2e-test.yml +0 -0
  23. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/pr-preview.yml +0 -0
  24. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/python-tests.yml +0 -0
  25. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/release.yml +0 -0
  26. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/workflows/version-check.yml +0 -0
  27. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.github/zizmor.yml +0 -0
  28. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.gitignore +0 -0
  29. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.hooks/sync_version.py +0 -0
  30. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.pre-commit-config.yaml +0 -0
  31. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/.python-version +0 -0
  32. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/Dockerfile +0 -0
  33. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/LICENSE +0 -0
  34. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/Makefile +0 -0
  35. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/README.md +0 -0
  36. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/docs/ci-cd.md +0 -0
  37. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/docs/development.md +0 -0
  38. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-dashboard-parity.json +0 -0
  39. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-dashboard-parity.toml +0 -0
  40. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-diff-ci-cd.json +0 -0
  41. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-diff-ci-cd.toml +0 -0
  42. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-instance-detail.json +0 -0
  43. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/examples/config/sarif-instance-detail.toml +0 -0
  44. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/instructions/gitlab-commit-status/uat.md +0 -0
  45. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/pytest.ini +0 -0
  46. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/build_container.sh +0 -0
  47. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/build_container_flexible.sh +0 -0
  48. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/deploy-test-docker.sh +0 -0
  49. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/deploy-test-pypi.sh +0 -0
  50. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/docker-entrypoint.sh +0 -0
  51. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/scripts/run.sh +0 -0
  52. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/session.md +0 -0
  53. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socket.yml +0 -0
  54. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/config.py +0 -0
  55. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/alert_selection.py +0 -0
  56. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/classes.py +0 -0
  57. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/cli_client.py +0 -0
  58. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/cli_run.py +0 -0
  59. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/exceptions.py +0 -0
  60. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/git_interface.py +0 -0
  61. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/helper/__init__.py +0 -0
  62. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/helper/socket_facts_loader.py +0 -0
  63. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/lazy_file_loader.py +0 -0
  64. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/log_uploader.py +0 -0
  65. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/logging.py +0 -0
  66. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/messages.py +0 -0
  67. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/resource_utils.py +0 -0
  68. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm/__init__.py +0 -0
  69. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm/base.py +0 -0
  70. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm/client.py +0 -0
  71. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm/github.py +0 -0
  72. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm/gitlab.py +0 -0
  73. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/scm_comments.py +0 -0
  74. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/socket_config.py +0 -0
  75. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/streaming.py +0 -0
  76. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/core/utils.py +0 -0
  77. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/fossa_compat.py +0 -0
  78. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/output.py +0 -0
  79. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/__init__.py +0 -0
  80. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/base.py +0 -0
  81. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/formatters/__init__.py +0 -0
  82. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/formatters/slack.py +0 -0
  83. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/jira.py +0 -0
  84. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/manager.py +0 -0
  85. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/slack.py +0 -0
  86. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/teams.py +0 -0
  87. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/plugins/webhook.py +0 -0
  88. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/socketsecurity/socketcli.py +0 -0
  89. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/__init__.py +0 -0
  90. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/conftest.py +0 -0
  91. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/create_diff_input.json +0 -0
  92. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_diff_alerts.py +0 -0
  93. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_diff_generation.py +0 -0
  94. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_facts_compression.py +0 -0
  95. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_has_manifest_files.py +0 -0
  96. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_package_and_alerts.py +0 -0
  97. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_sdk_methods.py +0 -0
  98. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/core/test_supporting_methods.py +0 -0
  99. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/create_response.json +0 -0
  100. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/diff/stream_diff.json +0 -0
  101. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  102. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/head_scan/metadata.json +0 -0
  103. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  104. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  105. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/new_scan/metadata.json +0 -0
  106. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  107. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/repos/repo_info_error.json +0 -0
  108. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/repos/repo_info_no_head.json +0 -0
  109. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/repos/repo_info_success.json +0 -0
  110. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/data/settings/security-policy.json +0 -0
  111. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/fixtures/simple-npm/index.js +0 -0
  112. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/fixtures/simple-npm/package.json +0 -0
  113. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/fixtures/simple-pypi/requirements.txt +0 -0
  114. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/validate-gitlab.sh +0 -0
  115. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/validate-json.sh +0 -0
  116. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/validate-reachability.sh +0 -0
  117. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/validate-sarif.sh +0 -0
  118. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/e2e/validate-scan.sh +0 -0
  119. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/fixtures/fossa/README.md +0 -0
  120. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/fixtures/fossa/fossa-analyze-empty.json +0 -0
  121. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/fixtures/fossa/fossa-analyze-populated.json +0 -0
  122. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/fixtures/fossa/fossa-sbom-empty-deep.json +0 -0
  123. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/fixtures/fossa/fossa-sbom-populated.json +0 -0
  124. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/__init__.py +0 -0
  125. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_alert_selection.py +0 -0
  126. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_cli_config.py +0 -0
  127. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_cli_run.py +0 -0
  128. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_client.py +0 -0
  129. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_config.py +0 -0
  130. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_dependency_overview.py +0 -0
  131. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_disable_ignore.py +0 -0
  132. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_exclude_paths.py +0 -0
  133. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_fossa_compat.py +0 -0
  134. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_fossa_parity.py +0 -0
  135. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_full_scan_retry.py +0 -0
  136. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_gitlab_auth.py +0 -0
  137. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  138. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_gitlab_commit_status.py +0 -0
  139. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_gitlab_format.py +0 -0
  140. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_ignore_telemetry_filtering.py +0 -0
  141. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_include_dirs.py +0 -0
  142. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_log_uploader.py +0 -0
  143. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_output.py +0 -0
  144. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_slack_plugin.py +0 -0
  145. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_socketcli.py +0 -0
  146. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_streaming.py +0 -0
  147. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/tests/unit/test_tier1_finalize.py +0 -0
  148. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/workflows/bitbucket-pipelines.yml +0 -0
  149. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/workflows/buildkite.yml +0 -0
  150. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/workflows/github-actions.yml +0 -0
  151. {socketsecurity-2.4.11 → socketsecurity-2.4.13}/workflows/gitlab-ci.yml +0 -0
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.4.13
4
+
5
+ ### Changed: reachability analysis types now use full names instead of "Tier 1/2/3"
6
+
7
+ - Reachability analysis types are referred to by their full names instead of the
8
+ "Tier 1/2/3" numbering: **Full application reachability** (formerly Tier 1),
9
+ **Precomputed reachability** (formerly Tier 2), and **Dependency reachability**
10
+ (formerly Tier 3). This updates `--help` text, command output, log messages, and docs
11
+ only — wire-format values such as the `socket_tier1` scan type are unchanged for
12
+ backward compatibility. See the reachability section in `docs/cli-reference.md` for the
13
+ old→new name mapping.
14
+ - Bumped the pinned `@coana-tech/cli` version to `15.5.7`.
15
+
16
+ ## 2.4.12
17
+
18
+ ### Changed: consolidated coana launcher env vars into `SOCKET_CLI_COANA_LAUNCHER`
19
+
20
+ - The reachability launcher is now tuned via a single `SOCKET_CLI_COANA_LAUNCHER`
21
+ environment variable (mirroring the Socket Node CLI): `auto` (default when unset; try
22
+ `npx` first, fall back to `npm install` + `node` on launcher-level failures),
23
+ `npm-install` (skip `npx` entirely), or `npx` (never fall back). An unrecognized value
24
+ logs a warning and behaves as `auto`.
25
+ - The legacy `SOCKET_CLI_COANA_FORCE_NPM_INSTALL` and `SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK`
26
+ variables remain supported for back-compat when `SOCKET_CLI_COANA_LAUNCHER` is unset, but
27
+ are deprecated and no longer documented.
28
+
3
29
  ## 2.4.11
4
30
 
5
31
  ### Changed: units for `--reach-analysis-timeout` and `--reach-analysis-memory-limit`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketsecurity
3
- Version: 2.4.11
3
+ Version: 2.4.13
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Project-URL: Homepage, https://socket.dev
6
6
  Author-email: Douglas Coburn <douglas@socket.dev>
@@ -240,8 +240,8 @@ If you don't want to provide the Socket API Token every time then you can use th
240
240
  #### Reachability Analysis
241
241
  | Parameter | Required | Default | Description |
242
242
  |:---------------------------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------------------------|
243
- | `--reach` | False | False | Enable reachability analysis to identify which vulnerable functions are actually called by your code. Creates a tier-1 full-application reachability scan (`scan_type=socket_tier1`). |
244
- | `--reach-version` | False | 15.5.0 | Version of @coana-tech/cli to use. Defaults to the pinned version that ships with this CLI release, so the engine only changes when you upgrade the Socket CLI. Pass `latest` to always use the newest published version (opt-in auto-update), or an explicit version (e.g. `1.2.3`) to pin it. |
243
+ | `--reach` | False | False | Enable reachability analysis to identify which vulnerable functions are actually called by your code. Creates a full application reachability scan (`scan_type=socket_tier1`). |
244
+ | `--reach-version` | False | 15.5.7 | Version of @coana-tech/cli to use. Defaults to the pinned version that ships with this CLI release, so the engine only changes when you upgrade the Socket CLI. Pass `latest` to always use the newest published version (opt-in auto-update), or an explicit version (e.g. `1.2.3`) to pin it. |
245
245
  | `--reach-analysis-timeout` | False | 10m | Timeout for each reachability analysis run, e.g. `90s`, `10m` or `1h`. Omitted by default, so coana applies its own default (`10m`). Alias: `--reach-timeout` |
246
246
  | `--reach-analysis-memory-limit` | False | 8GB | Memory limit for each reachability analysis run, e.g. `512MB` or `8GB`. Omitted by default, so coana applies its own default (`8GB`). Alias: `--reach-memory-limit` |
247
247
  | `--reach-concurrency` | False | 1 | Control parallel analysis execution (must be >= 1). Omitted by default, so coana applies its own default. |
@@ -271,6 +271,14 @@ The Python CLI verifies the following **up front** (before invoking the analysis
271
271
 
272
272
  Separately, the analysis engine (coana) needs the **per-ecosystem build toolchain** for whatever languages your project uses — e.g. a compatible Python interpreter (3.11+, or PyPy) for Python, a JDK for Java/Kotlin/Scala, .NET 6+ for C#, the matching Go toolchain for Go, etc. These are validated by the engine **at analysis time** (the CLI does not pre-check them) and that validation can be skipped with `--reach-disable-external-tool-checks`.
273
273
 
274
+ **Reachability analysis types:**
275
+
276
+ Socket's reachability analysis comes in three forms, referred to by their full names rather than the older "Tier" numbering:
277
+
278
+ - **Full application reachability** (formerly *Tier 1*) — the full-application analysis enabled by `--reach`.
279
+ - **Precomputed reachability** (formerly *Tier 2*).
280
+ - **Dependency reachability** (formerly *Tier 3*).
281
+
274
282
  ## Config file support
275
283
 
276
284
  Use `--config <path>` to load defaults from a `.toml` or `.json` file.
@@ -317,9 +325,10 @@ For CI-specific examples and guidance, see [`ci-cd.md`](ci-cd.md).
317
325
 
318
326
  The CLI runs a pinned `@coana-tech/cli` version via `npx --yes --force` (the same flags the Socket Node CLI passes for coana); it does **not** auto-update the engine or install it globally. `--yes` skips npx's interactive install prompt so non-interactive/CI runs don't hang. If the `npx` launcher is unavailable or fails before the engine starts, the CLI falls back to `npm install`-ing the pinned version into a temp directory and running it via `node`. Pass `--reach-version latest` to opt into the newest published version. Use `--reach` to enable reachability analysis during a full scan, or add `--only-facts-file` (with `--reach`) to submit only the reachability facts file (`.socket.facts.json`) when creating the full scan.
319
327
 
320
- The launcher fallback can be tuned via environment variables:
321
- - `SOCKET_CLI_COANA_FORCE_NPM_INSTALL` — skip `npx` entirely and always use the `npm install` + `node` path (useful where `npx` is known-broken).
322
- - `SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK` — never fall back; surface the `npx` failure directly.
328
+ The launcher can be tuned via the `SOCKET_CLI_COANA_LAUNCHER` environment variable:
329
+ - `auto` (default when unset) try `npx` first; fall back to `npm install` + `node` if the launcher fails before the engine starts.
330
+ - `npm-install` — skip `npx` entirely and always use the `npm install` + `node` path (useful where `npx` is known-broken).
331
+ - `npx` — never fall back; surface the `npx` failure directly.
323
332
 
324
333
  #### Advanced Configuration
325
334
  | Parameter | Required | Default | Description |
@@ -22,7 +22,7 @@ Common reasons:
22
22
  - Policy vs dataset:
23
23
  - `--strict-blocking` only affects diff-scope behavior and does not make diff output equivalent to full dashboard data.
24
24
  - Reachability data availability:
25
- - If reachability analysis partially fails and falls back to precomputed tiers, counts can shift.
25
+ - If reachability analysis partially fails and falls back to precomputed reachability, counts can shift.
26
26
 
27
27
  Recommended comparison path:
28
28
 
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.4.11"
9
+ version = "2.4.13"
10
10
  requires-python = ">= 3.11"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -1,3 +1,3 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.4.11'
2
+ __version__ = '2.4.13'
3
3
  USER_AGENT = f'SocketPythonCLI/{__version__}'
@@ -58,7 +58,7 @@ _HUMANIZE_BOUNDARY = re.compile(r"(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z]
58
58
  # whose basename is exactly ``.socket.facts.json.br`` and stores it as plain
59
59
  # ``.socket.facts.json``. Compressing the facts file on upload keeps it well under the
60
60
  # server's per-file size cap (a ~262 MB facts file compresses to roughly 15-30 MB),
61
- # which is required for large reachability (tier 1) scans to succeed.
61
+ # which is required for large full application reachability scans to succeed.
62
62
  #
63
63
  # The server matches the *exact* name ``.socket.facts.json.br``, so we only compress
64
64
  # files whose basename is exactly ``.socket.facts.json`` (a custom ``--reach-output-file``
@@ -72,8 +72,8 @@ SOCKET_FACTS_BROTLI_LGWIN = 24
72
72
  # Stream the facts file in 1 MiB chunks so large files aren't held fully in memory.
73
73
  SOCKET_FACTS_BROTLI_CHUNK_SIZE = 1024 * 1024
74
74
 
75
- # Tier 1 reachability finalize retry policy. The finalize call links the tier1 scan to the
76
- # full scan and can fail transiently (network/API blips); a few backoff retries make it robust.
75
+ # Full application reachability finalize retry policy. The finalize call links the reachability
76
+ # scan to the full scan and can fail transiently (network/API blips); a few backoff retries make it robust.
77
77
  TIER1_FINALIZE_MAX_ATTEMPTS = 3
78
78
  TIER1_FINALIZE_BACKOFF_SECONDS = 1.0
79
79
 
@@ -612,21 +612,21 @@ class Core:
612
612
 
613
613
  def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool:
614
614
  """
615
- Finalize a tier 1 reachability scan by associating it with a full scan.
615
+ Finalize a full application reachability scan by associating it with a full scan.
616
616
 
617
617
  This function reads the tier1ReachabilityScanId from the facts file and
618
618
  calls the SDK to link it with the specified full scan.
619
619
 
620
- Linking the tier 1 scan to the full scan helps the Socket team debug potential issues.
620
+ Linking the reachability scan to the full scan helps the Socket team debug potential issues.
621
621
 
622
622
  Args:
623
- full_scan_id: The ID of the full scan to associate with the tier 1 scan
623
+ full_scan_id: The ID of the full scan to associate with the reachability scan
624
624
  facts_file_path: Path to the .socket.facts.json file containing the tier1ReachabilityScanId
625
625
 
626
626
  Returns:
627
627
  True if successful, False otherwise
628
628
  """
629
- log.debug(f"Finalizing tier 1 scan for full scan {full_scan_id}")
629
+ log.debug(f"Finalizing full application reachability scan for full scan {full_scan_id}")
630
630
 
631
631
  # Read the tier1ReachabilityScanId from the facts file
632
632
  try:
@@ -649,7 +649,7 @@ class Core:
649
649
  log.debug(f"Failed to read tier1ReachabilityScanId from {facts_file_path}: {e}")
650
650
  return False
651
651
 
652
- # Call the SDK to finalize the tier 1 scan, retrying transient failures with backoff.
652
+ # Call the SDK to finalize the full application reachability scan, retrying transient failures with backoff.
653
653
  last_error: Optional[Exception] = None
654
654
  for attempt in range(1, TIER1_FINALIZE_MAX_ATTEMPTS + 1):
655
655
  try:
@@ -659,7 +659,7 @@ class Core:
659
659
  )
660
660
 
661
661
  if success:
662
- log.debug(f"Successfully finalized tier 1 scan {tier1_scan_id} for full scan {full_scan_id}")
662
+ log.debug(f"Successfully finalized full application reachability scan {tier1_scan_id} for full scan {full_scan_id}")
663
663
  return True
664
664
 
665
665
  log.debug(
@@ -669,7 +669,7 @@ class Core:
669
669
  except Exception as e:
670
670
  last_error = e
671
671
  log.debug(
672
- f"Unable to finalize tier 1 scan (attempt {attempt}/{TIER1_FINALIZE_MAX_ATTEMPTS}): {e}"
672
+ f"Unable to finalize full application reachability scan (attempt {attempt}/{TIER1_FINALIZE_MAX_ATTEMPTS}): {e}"
673
673
  )
674
674
 
675
675
  if attempt < TIER1_FINALIZE_MAX_ATTEMPTS:
@@ -677,12 +677,12 @@ class Core:
677
677
 
678
678
  if last_error is not None:
679
679
  log.debug(
680
- f"Giving up finalizing tier 1 scan {tier1_scan_id} after "
680
+ f"Giving up finalizing full application reachability scan {tier1_scan_id} after "
681
681
  f"{TIER1_FINALIZE_MAX_ATTEMPTS} attempts: {last_error}"
682
682
  )
683
683
  else:
684
684
  log.debug(
685
- f"Giving up finalizing tier 1 scan {tier1_scan_id} after "
685
+ f"Giving up finalizing full application reachability scan {tier1_scan_id} after "
686
686
  f"{TIER1_FINALIZE_MAX_ATTEMPTS} attempts"
687
687
  )
688
688
  return False
@@ -846,21 +846,21 @@ class Core:
846
846
  total_time = create_full_end - create_full_start
847
847
  log.debug(f"New Full Scan created in {total_time:.2f} seconds")
848
848
 
849
- # Finalize tier1 scan if reachability analysis was enabled
849
+ # Finalize full application reachability scan if reachability analysis was enabled
850
850
  if self.cli_config and self.cli_config.reach:
851
851
  facts_file_path = os.path.join(
852
- self.cli_config.target_path or ".",
852
+ self.cli_config.target_path or ".",
853
853
  self.cli_config.reach_output_file
854
854
  )
855
- log.debug(f"Reachability analysis enabled, finalizing tier1 scan for full scan {full_scan.id}")
855
+ log.debug(f"Reachability analysis enabled, finalizing full application reachability scan for full scan {full_scan.id}")
856
856
  try:
857
857
  success = self.finalize_tier1_scan(full_scan.id, facts_file_path)
858
858
  if success:
859
- log.debug(f"Successfully finalized tier1 scan for full scan {full_scan.id}")
859
+ log.debug(f"Successfully finalized full application reachability scan for full scan {full_scan.id}")
860
860
  else:
861
- log.debug(f"Failed to finalize tier1 scan for full scan {full_scan.id}")
861
+ log.debug(f"Failed to finalize full application reachability scan for full scan {full_scan.id}")
862
862
  except Exception as e:
863
- log.warning(f"Error finalizing tier1 scan for full scan {full_scan.id}: {e}")
863
+ log.warning(f"Error finalizing full application reachability scan for full scan {full_scan.id}: {e}")
864
864
 
865
865
  return full_scan
866
866
 
@@ -18,7 +18,7 @@ log = logging.getLogger(__name__)
18
18
  # Pinned @coana-tech/cli version. Bumped deliberately per Python CLI release so the
19
19
  # reachability engine version only changes through a standard pip upgrade (advance notice).
20
20
  # Pass --reach-version latest to opt into the newest published version instead.
21
- DEFAULT_COANA_CLI_VERSION: Final = "15.5.0"
21
+ DEFAULT_COANA_CLI_VERSION: Final = "15.5.7"
22
22
 
23
23
  # Resolved @coana-tech/cli script paths from the npm-install fallback, keyed by version.
24
24
  # Lives for the process lifetime so repeated fallback invocations install only once
@@ -55,7 +55,7 @@ class ReachabilityAnalyzer:
55
55
 
56
56
  def _resolve_coana_package_spec(self, version: Optional[str] = None) -> str:
57
57
  """
58
- Resolve the @coana-tech/cli package spec to run (e.g. '@coana-tech/cli@15.5.0').
58
+ Resolve the @coana-tech/cli package spec to run (e.g. '@coana-tech/cli@15.5.7').
59
59
 
60
60
  Args:
61
61
  version: Coana CLI version to use.
@@ -64,7 +64,7 @@ class ReachabilityAnalyzer:
64
64
  - '<semver>': that exact version.
65
65
 
66
66
  Returns:
67
- str: The package specifier to use with npx (e.g. '@coana-tech/cli@15.5.0').
67
+ str: The package specifier to use with npx (e.g. '@coana-tech/cli@15.5.7').
68
68
  """
69
69
  return f"@coana-tech/cli@{self._resolve_coana_version(version)}"
70
70
 
@@ -304,6 +304,31 @@ class ReachabilityAnalyzer:
304
304
  """
305
305
  return returncode < 0 or returncode >= 128
306
306
 
307
+ @staticmethod
308
+ def _resolve_coana_launcher_mode() -> str:
309
+ """Resolve the coana launcher mode: ``auto``, ``npx``, or ``npm-install``.
310
+
311
+ ``SOCKET_CLI_COANA_LAUNCHER`` wins when set to a recognized value; an unrecognized
312
+ value warns and behaves as ``auto``. Only when it is unset/empty do the legacy vars
313
+ apply: ``SOCKET_CLI_COANA_FORCE_NPM_INSTALL`` -> ``npm-install``, else
314
+ ``SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK`` -> ``npx``. Mirrors the Node CLI.
315
+ """
316
+ raw = os.environ.get("SOCKET_CLI_COANA_LAUNCHER", "")
317
+ mode = raw.strip().lower()
318
+ if mode in ("auto", "npx", "npm-install"):
319
+ return mode
320
+ if mode:
321
+ log.warning(
322
+ f'Ignoring unrecognized SOCKET_CLI_COANA_LAUNCHER value "{raw}"; '
323
+ 'expected "auto", "npm-install", or "npx".'
324
+ )
325
+ return "auto"
326
+ if os.environ.get("SOCKET_CLI_COANA_FORCE_NPM_INSTALL"):
327
+ return "npm-install"
328
+ if os.environ.get("SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK"):
329
+ return "npx"
330
+ return "auto"
331
+
307
332
  def _spawn_coana(
308
333
  self,
309
334
  coana_args: List[str],
@@ -324,14 +349,15 @@ class ReachabilityAnalyzer:
324
349
 
325
350
  Fallback path: if npx is missing, or its launcher dies before coana starts, install
326
351
  @coana-tech/cli into a temp dir via ``npm install`` and run it directly via ``node``.
327
- Toggle with ``SOCKET_CLI_COANA_FORCE_NPM_INSTALL`` (use the fallback as the primary
328
- path) and ``SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK`` (never fall back).
352
+ Tune with ``SOCKET_CLI_COANA_LAUNCHER``: ``auto`` (default; npx with the npm-install
353
+ fallback), ``npm-install`` (skip npx, always use the fallback path), or ``npx``
354
+ (never fall back).
329
355
  """
330
356
  effective_version = self._resolve_coana_version(version)
331
357
  coana_env = self._sanitize_coana_env(env)
332
- disable_fallback = bool(os.environ.get("SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK"))
358
+ launcher_mode = self._resolve_coana_launcher_mode()
333
359
 
334
- if os.environ.get("SOCKET_CLI_COANA_FORCE_NPM_INSTALL"):
360
+ if launcher_mode == "npm-install":
335
361
  return self._spawn_coana_via_npm_install(coana_args, effective_version, coana_env, cwd)
336
362
 
337
363
  package_spec = f"@coana-tech/cli@{effective_version}"
@@ -347,7 +373,7 @@ class ReachabilityAnalyzer:
347
373
  )
348
374
  except FileNotFoundError:
349
375
  # npx is not on PATH: the launcher provably never started coana.
350
- if disable_fallback:
376
+ if launcher_mode == "npx":
351
377
  raise
352
378
  log.warning("npx not found on PATH; retrying reachability analysis via `npm install` + `node`.")
353
379
  return self._spawn_coana_via_npm_install(coana_args, effective_version, coana_env, cwd)
@@ -355,7 +381,7 @@ class ReachabilityAnalyzer:
355
381
  if result.returncode == 0:
356
382
  return 0
357
383
 
358
- if not disable_fallback and self._npx_launcher_failed_before_coana(result.returncode):
384
+ if launcher_mode != "npx" and self._npx_launcher_failed_before_coana(result.returncode):
359
385
  log.warning(
360
386
  f"npx launcher failed (exit {result.returncode}) before coana started; "
361
387
  "retrying reachability analysis via `npm install` + `node`."
@@ -317,6 +317,54 @@ def test_disable_fallback_propagates_npx_failure(analyzer, mocker, monkeypatch):
317
317
  assert all(c[:2] != ["npm", "install"] for c in calls)
318
318
 
319
319
 
320
+ def test_launcher_npm_install_skips_npx(analyzer, mocker, monkeypatch):
321
+ """SOCKET_CLI_COANA_LAUNCHER=npm-install routes straight to npm install + node."""
322
+ monkeypatch.setenv("SOCKET_CLI_COANA_LAUNCHER", "npm-install")
323
+ calls = _capture_spawns(analyzer, mocker, npx_behavior=0)
324
+ assert all(c[0] != "npx" for c in calls)
325
+ assert calls[0][:2] == ["npm", "install"]
326
+ assert calls[1][0] == "node"
327
+
328
+
329
+ def test_launcher_npx_propagates_npx_failure(analyzer, mocker, monkeypatch):
330
+ """SOCKET_CLI_COANA_LAUNCHER=npx: a launcher failure is NOT retried via npm."""
331
+ monkeypatch.setenv("SOCKET_CLI_COANA_LAUNCHER", "npx")
332
+ mocker.patch.object(analyzer, "_extract_scan_id", return_value=None)
333
+ calls = []
334
+
335
+ def fake_run(argv, **_kw):
336
+ calls.append(argv)
337
+ m = MagicMock()
338
+ m.returncode = 137
339
+ return m
340
+
341
+ mocker.patch.object(reachability.subprocess, "run", side_effect=fake_run)
342
+ with pytest.raises(Exception):
343
+ analyzer.run_reachability_analysis(org_slug="my-org", target_directory=".")
344
+ assert calls[0][0] == "npx"
345
+ assert all(c[:2] != ["npm", "install"] for c in calls)
346
+
347
+
348
+ def test_launcher_overrides_legacy_vars(analyzer, mocker, monkeypatch):
349
+ """A recognized SOCKET_CLI_COANA_LAUNCHER wins; legacy vars are ignored entirely."""
350
+ monkeypatch.setenv("SOCKET_CLI_COANA_LAUNCHER", "auto")
351
+ monkeypatch.setenv("SOCKET_CLI_COANA_FORCE_NPM_INSTALL", "1")
352
+ monkeypatch.setenv("SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK", "1")
353
+ calls = _capture_spawns(analyzer, mocker, npx_behavior=137)
354
+ assert calls[0][0] == "npx" # force-npm-install ignored: npx still attempted
355
+ assert calls[1][:2] == ["npm", "install"] # disable-fallback ignored: fallback runs
356
+ assert calls[2][0] == "node"
357
+
358
+
359
+ def test_launcher_unrecognized_value_behaves_as_auto(analyzer, mocker, monkeypatch):
360
+ """An unrecognized SOCKET_CLI_COANA_LAUNCHER value warns and behaves as auto."""
361
+ monkeypatch.setenv("SOCKET_CLI_COANA_LAUNCHER", "bogus")
362
+ calls = _capture_spawns(analyzer, mocker, npx_behavior=137)
363
+ assert calls[0][0] == "npx"
364
+ assert calls[1][:2] == ["npm", "install"]
365
+ assert calls[2][0] == "node"
366
+
367
+
320
368
  def test_fallback_installs_once_per_version(analyzer, mocker):
321
369
  """A second in-process fallback for the same version reuses the install (no re-install)."""
322
370
  mocker.patch.object(analyzer, "_extract_scan_id", return_value="scan-123")
@@ -1283,7 +1283,7 @@ wheels = [
1283
1283
 
1284
1284
  [[package]]
1285
1285
  name = "socketsecurity"
1286
- version = "2.4.11"
1286
+ version = "2.4.13"
1287
1287
  source = { editable = "." }
1288
1288
  dependencies = [
1289
1289
  { name = "brotli", marker = "platform_python_implementation == 'CPython'" },
File without changes