Skip to content

Commit f5cbdcc

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions/checkout-7.0.0
2 parents 8532406 + aca2eb3 commit f5cbdcc

12 files changed

Lines changed: 548 additions & 21 deletions

File tree

CHANGELOG.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,131 @@
11
# Changelog
22

3+
## 2.5.7
4+
5+
### Changed: bump pinned @coana-tech/cli to 15.10.0
6+
7+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.6` to
8+
`15.10.0`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
9+
engine changes.
10+
11+
## 2.5.6
12+
13+
### Changed: bump pinned @coana-tech/cli to 15.9.6
14+
15+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.5` to
16+
`15.9.6`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
17+
engine changes.
18+
19+
## 2.5.5
20+
21+
### Changed: bump pinned @coana-tech/cli to 15.9.5
22+
23+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.4` to
24+
`15.9.5`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
25+
engine changes.
26+
27+
## 2.5.4
28+
29+
### Changed: bump pinned @coana-tech/cli to 15.9.4
30+
31+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.2` to
32+
`15.9.4`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
33+
engine changes.
34+
35+
## 2.5.3
36+
37+
### Changed: bump pinned @coana-tech/cli to 15.9.2
38+
39+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.1` to
40+
`15.9.2`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
41+
engine changes.
42+
43+
## 2.5.2
44+
45+
### Changed: bump pinned @coana-tech/cli to 15.9.1
46+
47+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.9.0` to
48+
`15.9.1`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
49+
engine changes.
50+
51+
## 2.5.1
52+
53+
### Changed: bump pinned @coana-tech/cli to 15.9.0
54+
55+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.8.8` to
56+
`15.9.0`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
57+
engine changes.
58+
59+
## 2.5.0
60+
61+
### Added: `--base-scan-id` / `--base-commit-sha` diff baseline overrides
62+
63+
- New mutually exclusive flags to control which full scan a diff is compared
64+
against, instead of always using the repository's latest head scan:
65+
- `--base-scan-id <id>` diffs against that full scan ID verbatim.
66+
- `--base-commit-sha <sha>` diffs against the most recent full scan created
67+
from that commit — e.g. the PR's merge base from
68+
`git merge-base origin/main HEAD` — so PR diffs are not polluted by
69+
default-branch commits the PR never branched from.
70+
- A `--base-commit-sha` with no matching full scan is a hard error (exit code 3,
71+
or `--exit-code-on-api-error`; exit 0 with `--disable-blocking`) rather than a
72+
silent fallback to the head scan, since diffing against the wrong baseline
73+
misreports which alerts a PR introduces.
74+
- Both flags are also settable via `--config` files (`base_scan_id`,
75+
`base_commit_sha`).
76+
- **Requirement:** `--base-commit-sha` looks up an existing scan — it does not
77+
create one. Using it requires CI to run `socketcli` on every commit that lands
78+
on the default branch; see the "Diffing against the merge base" note in
79+
`docs/cli-reference.md` for the failure modes and a backfill pattern.
80+
81+
## 2.4.20
82+
83+
### Changed: bump pinned @coana-tech/cli to 15.8.8
84+
85+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.8.5` to
86+
`15.8.8`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
87+
engine changes.
88+
89+
## 2.4.19
90+
91+
### Changed: bump pinned @coana-tech/cli to 15.8.5
92+
93+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.8.4` to
94+
`15.8.5`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
95+
engine changes.
96+
97+
## 2.4.18
98+
99+
### Changed: bump pinned @coana-tech/cli to 15.8.4
100+
101+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.8.1` to
102+
`15.8.4`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
103+
engine changes.
104+
105+
## 2.4.17
106+
107+
### Changed: bump pinned @coana-tech/cli to 15.8.1
108+
109+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.6.7` to
110+
`15.8.1`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
111+
engine changes.
112+
113+
## 2.4.16
114+
115+
### Changed: bump pinned @coana-tech/cli to 15.6.7
116+
117+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.6.1` to
118+
`15.6.7`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
119+
engine changes.
120+
121+
## 2.4.15
122+
123+
### Changed: bump pinned @coana-tech/cli to 15.6.1
124+
125+
- Bumped the pinned reachability engine (`@coana-tech/cli`) from `15.5.9` to
126+
`15.6.1`. See the [Coana changelogs](https://docs.coana.tech/changelogs) for
127+
engine changes.
128+
3129
## 2.4.14
4130

5131
### Changed: bump pinned @coana-tech/cli to 15.5.9

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ socketcli --target-path .
4242
socketcli --enable-gitlab-security --gitlab-security-file gl-dependency-scanning-report.json
4343
```
4444

45+
### PR scan diffed against the merge base
46+
47+
By default, PR scans are diffed against the repository's latest head scan. To diff against
48+
the exact commit your PR branched from instead, pass the merge base as the baseline:
49+
50+
```bash
51+
BASE_SHA=$(git merge-base origin/main HEAD)
52+
socketcli --pr-number 123 --base-commit-sha "$BASE_SHA"
53+
```
54+
55+
> **Requirement:** `--base-commit-sha` only works if Socket already has a full scan for that
56+
> exact commit. In practice this means your CI must run `socketcli` on **every commit that
57+
> lands on your default branch** — not just some of them. If merges can land without a scan
58+
> (skipped/canceled builds, `[skip ci]`, path-filtered pipelines), the PR scan will fail with
59+
> exit code 3 rather than silently diff against the wrong baseline. See
60+
> [`docs/cli-reference.md`](https://github.com/SocketDev/socket-python-cli/blob/main/docs/cli-reference.md)
61+
> for the full requirements and a backfill pattern that makes PR jobs self-sufficient.
62+
63+
A specific full scan ID also works: `--base-scan-id <id>`.
64+
4565
## SARIF use cases
4666

4767
### Full-scope reachable SARIF (grouped alerts)
@@ -204,8 +224,10 @@ Minimal pattern:
204224
| `3` | Infrastructure or API error (timeout, network failure, unexpected error) |
205225

206226
`--exit-code-on-api-error <N>` remaps the infrastructure-error code (`3`) to any
207-
value — e.g. a Buildkite `soft_fail` code, or `0` to swallow infra errors. Exit
208-
`3` is a Socket convention, not an industry standard.
227+
value — e.g. a Buildkite
228+
[`soft_fail`](https://buildkite.com/docs/pipelines/configure/step-types/command-step)
229+
code, or `0` to swallow infra errors. Exit `3` is a Socket convention, not an
230+
industry standard.
209231

210232
### How these options interact
211233

docs/ci-cd.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,54 @@ steps:
8181
SOCKET_SECURITY_API_TOKEN: "${SOCKET_SECURITY_API_TOKEN}"
8282
```
8383
84+
#### Merge-base baselines in Buildkite (dynamic pipelines)
85+
86+
Notes for using `--base-commit-sha` (see the
87+
[merge-base note in the CLI reference](cli-reference.md#pull-request-and-commit))
88+
when your steps are emitted by a
89+
[dynamic pipeline](https://buildkite.com/docs/pipelines/configure/dynamic-pipelines)
90+
generator rather than a static YAML file:
91+
92+
- **Compute the merge base at generation time, not step time.** The generator runs
93+
with a full checkout; step agents may have shallow or fresh clones where
94+
`git merge-base` fails or needs an extra fetch. Resolve it once in the generator and
95+
bake it into the emitted step's `env`. Diff against the PR's *target* branch, which
96+
isn't always the default branch (see Buildkite's
97+
[environment variables](https://buildkite.com/docs/pipelines/configure/environment-variables)):
98+
99+
```shell
100+
TARGET="${BUILDKITE_PULL_REQUEST_BASE_BRANCH:-$BUILDKITE_PIPELINE_DEFAULT_BRANCH}"
101+
BASE_SHA=$(git merge-base "origin/${TARGET}" HEAD)
102+
```
103+
104+
- **Emit the backfill step conditionally from the generator.** The generator is the
105+
natural place for the "does a baseline scan exist?" check
106+
(`GET /orgs/{org}/full-scans?repo=<repo>&commit_hash=$BASE_SHA&per_page=1`): only
107+
emit the baseline-scan step when it returns nothing. The emitted pipeline then shows
108+
in the UI whether a backfill will run.
109+
110+
- **Keep the backfill inside one command step.** The checkout-base → scan →
111+
checkout-PR sequence must not be split across steps — steps can land on different
112+
agents with different checkouts. Prefer
113+
[`git worktree`](https://git-scm.com/docs/git-worktree) over mutating the step's
114+
checkout: `git worktree add /tmp/socket-base "$BASE_SHA"` then
115+
`socketcli --target-path /tmp/socket-base --branch "$TARGET" --disable-blocking`.
116+
117+
- **Soft-fail infra errors, not findings.** A missing baseline (or any API error)
118+
exits with code 3 (`--exit-code-on-api-error` to change it); real findings exit 1.
119+
[`soft_fail: [{exit_status: 3}]`](https://buildkite.com/docs/pipelines/configure/step-types/command-step)
120+
on the PR scan step keeps infra errors from blocking merges while security findings
121+
still do.
122+
123+
- **["Cancel intermediate builds"](https://buildkite.com/docs/pipelines/configure/canceling-builds#cancel-running-intermediate-builds)
124+
on the default branch is the main source of baseline gaps.** Canceled builds never
125+
scan their commit, so merge-base lookups for PRs based on those commits fail. The
126+
conditional backfill step above is the remedy; there is no per-step exemption from
127+
build cancellation in Buildkite. If you need strict scan-once semantics for
128+
concurrent backfills of the same merge base, serialize the backfill step with a
129+
[concurrency group](https://buildkite.com/docs/pipelines/configure/workflows/controlling-concurrency)
130+
keyed on the merge-base SHA.
131+
84132
### GitLab CI
85133

86134
```yaml

docs/cli-reference.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ This will simultaneously generate:
146146
socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--workspace WORKSPACE] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
147147
[--config <path>]
148148
[--owner OWNER] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA] [--committers [COMMITTERS ...]]
149+
[--base-scan-id BASE_SCAN_ID | --base-commit-sha BASE_COMMIT_SHA]
149150
[--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--license-file-name LICENSE_FILE_NAME] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
150151
[--save-manifest-tar SAVE_MANIFEST_TAR] [--files FILES] [--sub-path SUB_PATH] [--workspace-name WORKSPACE_NAME]
151152
[--excluded-ecosystems EXCLUDED_ECOSYSTEMS] [--exclude-paths EXCLUDE_PATHS] [--include-dirs INCLUDE_DIRS] [--default-branch] [--pending-head] [--generate-license] [--enable-debug]
@@ -191,6 +192,39 @@ If you don't want to provide the Socket API Token every time then you can use th
191192
| `--pr-number` | False | "0" | Pull request number |
192193
| `--commit-message` | False | *auto* | Commit message (auto-detected from git) |
193194
| `--commit-sha` | False | *auto* | Commit SHA (auto-detected from git) |
195+
| `--base-scan-id` | False | | Full scan ID to diff against, overriding the repository's head scan as the baseline. Mutually exclusive with `--base-commit-sha` |
196+
| `--base-commit-sha`| False | | Commit SHA to diff against, overriding the repository's head scan as the baseline. The most recent full scan for that commit is used; the CLI errors (exit code 3, or `--exit-code-on-api-error`) if no scan exists for it. Mutually exclusive with `--base-scan-id` |
197+
198+
> **Diffing against the merge base** — by default, PR scans are diffed against the repository's *latest* head scan, which may include newer default-branch commits than your PR branched from. To diff against the exact commit your PR is based on, compute the merge base and pass it as the baseline:
199+
>
200+
> ```shell
201+
> BASE_SHA=$(git merge-base origin/main HEAD)
202+
> socketcli --pr-number 123 --base-commit-sha "$BASE_SHA"
203+
> ```
204+
>
205+
> **Requirement: a full scan must already exist for the merge-base commit.** `--base-commit-sha` does not create a scan of that commit; it looks up an existing one. That lookup only succeeds if your CI runs `socketcli` on **every commit that lands on your default branch** — every merge and direct push, not just periodic or latest-only scans. Common ways commits slip through without a scan:
206+
>
207+
> - CI settings that cancel or skip intermediate builds when newer commits land (e.g. Buildkite's ["cancel intermediate builds"](https://buildkite.com/docs/pipelines/configure/canceling-builds#cancel-running-intermediate-builds))
208+
> - `[skip ci]` commits, path-filtered pipelines, or failed/canceled scan steps
209+
> - merge-base commits that predate your Socket rollout
210+
>
211+
> If no scan exists for the commit, the CLI **fails** (exit code 3, or your `--exit-code-on-api-error` value; exit 0 with `--disable-blocking`) instead of silently falling back to the head scan — a wrong baseline would misreport which alerts the PR introduces. Don't adopt this flag without default-branch scan coverage in place; you'll fail PR builds on lookup misses.
212+
>
213+
> **Backfill pattern** — if your default-branch coverage has gaps, the PR job can create the missing baseline itself before scanning:
214+
>
215+
> ```shell
216+
> BASE_SHA=$(git merge-base origin/main HEAD)
217+
> # Create the baseline only if Socket doesn't have one for this commit yet
218+
> # (check: GET /orgs/{org}/full-scans?repo=<repo>&commit_hash=$BASE_SHA&per_page=1)
219+
> git checkout "$BASE_SHA"
220+
> socketcli --branch main --disable-blocking
221+
> git checkout -
222+
> socketcli --pr-number 123 --base-commit-sha "$BASE_SHA"
223+
> ```
224+
>
225+
> Run the baseline step with `--disable-blocking` (findings on the default branch must not fail the PR job) and an explicit `--branch`, since branch auto-detection is unreliable at a detached HEAD.
226+
>
227+
> Buildkite users with dynamically generated pipelines: see [Merge-base baselines in Buildkite](ci-cd.md#merge-base-baselines-in-buildkite-dynamic-pipelines) for generation-time vs. step-time guidance.
194228
195229
#### Path and File
196230
| Parameter | Required | Default | Description |
@@ -241,7 +275,7 @@ If you don't want to provide the Socket API Token every time then you can use th
241275
| Parameter | Required | Default | Description |
242276
|:---------------------------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------------------------|
243277
| `--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.9 | 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. |
278+
| `--reach-version` | False | 15.10.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. |
245279
| `--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` |
246280
| `--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` |
247281
| `--reach-concurrency` | False | 1 | Control parallel analysis execution (must be >= 1). Omitted by default, so coana applies its own default. |

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66

77
[project]
88
name = "socketsecurity"
9-
version = "2.4.14"
9+
version = "2.5.7"
1010
requires-python = ">= 3.11"
1111
license = {"file" = "LICENSE"}
1212
dependencies = [

socketsecurity/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__author__ = 'socket.dev'
2-
__version__ = '2.4.14'
2+
__version__ = '2.5.7'
33
USER_AGENT = f'SocketPythonCLI/{__version__}'

socketsecurity/config.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class CliConfig:
119119
scm: str = "api"
120120
sbom_file: Optional[str] = None
121121
commit_sha: str = ""
122+
base_scan_id: Optional[str] = None
123+
base_commit_sha: Optional[str] = None
122124
generate_license: bool = False
123125
enable_debug: bool = False
124126
allow_unverified: bool = False
@@ -265,6 +267,8 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
265267
'scm': args.scm,
266268
'sbom_file': args.sbom_file,
267269
'commit_sha': args.commit_sha,
270+
'base_scan_id': args.base_scan_id,
271+
'base_commit_sha': args.base_commit_sha,
268272
'generate_license': args.generate_license,
269273
'enable_debug': args.enable_debug,
270274
'enable_diff': args.enable_diff,
@@ -406,6 +410,12 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
406410
logging.error("--workspace-name requires --sub-path to be specified")
407411
exit(1)
408412

413+
# argparse only enforces the mutually exclusive group for real CLI args;
414+
# this also catches both values arriving via a --config file.
415+
if args.base_scan_id and args.base_commit_sha:
416+
logging.error("--base-scan-id and --base-commit-sha are mutually exclusive")
417+
exit(1)
418+
409419
if args.sarif_scope == "full" and not args.reach:
410420
logging.error("--sarif-scope full requires --reach to be specified")
411421
exit(1)
@@ -560,6 +570,25 @@ def create_argument_parser() -> argparse.ArgumentParser:
560570
help="Committer for the commit (comma separated)",
561571
nargs="*"
562572
)
573+
base_scan_group = pr_group.add_mutually_exclusive_group()
574+
base_scan_group.add_argument(
575+
"--base-scan-id",
576+
dest="base_scan_id",
577+
metavar="<id>",
578+
default=None,
579+
help="Full scan ID to diff the new scan against, overriding the repository's "
580+
"head scan as the baseline. Mutually exclusive with --base-commit-sha."
581+
)
582+
base_scan_group.add_argument(
583+
"--base-commit-sha",
584+
dest="base_commit_sha",
585+
metavar="<sha>",
586+
default=None,
587+
help="Commit SHA to diff the new scan against, overriding the repository's head "
588+
"scan as the baseline. The most recent full scan matching this commit (e.g. "
589+
"the merge base from 'git merge-base origin/main HEAD') is used; the CLI "
590+
"errors if no scan exists for it. Mutually exclusive with --base-scan-id."
591+
)
563592

564593
# Path and File options
565594
path_group = parser.add_argument_group('Path and File')

0 commit comments

Comments
 (0)