diff --git a/CHANGELOG.md b/CHANGELOG.md index 90b17fc..c7a50b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 2.4.13 + +### Changed: reachability analysis types now use full names instead of "Tier 1/2/3" + +- Reachability analysis types are referred to by their full names instead of the + "Tier 1/2/3" numbering: **Full application reachability** (formerly Tier 1), + **Precomputed reachability** (formerly Tier 2), and **Dependency reachability** + (formerly Tier 3). This updates `--help` text, command output, log messages, and docs + only — wire-format values such as the `socket_tier1` scan type are unchanged for + backward compatibility. See the reachability section in `docs/cli-reference.md` for the + old→new name mapping. +- Bumped the pinned `@coana-tech/cli` version to `15.5.7`. + ## 2.4.12 ### Changed: consolidated coana launcher env vars into `SOCKET_CLI_COANA_LAUNCHER` diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 35e2218..fdbb5a7 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -240,8 +240,8 @@ If you don't want to provide the Socket API Token every time then you can use th #### Reachability Analysis | Parameter | Required | Default | Description | |:---------------------------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------------------------| -| `--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`). | -| `--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. | +| `--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`). | +| `--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. | | `--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` | | `--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` | | `--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 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`. +**Reachability analysis types:** + +Socket's reachability analysis comes in three forms, referred to by their full names rather than the older "Tier" numbering: + +- **Full application reachability** (formerly *Tier 1*) — the full-application analysis enabled by `--reach`. +- **Precomputed reachability** (formerly *Tier 2*). +- **Dependency reachability** (formerly *Tier 3*). + ## Config file support Use `--config ` to load defaults from a `.toml` or `.json` file. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 80d08f9..531099c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -22,7 +22,7 @@ Common reasons: - Policy vs dataset: - `--strict-blocking` only affects diff-scope behavior and does not make diff output equivalent to full dashboard data. - Reachability data availability: - - If reachability analysis partially fails and falls back to precomputed tiers, counts can shift. + - If reachability analysis partially fails and falls back to precomputed reachability, counts can shift. Recommended comparison path: diff --git a/pyproject.toml b/pyproject.toml index 96e9a77..151be6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "socketsecurity" -version = "2.4.12" +version = "2.4.13" requires-python = ">= 3.11" license = {"file" = "LICENSE"} dependencies = [ diff --git a/socketsecurity/__init__.py b/socketsecurity/__init__.py index c50caaf..e8d10bb 100644 --- a/socketsecurity/__init__.py +++ b/socketsecurity/__init__.py @@ -1,3 +1,3 @@ __author__ = 'socket.dev' -__version__ = '2.4.12' +__version__ = '2.4.13' USER_AGENT = f'SocketPythonCLI/{__version__}' diff --git a/socketsecurity/core/__init__.py b/socketsecurity/core/__init__.py index 4e6c032..a8cef92 100644 --- a/socketsecurity/core/__init__.py +++ b/socketsecurity/core/__init__.py @@ -58,7 +58,7 @@ # whose basename is exactly ``.socket.facts.json.br`` and stores it as plain # ``.socket.facts.json``. Compressing the facts file on upload keeps it well under the # server's per-file size cap (a ~262 MB facts file compresses to roughly 15-30 MB), -# which is required for large reachability (tier 1) scans to succeed. +# which is required for large full application reachability scans to succeed. # # The server matches the *exact* name ``.socket.facts.json.br``, so we only compress # files whose basename is exactly ``.socket.facts.json`` (a custom ``--reach-output-file`` @@ -72,8 +72,8 @@ # Stream the facts file in 1 MiB chunks so large files aren't held fully in memory. SOCKET_FACTS_BROTLI_CHUNK_SIZE = 1024 * 1024 -# Tier 1 reachability finalize retry policy. The finalize call links the tier1 scan to the -# full scan and can fail transiently (network/API blips); a few backoff retries make it robust. +# Full application reachability finalize retry policy. The finalize call links the reachability +# scan to the full scan and can fail transiently (network/API blips); a few backoff retries make it robust. TIER1_FINALIZE_MAX_ATTEMPTS = 3 TIER1_FINALIZE_BACKOFF_SECONDS = 1.0 @@ -612,21 +612,21 @@ def empty_head_scan_file() -> List[str]: def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool: """ - Finalize a tier 1 reachability scan by associating it with a full scan. + Finalize a full application reachability scan by associating it with a full scan. This function reads the tier1ReachabilityScanId from the facts file and calls the SDK to link it with the specified full scan. - Linking the tier 1 scan to the full scan helps the Socket team debug potential issues. + Linking the reachability scan to the full scan helps the Socket team debug potential issues. Args: - full_scan_id: The ID of the full scan to associate with the tier 1 scan + full_scan_id: The ID of the full scan to associate with the reachability scan facts_file_path: Path to the .socket.facts.json file containing the tier1ReachabilityScanId Returns: True if successful, False otherwise """ - log.debug(f"Finalizing tier 1 scan for full scan {full_scan_id}") + log.debug(f"Finalizing full application reachability scan for full scan {full_scan_id}") # Read the tier1ReachabilityScanId from the facts file try: @@ -649,7 +649,7 @@ def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool: log.debug(f"Failed to read tier1ReachabilityScanId from {facts_file_path}: {e}") return False - # Call the SDK to finalize the tier 1 scan, retrying transient failures with backoff. + # Call the SDK to finalize the full application reachability scan, retrying transient failures with backoff. last_error: Optional[Exception] = None for attempt in range(1, TIER1_FINALIZE_MAX_ATTEMPTS + 1): try: @@ -659,7 +659,7 @@ def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool: ) if success: - log.debug(f"Successfully finalized tier 1 scan {tier1_scan_id} for full scan {full_scan_id}") + log.debug(f"Successfully finalized full application reachability scan {tier1_scan_id} for full scan {full_scan_id}") return True log.debug( @@ -669,7 +669,7 @@ def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool: except Exception as e: last_error = e log.debug( - f"Unable to finalize tier 1 scan (attempt {attempt}/{TIER1_FINALIZE_MAX_ATTEMPTS}): {e}" + f"Unable to finalize full application reachability scan (attempt {attempt}/{TIER1_FINALIZE_MAX_ATTEMPTS}): {e}" ) if attempt < TIER1_FINALIZE_MAX_ATTEMPTS: @@ -677,12 +677,12 @@ def finalize_tier1_scan(self, full_scan_id: str, facts_file_path: str) -> bool: if last_error is not None: log.debug( - f"Giving up finalizing tier 1 scan {tier1_scan_id} after " + f"Giving up finalizing full application reachability scan {tier1_scan_id} after " f"{TIER1_FINALIZE_MAX_ATTEMPTS} attempts: {last_error}" ) else: log.debug( - f"Giving up finalizing tier 1 scan {tier1_scan_id} after " + f"Giving up finalizing full application reachability scan {tier1_scan_id} after " f"{TIER1_FINALIZE_MAX_ATTEMPTS} attempts" ) return False @@ -846,21 +846,21 @@ def create_full_scan(self, files: List[str], params: FullScanParams, base_paths: total_time = create_full_end - create_full_start log.debug(f"New Full Scan created in {total_time:.2f} seconds") - # Finalize tier1 scan if reachability analysis was enabled + # Finalize full application reachability scan if reachability analysis was enabled if self.cli_config and self.cli_config.reach: facts_file_path = os.path.join( - self.cli_config.target_path or ".", + self.cli_config.target_path or ".", self.cli_config.reach_output_file ) - log.debug(f"Reachability analysis enabled, finalizing tier1 scan for full scan {full_scan.id}") + log.debug(f"Reachability analysis enabled, finalizing full application reachability scan for full scan {full_scan.id}") try: success = self.finalize_tier1_scan(full_scan.id, facts_file_path) if success: - log.debug(f"Successfully finalized tier1 scan for full scan {full_scan.id}") + log.debug(f"Successfully finalized full application reachability scan for full scan {full_scan.id}") else: - log.debug(f"Failed to finalize tier1 scan for full scan {full_scan.id}") + log.debug(f"Failed to finalize full application reachability scan for full scan {full_scan.id}") except Exception as e: - log.warning(f"Error finalizing tier1 scan for full scan {full_scan.id}: {e}") + log.warning(f"Error finalizing full application reachability scan for full scan {full_scan.id}: {e}") return full_scan diff --git a/socketsecurity/core/tools/reachability.py b/socketsecurity/core/tools/reachability.py index 91d5037..4fd6d06 100644 --- a/socketsecurity/core/tools/reachability.py +++ b/socketsecurity/core/tools/reachability.py @@ -18,7 +18,7 @@ # Pinned @coana-tech/cli version. Bumped deliberately per Python CLI release so the # reachability engine version only changes through a standard pip upgrade (advance notice). # Pass --reach-version latest to opt into the newest published version instead. -DEFAULT_COANA_CLI_VERSION: Final = "15.5.0" +DEFAULT_COANA_CLI_VERSION: Final = "15.5.7" # Resolved @coana-tech/cli script paths from the npm-install fallback, keyed by version. # Lives for the process lifetime so repeated fallback invocations install only once @@ -55,7 +55,7 @@ def __init__(self, sdk: socketdev, api_token: str): def _resolve_coana_package_spec(self, version: Optional[str] = None) -> str: """ - Resolve the @coana-tech/cli package spec to run (e.g. '@coana-tech/cli@15.5.0'). + Resolve the @coana-tech/cli package spec to run (e.g. '@coana-tech/cli@15.5.7'). Args: version: Coana CLI version to use. @@ -64,7 +64,7 @@ def _resolve_coana_package_spec(self, version: Optional[str] = None) -> str: - '': that exact version. Returns: - str: The package specifier to use with npx (e.g. '@coana-tech/cli@15.5.0'). + str: The package specifier to use with npx (e.g. '@coana-tech/cli@15.5.7'). """ return f"@coana-tech/cli@{self._resolve_coana_version(version)}" diff --git a/uv.lock b/uv.lock index 63b5eed..160f494 100644 --- a/uv.lock +++ b/uv.lock @@ -1283,7 +1283,7 @@ wheels = [ [[package]] name = "socketsecurity" -version = "2.4.12" +version = "2.4.13" source = { editable = "." } dependencies = [ { name = "brotli", marker = "platform_python_implementation == 'CPython'" },