@landstrip/landstrip 0.17.43 → 0.18.1

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 (2) hide show
  1. package/README.md +121 -83
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -16,19 +16,46 @@ npm install --save-dev @landstrip/landstrip
16
16
  ```
17
17
 
18
18
  ```sh
19
- npx landstrip -p policy.json cargo test
19
+ npx landstrip run -p policy.json -- cargo test
20
20
  ```
21
21
 
22
22
  The npm package installs a small Node.js wrapper and a platform-specific native
23
23
  binary package.
24
24
 
25
+ ## Command line
26
+
27
+ Landstrip uses explicit commands:
28
+
29
+ ```text
30
+ landstrip run [OPTIONS] -- <PROGRAM> [ARGS...]
31
+ landstrip policy validate [OPTIONS]
32
+ landstrip policy resolve [OPTIONS]
33
+ landstrip doctor
34
+ landstrip windows install [OPTIONS]
35
+ landstrip windows status
36
+ landstrip windows uninstall
37
+ ```
38
+
39
+ The `windows` command family is available only in Windows builds.
40
+
41
+ Policy options are `-p, --policy <FILE>`, repeated in merge order, and
42
+ `--policy-format <json|yaml>`. Use `-p -` to read standard input; its format
43
+ must be explicit. `policy validate` checks the merged policy and current platform
44
+ support, returning `valid: true` or `valid: false` with a coded error. `policy
45
+ resolve` prints the normalized merged policy. Add `--tool <PROGRAM>` to either
46
+ policy command to include executable-attached policy.
47
+
48
+ Policy inspection, `doctor`, and Windows management commands each write one JSON
49
+ document to standard output. An invalid policy, an unhealthy `doctor` report, or
50
+ an unhealthy `windows status` exits with status 1. Operational failures emit a
51
+ coded trap on standard error. `run` returns the sandboxed program's exit status.
52
+
25
53
  ### Agent extensions
26
54
 
27
- The bundled extensions integrate Landstrip with Pi and OpenCode. The Pi
28
- extension sandboxes Bash execution, provides OpenCode-compatible primary-agent
29
- selection, and runs subagents as full Pi RPC processes. Subagents normally run
30
- inside an outer Landstrip sandbox; explicitly disabling sandboxing emits a
31
- warning and uses a process-only fallback:
55
+ The bundled extensions integrate Landstrip with Pi and OpenCode. The Pi extension
56
+ sandboxes Bash, supports primary agents, and runs subagents as separate Pi RPC
57
+ processes. Subagents normally run inside a Landstrip sandbox. Disabling sandboxing
58
+ shows a warning and uses process isolation only:
32
59
 
33
60
  ```sh
34
61
  pi install npm:pi-landstrip
@@ -65,82 +92,93 @@ and reports broker decisions.
65
92
 
66
93
  ### Windows
67
94
 
68
- Landstrip has two Windows backends. AppContainer is the default and needs no
69
- installation. The restricted-user backend is an explicit, preinstalled alternative
70
- for programs such as Git Bash/MSYS that cannot initialize inside AppContainer.
71
- Select the backend with the trusted command-line option `--windows-backend`; a
72
- project policy cannot select it.
95
+ Landstrip has two internal Windows implementations. AppContainer needs no
96
+ installation and is used by default. `landstrip windows install` provisions
97
+ and activates restricted-user execution for programs such as Git Bash/MSYS
98
+ that cannot initialize inside AppContainer. `landstrip windows uninstall`
99
+ returns to AppContainer. There is no implementation selector in the command
100
+ line or policy. An unhealthy restricted-user installation causes failure
101
+ rather than silent fallback, and `landstrip windows status` reports the active
102
+ implementation and health. Policies containing the removed `windows.backend`
103
+ field are rejected; use the Windows commands to select the implementation.
73
104
 
74
- Both backends use explicit read allowlists. Ancestors receive traversal-only,
75
- non-inheriting access; unrelated siblings are not exposed.
105
+ Both implementations use explicit read allowlists. Ancestors receive
106
+ traversal-only, non-inheriting access; unrelated siblings are not exposed.
76
107
 
77
108
  #### AppContainer
78
109
 
79
- Landstrip creates a per-run profile, grants its SID access to the lowered read and
80
- write roots, and removes those grants after the sandboxed process tree exits.
81
-
82
- `windows.appContainerMode` selects `"lpac"` (the default) or `"standard"`. LPAC
83
- provides the stricter boundary. Standard AppContainer can also access resources
84
- already granted to `ALL APPLICATION PACKAGES`, so selecting it is an explicit
85
- security downgrade. Landstrip never retries an LPAC launch in standard mode.
86
-
87
- Landstrip assigns the sandboxed process to a Job Object with `KILL_ON_JOB_CLOSE`, so
88
- child processes are kept in the sandbox process tree and terminated when the
89
- launcher exits. When a restrictive host Job Object prevents safe breakaway,
90
- Landstrip fails with `HOST_JOB_INCOMPATIBLE`; it never launches without its own job.
91
-
92
- `allowNetwork` grants the internet and private-network AppContainer capabilities,
93
- while the default container holds none. `windows.allowLoopback` is a separate,
94
- explicit opt-in that temporarily exempts only the per-run AppContainer SID. The
95
- exemption permits every local loopback service, not a single proxy port. Existing
96
- system exemptions are preserved and the per-run exemption is removed at exit.
97
-
98
- AppContainer capabilities are coarse. Fine-grained direct TCP policies by host or
99
- port require elevated Windows Filtering Platform rules keyed by the AppContainer
100
- SID, which is unsuitable for an unprivileged agent sandbox runtime.
110
+ Landstrip creates a per-run profile, grants its SID access to the lowered read
111
+ and write roots, and removes those grants after the sandboxed process tree
112
+ exits.
113
+
114
+ `windows.appContainerMode` selects `"lpac"` (the default) or `"standard"`.
115
+ LPAC provides the stricter boundary. Standard AppContainer can also access
116
+ resources already granted to `ALL APPLICATION PACKAGES`, so selecting it is an
117
+ explicit security downgrade. Landstrip never retries an LPAC launch in
118
+ standard mode.
119
+
120
+ Landstrip assigns the sandboxed process to a Job Object with
121
+ `KILL_ON_JOB_CLOSE`, so child processes are kept in the sandbox process tree
122
+ and terminated when the launcher exits. When a restrictive host Job Object
123
+ prevents safe breakaway, Landstrip fails with `HOST_JOB_INCOMPATIBLE`; it never
124
+ launches without its own job.
125
+
126
+ `allowNetwork` grants the internet and private-network AppContainer
127
+ capabilities, while the default container holds none. `windows.allowLoopback`
128
+ is a separate, explicit opt-in that temporarily exempts only the per-run
129
+ AppContainer SID. The exemption permits every local loopback service, not a
130
+ single proxy port. Existing system exemptions are preserved and the per-run
131
+ exemption is removed at exit.
132
+
133
+ AppContainer capabilities are coarse. Fine-grained direct TCP policies by host
134
+ or port require elevated Windows Filtering Platform rules keyed by the
135
+ AppContainer SID, which is unsuitable for an unprivileged agent sandbox
136
+ runtime.
101
137
 
102
138
  #### Restricted user
103
139
 
104
- Install the restricted-user backend once from the intended host account. Setup
140
+ Install restricted-user execution once from the intended host account. Install
105
141
  requests elevation through UAC, provisions dedicated local accounts, installs
106
- account-scoped persistent WFP rules, and copies a protected broker executable:
142
+ account-scoped persistent WFP rules, and copies a protected runner executable:
107
143
 
108
144
  ```powershell
109
- landstrip windows setup
145
+ landstrip windows install
110
146
  landstrip windows status
111
- landstrip --windows-backend restricted-user -p policy.json cargo test
147
+ landstrip run -p policy.json -- cargo test
112
148
  landstrip windows uninstall
113
149
  ```
114
150
 
115
- The default pool has eight restricted-network accounts and two unrestricted-network
116
- accounts. Use `landstrip windows setup --help` to configure pool sizes and the
117
- loopback proxy port range. Setup replaces an existing installation; uninstall
118
- revokes recorded ACL grants, removes WFP policy and accounts, and deletes the
119
- installed runner.
151
+ The default pool has eight restricted-network accounts and two
152
+ unrestricted-network accounts. Use `landstrip windows install --help` to
153
+ configure pool sizes and the loopback proxy port range. Install replaces an
154
+ existing installation; uninstall revokes recorded ACL grants, removes WFP
155
+ policy and accounts, and deletes the installed runner.
120
156
 
121
157
  Each run exclusively leases an account, journals its filesystem grants before
122
- applying them, launches the command through a restricted token and Job Object, then
123
- revokes the grants. A later lease or uninstall recovers stale journaled grants after
124
- a crash. Account credentials are random, stored with Windows DPAPI, and never placed
125
- in policy files.
126
-
127
- Restricted-network accounts are blocked by WFP except for loopback connections to
128
- the proxy port range chosen during setup. Proxy ports in a policy must fall in that
129
- range. `network.allowLocalBinding` and `windows.allowLoopback` are unsupported by
130
- this backend. `network.allowNetwork: true` instead leases an unrestricted-network
131
- account and therefore requires at least one such account in the installed pool.
132
-
133
- The restricted token enforces the per-run account-SID grants while retaining the
134
- standard `ALL APPLICATION PACKAGES` read/execute baseline for Windows and Program
135
- Files. As with standard AppContainer, resources exposed to that SID remain visible.
158
+ applying them, launches the command through a restricted token and Job Object,
159
+ then revokes the grants. A later lease or uninstall recovers stale journaled
160
+ grants after a crash. Account credentials are random, stored with Windows
161
+ DPAPI, and never placed in policy files.
162
+
163
+ Restricted-network accounts are blocked by WFP except for loopback connections
164
+ to the proxy port range chosen during installation. Proxy ports in a policy
165
+ must fall in that range. `network.allowLocalBinding` and
166
+ `windows.allowLoopback` are unsupported by this implementation.
167
+ `network.allowNetwork: true` instead leases an account and therefore requires
168
+ at least one such account in the installed pool.
169
+
170
+ The restricted token enforces the per-run account-SID grants while retaining
171
+ the standard `ALL APPLICATION PACKAGES` read/execute baseline for Windows and
172
+ Program Files. As with standard AppContainer, resources exposed to that SID
173
+ remain visible.
136
174
 
137
175
  ## Policy format
138
176
 
139
- JSON is the default policy format. Use `--format yaml` for YAML policy files or
140
- YAML read from standard input.
177
+ JSON is the default policy format for files. Use `--policy-format yaml` for YAML
178
+ or specify the format explicitly whenever policy is read from standard input.
141
179
 
142
180
  ```sh
143
- landstrip --format yaml -p policy.yaml cargo test
181
+ landstrip run --policy-format yaml -p policy.yaml -- cargo test
144
182
  ```
145
183
 
146
184
  YAML path fields can use normal lists or one statement per line:
@@ -190,8 +228,7 @@ by platform:
190
228
  - **macOS**: Globs are snapshot-expanded when the Seatbelt profile is compiled.
191
229
  Files created after `sandbox_init` are not protected by glob denies; use
192
230
  concrete paths for them. A warning is logged when glob deny patterns are used.
193
- - **Windows**: Glob `denyWrite` entries are not enforced by the AppContainer
194
- backend.
231
+ - **Windows**: Glob `denyWrite` entries are not enforced by AppContainer.
195
232
 
196
233
  ## Network policy
197
234
 
@@ -215,10 +252,10 @@ For a filesystem-only sandbox with unrestricted direct network access, set:
215
252
 
216
253
  `allowNetwork` disables Landstrip network enforcement while leaving filesystem
217
254
  policy enforcement in place. On Windows, AppContainer receives its network
218
- capabilities while the restricted-user backend leases an unrestricted-network
255
+ capabilities while restricted-user isolation leases an unrestricted-network
219
256
  account. With `allowNetwork: false`, AppContainer denies network unless
220
- `windows.allowLoopback` enables the all-loopback exemption described above; the
221
- restricted-user backend permits only the installed loopback proxy port range.
257
+ `windows.allowLoopback` enables the all-loopback exemption described above;
258
+ restricted-user isolation permits only the installed loopback proxy port range.
222
259
 
223
260
  A Windows runtime that requires standard AppContainer and loopback can opt in with
224
261
  the following policy:
@@ -240,11 +277,11 @@ Every Landstrip event, whether a sandbox denial or a failure that prevents the
240
277
  tool from running, is reported as one JSON object per line, with a fixed `kind`
241
278
  discriminant and stable `code`. Consumers route on `kind` for the record shape
242
279
  and `code` for the event. Failures and completed denials go to standard error by
243
- default. On Linux, pending query traps go only to `--trap-fd FD`, which must name
244
- an already-open descriptor.
280
+ default. The `--trap-fd FD` option is available only in Unix builds and names an
281
+ already-open descriptor. On Linux, pending query traps go only to that descriptor.
245
282
 
246
283
  ```sh
247
- landstrip --trap-fd 3 -p policy.json cargo test 3>landstrip-traps.txt
284
+ landstrip run --trap-fd 3 -p policy.json -- cargo test 3>landstrip-traps.txt
248
285
  ```
249
286
 
250
287
  The trap kinds are:
@@ -272,14 +309,15 @@ The trap kinds are:
272
309
  does not name.
273
310
 
274
311
  A code names the stage that failed, not the operating system that reported it:
275
- the same `LAUNCH_FAILED` or `SANDBOX_SETUP_FAILED` is raised by every backend
276
- that has that stage. The platform detail rides along in the record instead.
312
+ the same `LAUNCH_FAILED` or `SANDBOX_SETUP_FAILED` is raised by every
313
+ implementation that has that stage. The platform detail rides along in the
314
+ record instead.
277
315
 
278
316
  `mechanism` records the kernel layer an event is attributed to: `landlock`,
279
- `seccomp`, `seatbelt`, `appcontainer`, or `windowsuser`. Per-denial traps are always
280
- `seccomp`, the only layer with a per-denial callback; Landlock enforces in-kernel
281
- without one. `SANDBOX_SETUP_FAILED` carries the mechanism that could not be
282
- installed.
317
+ `seccomp`, `seatbelt`, `appcontainer`, or `windowsuser`. Per-denial traps are
318
+ always `seccomp`, the only layer with a per-denial callback; Landlock enforces
319
+ in-kernel without one. `SANDBOX_SETUP_FAILED` carries the mechanism that could
320
+ not be installed.
283
321
 
284
322
  `reason` is a platform-independent classification of a filesystem decision,
285
323
  derived from the policy and the requested path:
@@ -333,14 +371,14 @@ derived from the policy and the requested path:
333
371
 
334
372
  Denial traps are informational; the configured policy always applies. Landstrip
335
373
  is otherwise quiet on success: standard error belongs to Landstrip and standard
336
- output to the sandboxed tool. Failure traps include a human-readable log line;
337
- machines should read the JSON. Usage errors exit with status 2, other Landstrip
338
- failures with 1, and the tool's own status is otherwise passed through.
339
-
340
- Writing to `--trap-fd` is best-effort: it needs an already-open descriptor (3 or
341
- greater; 0-2 are reserved), and if the write fails the trap is dropped while the
342
- policy stays in effect. On Linux, a broker launch failure also reaches
343
- `--trap-fd` while the descriptor remains open.
374
+ output to the sandboxed tool. Failures are emitted as coded JSON traps. Usage
375
+ errors exit with status 2, other Landstrip failures with 1, and the tool's own
376
+ status is otherwise passed through.
377
+
378
+ On Unix, writing to `--trap-fd` is best-effort: it needs an already-open
379
+ descriptor (3 or greater; 0-2 are reserved), and if the write fails the trap is
380
+ dropped while the policy stays in effect. On Linux, a broker launch failure also
381
+ reaches `--trap-fd` while the descriptor remains open.
344
382
 
345
383
  ## Development
346
384
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@landstrip/landstrip",
3
- "version": "0.17.43",
3
+ "version": "0.18.1",
4
4
  "description": "Sandbox runner using Landlock, Seatbelt, and AppContainer",
5
5
  "license": "Apache-2.0 AND LGPL-2.1-or-later",
6
6
  "homepage": "https://github.com/landstrip/landstrip#readme",
@@ -30,12 +30,12 @@
30
30
  "LICENSE-LGPL-2.1"
31
31
  ],
32
32
  "optionalDependencies": {
33
- "@landstrip/landstrip-darwin-arm64": "0.17.43",
34
- "@landstrip/landstrip-darwin-x64": "0.17.43",
35
- "@landstrip/landstrip-linux-x64": "0.17.43",
36
- "@landstrip/landstrip-linux-arm64": "0.17.43",
37
- "@landstrip/landstrip-win32-x64": "0.17.43",
38
- "@landstrip/landstrip-win32-arm64": "0.17.43"
33
+ "@landstrip/landstrip-darwin-arm64": "0.18.1",
34
+ "@landstrip/landstrip-darwin-x64": "0.18.1",
35
+ "@landstrip/landstrip-linux-x64": "0.18.1",
36
+ "@landstrip/landstrip-linux-arm64": "0.18.1",
37
+ "@landstrip/landstrip-win32-x64": "0.18.1",
38
+ "@landstrip/landstrip-win32-arm64": "0.18.1"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"