@landstrip/landstrip 0.17.43 → 0.18.0

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 +117 -78
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -16,12 +16,40 @@ 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
55
  The bundled extensions integrate Landstrip with Pi and OpenCode. The Pi
@@ -65,82 +93,93 @@ and reports broker decisions.
65
93
 
66
94
  ### Windows
67
95
 
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.
96
+ Landstrip has two internal Windows implementations. AppContainer needs no
97
+ installation and is used by default. `landstrip windows install` provisions
98
+ and activates restricted-user execution for programs such as Git Bash/MSYS
99
+ that cannot initialize inside AppContainer. `landstrip windows uninstall`
100
+ returns to AppContainer. There is no implementation selector in the command
101
+ line or policy. An unhealthy restricted-user installation causes failure
102
+ rather than silent fallback, and `landstrip windows status` reports the active
103
+ implementation and health. Policies containing the removed `windows.backend`
104
+ field are rejected; use the Windows commands to select the implementation.
73
105
 
74
- Both backends use explicit read allowlists. Ancestors receive traversal-only,
75
- non-inheriting access; unrelated siblings are not exposed.
106
+ Both implementations use explicit read allowlists. Ancestors receive
107
+ traversal-only, non-inheriting access; unrelated siblings are not exposed.
76
108
 
77
109
  #### AppContainer
78
110
 
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.
111
+ Landstrip creates a per-run profile, grants its SID access to the lowered read
112
+ and write roots, and removes those grants after the sandboxed process tree
113
+ exits.
114
+
115
+ `windows.appContainerMode` selects `"lpac"` (the default) or `"standard"`.
116
+ LPAC provides the stricter boundary. Standard AppContainer can also access
117
+ resources already granted to `ALL APPLICATION PACKAGES`, so selecting it is an
118
+ explicit security downgrade. Landstrip never retries an LPAC launch in
119
+ standard mode.
120
+
121
+ Landstrip assigns the sandboxed process to a Job Object with
122
+ `KILL_ON_JOB_CLOSE`, so child processes are kept in the sandbox process tree
123
+ and terminated when the launcher exits. When a restrictive host Job Object
124
+ prevents safe breakaway, Landstrip fails with `HOST_JOB_INCOMPATIBLE`; it never
125
+ launches without its own job.
126
+
127
+ `allowNetwork` grants the internet and private-network AppContainer
128
+ capabilities, while the default container holds none. `windows.allowLoopback`
129
+ is a separate, explicit opt-in that temporarily exempts only the per-run
130
+ AppContainer SID. The exemption permits every local loopback service, not a
131
+ single proxy port. Existing system exemptions are preserved and the per-run
132
+ exemption is removed at exit.
133
+
134
+ AppContainer capabilities are coarse. Fine-grained direct TCP policies by host
135
+ or port require elevated Windows Filtering Platform rules keyed by the
136
+ AppContainer SID, which is unsuitable for an unprivileged agent sandbox
137
+ runtime.
101
138
 
102
139
  #### Restricted user
103
140
 
104
- Install the restricted-user backend once from the intended host account. Setup
141
+ Install restricted-user execution once from the intended host account. Install
105
142
  requests elevation through UAC, provisions dedicated local accounts, installs
106
- account-scoped persistent WFP rules, and copies a protected broker executable:
143
+ account-scoped persistent WFP rules, and copies a protected runner executable:
107
144
 
108
145
  ```powershell
109
- landstrip windows setup
146
+ landstrip windows install
110
147
  landstrip windows status
111
- landstrip --windows-backend restricted-user -p policy.json cargo test
148
+ landstrip run -p policy.json -- cargo test
112
149
  landstrip windows uninstall
113
150
  ```
114
151
 
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.
152
+ The default pool has eight restricted-network accounts and two
153
+ unrestricted-network accounts. Use `landstrip windows install --help` to
154
+ configure pool sizes and the loopback proxy port range. Install replaces an
155
+ existing installation; uninstall revokes recorded ACL grants, removes WFP
156
+ policy and accounts, and deletes the installed runner.
120
157
 
121
158
  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.
159
+ applying them, launches the command through a restricted token and Job Object,
160
+ then revokes the grants. A later lease or uninstall recovers stale journaled
161
+ grants after a crash. Account credentials are random, stored with Windows
162
+ DPAPI, and never placed in policy files.
163
+
164
+ Restricted-network accounts are blocked by WFP except for loopback connections
165
+ to the proxy port range chosen during installation. Proxy ports in a policy
166
+ must fall in that range. `network.allowLocalBinding` and
167
+ `windows.allowLoopback` are unsupported by this implementation.
168
+ `network.allowNetwork: true` instead leases an account and therefore requires
169
+ at least one such account in the installed pool.
170
+
171
+ The restricted token enforces the per-run account-SID grants while retaining
172
+ the standard `ALL APPLICATION PACKAGES` read/execute baseline for Windows and
173
+ Program Files. As with standard AppContainer, resources exposed to that SID
174
+ remain visible.
136
175
 
137
176
  ## Policy format
138
177
 
139
- JSON is the default policy format. Use `--format yaml` for YAML policy files or
140
- YAML read from standard input.
178
+ JSON is the default policy format for files. Use `--policy-format yaml` for YAML
179
+ or specify the format explicitly whenever policy is read from standard input.
141
180
 
142
181
  ```sh
143
- landstrip --format yaml -p policy.yaml cargo test
182
+ landstrip run --policy-format yaml -p policy.yaml -- cargo test
144
183
  ```
145
184
 
146
185
  YAML path fields can use normal lists or one statement per line:
@@ -190,8 +229,7 @@ by platform:
190
229
  - **macOS**: Globs are snapshot-expanded when the Seatbelt profile is compiled.
191
230
  Files created after `sandbox_init` are not protected by glob denies; use
192
231
  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.
232
+ - **Windows**: Glob `denyWrite` entries are not enforced by AppContainer.
195
233
 
196
234
  ## Network policy
197
235
 
@@ -215,10 +253,10 @@ For a filesystem-only sandbox with unrestricted direct network access, set:
215
253
 
216
254
  `allowNetwork` disables Landstrip network enforcement while leaving filesystem
217
255
  policy enforcement in place. On Windows, AppContainer receives its network
218
- capabilities while the restricted-user backend leases an unrestricted-network
256
+ capabilities while restricted-user isolation leases an unrestricted-network
219
257
  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.
258
+ `windows.allowLoopback` enables the all-loopback exemption described above;
259
+ restricted-user isolation permits only the installed loopback proxy port range.
222
260
 
223
261
  A Windows runtime that requires standard AppContainer and loopback can opt in with
224
262
  the following policy:
@@ -240,11 +278,11 @@ Every Landstrip event, whether a sandbox denial or a failure that prevents the
240
278
  tool from running, is reported as one JSON object per line, with a fixed `kind`
241
279
  discriminant and stable `code`. Consumers route on `kind` for the record shape
242
280
  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.
281
+ default. The `--trap-fd FD` option is available only in Unix builds and names an
282
+ already-open descriptor. On Linux, pending query traps go only to that descriptor.
245
283
 
246
284
  ```sh
247
- landstrip --trap-fd 3 -p policy.json cargo test 3>landstrip-traps.txt
285
+ landstrip run --trap-fd 3 -p policy.json -- cargo test 3>landstrip-traps.txt
248
286
  ```
249
287
 
250
288
  The trap kinds are:
@@ -272,14 +310,15 @@ The trap kinds are:
272
310
  does not name.
273
311
 
274
312
  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.
313
+ the same `LAUNCH_FAILED` or `SANDBOX_SETUP_FAILED` is raised by every
314
+ implementation that has that stage. The platform detail rides along in the
315
+ record instead.
277
316
 
278
317
  `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.
318
+ `seccomp`, `seatbelt`, `appcontainer`, or `windowsuser`. Per-denial traps are
319
+ always `seccomp`, the only layer with a per-denial callback; Landlock enforces
320
+ in-kernel without one. `SANDBOX_SETUP_FAILED` carries the mechanism that could
321
+ not be installed.
283
322
 
284
323
  `reason` is a platform-independent classification of a filesystem decision,
285
324
  derived from the policy and the requested path:
@@ -333,14 +372,14 @@ derived from the policy and the requested path:
333
372
 
334
373
  Denial traps are informational; the configured policy always applies. Landstrip
335
374
  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.
375
+ output to the sandboxed tool. Failures are emitted as coded JSON traps. Usage
376
+ errors exit with status 2, other Landstrip failures with 1, and the tool's own
377
+ status is otherwise passed through.
378
+
379
+ On Unix, writing to `--trap-fd` is best-effort: it needs an already-open
380
+ descriptor (3 or greater; 0-2 are reserved), and if the write fails the trap is
381
+ dropped while the policy stays in effect. On Linux, a broker launch failure also
382
+ reaches `--trap-fd` while the descriptor remains open.
344
383
 
345
384
  ## Development
346
385
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@landstrip/landstrip",
3
- "version": "0.17.43",
3
+ "version": "0.18.0",
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.0",
34
+ "@landstrip/landstrip-darwin-x64": "0.18.0",
35
+ "@landstrip/landstrip-linux-x64": "0.18.0",
36
+ "@landstrip/landstrip-linux-arm64": "0.18.0",
37
+ "@landstrip/landstrip-win32-x64": "0.18.0",
38
+ "@landstrip/landstrip-win32-arm64": "0.18.0"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"