@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.
- package/README.md +121 -83
- 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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
69
|
-
installation
|
|
70
|
-
for programs such as Git Bash/MSYS
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
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
|
|
80
|
-
write roots, and removes those grants after the sandboxed process tree
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
AppContainer
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
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
|
|
142
|
+
account-scoped persistent WFP rules, and copies a protected runner executable:
|
|
107
143
|
|
|
108
144
|
```powershell
|
|
109
|
-
landstrip windows
|
|
145
|
+
landstrip windows install
|
|
110
146
|
landstrip windows status
|
|
111
|
-
landstrip
|
|
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
|
|
116
|
-
accounts. Use `landstrip windows
|
|
117
|
-
loopback proxy port range.
|
|
118
|
-
revokes recorded ACL grants, removes WFP
|
|
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,
|
|
123
|
-
revokes the grants. A later lease or uninstall recovers stale journaled
|
|
124
|
-
a crash. Account credentials are random, stored with Windows
|
|
125
|
-
in policy files.
|
|
126
|
-
|
|
127
|
-
Restricted-network accounts are blocked by WFP except for loopback connections
|
|
128
|
-
the proxy port range chosen during
|
|
129
|
-
range. `network.allowLocalBinding` and
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
|
140
|
-
|
|
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
|
|
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
|
|
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;
|
|
221
|
-
restricted-user
|
|
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.
|
|
244
|
-
|
|
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
|
|
276
|
-
that has that stage. The platform detail rides along in the
|
|
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
|
|
280
|
-
`seccomp`, the only layer with a per-denial callback; Landlock enforces
|
|
281
|
-
without one. `SANDBOX_SETUP_FAILED` carries the mechanism that could
|
|
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.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
greater; 0-2 are reserved), and if the write fails the trap is
|
|
342
|
-
policy stays in effect. On Linux, a broker launch failure also
|
|
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.
|
|
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.
|
|
34
|
-
"@landstrip/landstrip-darwin-x64": "0.
|
|
35
|
-
"@landstrip/landstrip-linux-x64": "0.
|
|
36
|
-
"@landstrip/landstrip-linux-arm64": "0.
|
|
37
|
-
"@landstrip/landstrip-win32-x64": "0.
|
|
38
|
-
"@landstrip/landstrip-win32-arm64": "0.
|
|
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"
|