Skip to content

Commit 810a6bc

Browse files
mikolalysenkoclaude
andcommitted
docs(readme): document vendor + scan --vendor/--detached and vendor-aware commands
The vendor command had no README presence at all. Adds a full vendor section (committable model, supported ecosystems/flavors, --revert, ownership interactions, examples), scan --vendor/--detached flags + examples + the skipped/updates[] note, rollback's vendored exclusion, remove's revert-on-remove behavior, and the OpenVEX section's (vendored)/detached attestation notes (inline --vex now lists vendor; anchors updated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 414f753 commit 810a6bc

1 file changed

Lines changed: 94 additions & 10 deletions

File tree

README.md

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,13 @@ socket-patch scan [options]
193193
| Flag | Description |
194194
|------|-------------|
195195
| `--apply` | Download and apply selected patches in JSON mode (non-interactive). Without it, `scan --json` is read-only. |
196-
| `--prune` | Garbage-collect after the scan: remove manifest entries for uninstalled packages and orphan blob/diff/package-archive files. Off by default. |
196+
| `--prune` | Garbage-collect after the scan: remove manifest entries for uninstalled packages and orphan blob/diff/package-archive files. Off by default. [Vendored](#vendor) packages are never pruned. |
197197
| `--sync` | Sugar for `--apply --prune`. The canonical bot-mode flag. |
198+
| `--vendor` | [Vendor](#vendor) every patched dependency instead of applying in place: discover, download, and build + wire the committable `.socket/vendor/` artifacts in one pass. Re-vendors automatically when a newer patch is selected. Conflicts with `--apply`/`--sync`; combine with `--prune`. |
199+
| `--detached` | With `--vendor`: skip all `.socket/manifest.json` writes — the vendor ledger embeds the patch records instead. For projects that want the vendored patches *only* in the lockfile + `.socket/vendor/`. |
198200
| `--batch-size <n>` | Packages per API request (default: `100`) |
199201
| `--all-releases` | Store patches for every release/distribution variant, not just the installed one — makes the manifest portable across environments (e.g. cross-platform CI caches) |
200-
| `--vex <path>` | On a successful scan, also write an OpenVEX 0.2.0 document to this path. See [Inline VEX generation](#inline-vex-on-apply--scan). (env: `SOCKET_VEX`) |
202+
| `--vex <path>` | On a successful scan, also write an OpenVEX 0.2.0 document to this path. See [Inline VEX generation](#inline-vex-on-apply--scan--vendor). (env: `SOCKET_VEX`) |
201203
| `--vex-product`, `--vex-no-verify`, `--vex-doc-id`, `--vex-compact` | Passthrough to the embedded VEX builder; mirror the standalone [`vex`](#vex) knobs. Inert unless `--vex` is set. |
202204

203205
> Use `--dry-run` to preview what `--apply`/`--prune`/`--sync` would do without mutating disk.
@@ -230,8 +232,21 @@ socket-patch scan -g
230232

231233
# Scan + apply + emit an OpenVEX attestation in one pass
232234
socket-patch scan --json --sync --yes --vex socket.vex.json
235+
236+
# Vendor every patched dependency (committable; see the vendor command)
237+
socket-patch scan --json --vendor --yes
238+
239+
# Same, but keep the manifest out of it entirely
240+
socket-patch scan --json --vendor --detached --yes
241+
242+
# Preview what --vendor would do (would_vendor / would_revendor / already_vendored)
243+
socket-patch scan --json --vendor --yes --dry-run
233244
```
234245

246+
> Already-vendored packages are **skipped by plain `--apply`/`--sync`** (the committed artifact
247+
> is the patch); a newer available patch still appears in the JSON `updates[]` array — re-run
248+
> `scan --vendor` to take it.
249+
235250
### `apply`
236251

237252
Apply security patches from the local manifest.
@@ -245,7 +260,7 @@ socket-patch apply [options]
245260
| Flag | Description |
246261
|------|-------------|
247262
| `-f, --force` | Skip pre-application hash verification (apply even if package version differs) |
248-
| `--vex <path>` | On a successful apply, also write an OpenVEX 0.2.0 document to this path. See [Inline VEX generation](#inline-vex-on-apply--scan). (env: `SOCKET_VEX`) |
263+
| `--vex <path>` | On a successful apply, also write an OpenVEX 0.2.0 document to this path. See [Inline VEX generation](#inline-vex-on-apply--scan--vendor). (env: `SOCKET_VEX`) |
249264
| `--vex-product`, `--vex-no-verify`, `--vex-doc-id`, `--vex-compact` | Passthrough to the embedded VEX builder; mirror the standalone [`vex`](#vex) knobs. Inert unless `--vex` is set. |
250265

251266
**Examples:**
@@ -269,9 +284,75 @@ socket-patch apply --json
269284
socket-patch apply --vex socket.vex.json
270285
```
271286

287+
> Packages managed by [`vendor`](#vendor) are skipped (`skipped`/`vendored` in JSON): the
288+
> committed vendored artifact is the patch, so there is nothing for `apply` to do — even when
289+
> the installed tree (e.g. `node_modules/`) is absent.
290+
291+
### `vendor`
292+
293+
`apply`'s **committable** sibling. Instead of patching installed packages in place
294+
(machine-local state), `vendor` ejects each patched package into
295+
`.socket/vendor/<ecosystem>/<patch-uuid>/…` and rewires your lockfile so the project consumes
296+
the vendored copy. Commit `.socket/vendor/` plus the lockfile edits and **every fresh checkout
297+
builds with the patched dependency** — no `socket-patch` binary, no Socket API access, no
298+
install hook required on the consuming machine.
299+
300+
Supported ecosystems: **npm** (package-lock / yarn classic / pnpm / bun), **PyPI**
301+
(uv / poetry / pdm / pipenv / requirements.txt), **RubyGems**, **Cargo**, **Go**, and
302+
**Composer**. Vendoring is per-patch: only dependencies with a Socket patch are vendored.
303+
304+
**Usage:**
305+
```bash
306+
socket-patch vendor [options]
307+
```
308+
309+
**Command-specific options** (plus all [Global Options](#global-options)):
310+
| Flag | Description |
311+
|------|-------------|
312+
| `-f, --force` | Skip pre-vendor hash verification (vendor even if the installed files differ from the patch's `beforeHash`) |
313+
| `--revert` | Undo vendoring: restore the recorded original lockfile fragments byte-for-byte and remove the `.socket/vendor/` artifacts. Works without a manifest |
314+
| `--vex <path>` | On a successful vendor, also write an OpenVEX 0.2.0 document to this path (env: `SOCKET_VEX`) |
315+
| `--vex-product`, `--vex-no-verify`, `--vex-doc-id`, `--vex-compact` | Passthrough to the embedded VEX builder. Inert unless `--vex` is set. |
316+
317+
**How it interacts with the rest of the CLI** — once a package is vendored, `vendor` owns it:
318+
319+
- [`apply`](#apply) and [`rollback`](#rollback) skip vendored packages (they never touch a
320+
vendor-owned tree or lockfile entry).
321+
- [`remove`](#remove) **reverts the vendoring** as part of removing the patch — lockfile
322+
restored, artifact deleted — so one command fully undoes it.
323+
- [`scan`](#scan) skips downloading/applying patches for vendored packages and never prunes
324+
their manifest entries; newer patches show up in `updates[]` as the signal to re-run
325+
`scan --vendor`.
326+
- [`vex`](#vex) attests vendored patches by verifying the **committed artifact** (marked
327+
`(vendored)` in the impact statement) — no `setup` install hook needed, because the lockfile
328+
wiring *is* the persistence mechanism.
329+
- Re-running `vendor` is idempotent; patches dropped from the manifest are auto-reverted on the
330+
next run.
331+
332+
**Examples:**
333+
```bash
334+
# Vendor every patched dependency listed in the manifest
335+
socket-patch vendor
336+
337+
# Preview without writing anything
338+
socket-patch vendor --dry-run
339+
340+
# Then make it stick: commit the artifacts and the rewired lockfile
341+
git add .socket/vendor package-lock.json && git commit -m "vendor Socket patches"
342+
343+
# Undo everything (restores the original lockfile byte-for-byte)
344+
socket-patch vendor --revert
345+
346+
# JSON output for scripting
347+
socket-patch vendor --json
348+
```
349+
350+
> Prefer one command? [`scan --vendor`](#scan) discovers, downloads, *and* vendors in a single
351+
> pass.
352+
272353
### `rollback`
273354

274-
Rollback patches to restore original files. If no identifier is given, all patches are rolled back.
355+
Rollback patches to restore original files. If no identifier is given, all patches are rolled back. Packages managed by [`vendor`](#vendor) are excluded — their patch lives in the committed artifact, not the installed tree — and are listed in the JSON output's `vendored` array (use `remove` or `vendor --revert` to undo them).
275356

276357
**Usage:**
277358
```bash
@@ -339,7 +420,7 @@ Package: pkg:npm/lodash@4.17.20
339420

340421
### `remove`
341422

342-
Remove a patch from the manifest (rolls back files first by default).
423+
Remove a patch from the manifest (rolls back files first by default). If the package is [vendored](#vendor), `remove` also **reverts the vendoring** — the lockfile is restored byte-for-byte and the `.socket/vendor/` artifact is deleted — so the patch is fully gone in one command. Detached-vendored patches (from `scan --vendor --detached`) are removable by PURL or UUID too, even though they have no manifest entry.
343424

344425
**Usage:**
345426
```bash
@@ -352,7 +433,7 @@ socket-patch remove <identifier> [options]
352433
**Command-specific options** (plus all [Global Options](#global-options)):
353434
| Flag | Description |
354435
|------|-------------|
355-
| `--skip-rollback` | Only update manifest, do not restore original files |
436+
| `--skip-rollback` | Only update manifest, do not restore original files (for vendored packages this also leaves the vendor wiring + artifact in place) |
356437

357438
**Examples:**
358439
```bash
@@ -500,7 +581,7 @@ socket-patch vex --no-verify --output socket.vex.json
500581

501582
**How it works**
502583

503-
1. Reads `.socket/manifest.json` and, unless `--no-verify` is passed, re-checks each patched file's hash on disk so the attestation only covers patches that are actually applied.
584+
1. Reads `.socket/manifest.json` and, unless `--no-verify` is passed, re-checks each patched file's hash on disk so the attestation only covers patches that are actually applied. [Vendored](#vendor) patches are verified against the **committed artifact** instead of the installed tree (their impact statement carries a `(vendored)` marker), and need no `setup` install hook to be attested — the lockfile wiring is the persistence mechanism. Detached-vendored patches (`scan --vendor --detached`) attest from the vendor ledger's embedded records, so `vex` works even with no manifest file at all.
504585
2. Auto-detects the top-level **product** identifier (override with `--product`), probing in order:
505586
- `.git/config` `[remote "origin"]``pkg:github/<owner>/<repo>` (similar for GitLab/Bitbucket; raw URL otherwise)
506587
- `package.json``pkg:npm/<name>@<version>`
@@ -531,18 +612,21 @@ grype <image-or-dir> --vex socket.vex.json
531612
trivy image --vex socket.vex.json <image>
532613
```
533614

534-
Run `socket-patch get` or `socket-patch scan --sync` first — `vex` errors with `no_patches` against an empty manifest.
615+
Run `socket-patch get` or `socket-patch scan --sync` first — `vex` errors with `no_patches` when there is nothing to attest (an empty manifest and no detached-vendored patches).
535616

536-
### Inline VEX on `apply` / `scan`
617+
### Inline VEX on `apply` / `scan` / `vendor`
537618

538-
You don't need a separate `vex` invocation: pass `--vex <path>` to `apply` or `scan` and the same OpenVEX document is generated as a side-effect of a successful run.
619+
You don't need a separate `vex` invocation: pass `--vex <path>` to `apply`, `scan`, or `vendor` and the same OpenVEX document is generated as a side-effect of a successful run.
539620

540621
```bash
541622
# Patch and attest in one step
542623
socket-patch apply --vex socket.vex.json
543624

544625
# Discover, apply, prune, and attest — the full bot-mode pass
545626
socket-patch scan --json --sync --yes --vex socket.vex.json
627+
628+
# Vendor and attest — works manifest-less with --detached too
629+
socket-patch scan --json --vendor --yes --vex socket.vex.json
546630
```
547631

548632
The `--vex-product`, `--vex-no-verify`, `--vex-doc-id`, and `--vex-compact` flags mirror the standalone command's `--product` / `--no-verify` / `--doc-id` / `--compact` knobs.

0 commit comments

Comments
 (0)