Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
12 changes: 10 additions & 2 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down Expand Up @@ -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 <path>` to load defaults from a `.toml` or `.json` file.
Expand Down
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
2 changes: 1 addition & 1 deletion socketsecurity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__author__ = 'socket.dev'
__version__ = '2.4.12'
__version__ = '2.4.13'
USER_AGENT = f'SocketPythonCLI/{__version__}'
36 changes: 18 additions & 18 deletions socketsecurity/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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``
Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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(
Expand All @@ -669,20 +669,20 @@ 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:
time.sleep(TIER1_FINALIZE_BACKOFF_SECONDS * (2 ** (attempt - 1)))

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
Expand Down Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions socketsecurity/core/tools/reachability.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -64,7 +64,7 @@ def _resolve_coana_package_spec(self, version: Optional[str] = None) -> str:
- '<semver>': 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)}"

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading