@landstrip/landstrip 0.14.8 → 0.15.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 +106 -22
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -110,35 +110,79 @@ capabilities; without it the container denies all network access.
110
110
  ## Error Output
111
111
 
112
112
  Failures reported by `landstrip` are printed as JSON objects on standard
113
- error, one object per line. Each object is tagged by the trap kind, with the
114
- kind name as the single top-level key.
113
+ error, one object per line. Each object is a flat record with a fixed `kind`
114
+ discriminant and a stable `code`, so consumers can route on `kind` for the
115
+ coarse grouping and on `code` for the specific case.
115
116
 
116
117
  ```json
117
- {"Internal":{"file":"policy.json","source":"expected value at line 1 column 1"}}
118
+ {"kind":"internal","code":"INTERNAL_ERROR","detail":{"file":"policy.json","source":"expected value at line 1 column 1"}}
118
119
  ```
119
120
 
120
121
  ```json
121
- {"Launch":["cargo","No such file or directory"]}
122
+ {"kind":"launch","code":"LAUNCH_FAILED","program":"cargo","message":"No such file or directory"}
122
123
  ```
123
124
 
124
125
  The trap kinds are:
125
126
 
126
- - `Filesystem`: a filesystem access denial, as `[operation, path, mechanism]`
127
- where the operation is `read` or `write` and the mechanism is the kernel
128
- enforcement layer that detected the denial.
129
- - `Network`: a denied TCP connect or bind, as `[operation, target, mechanism]`
130
- where the operation is `connect` or `bind` and the target is `address:port`.
131
- - `Launch`: the tool could not be started, as `[program, message]`.
132
- - `Usage`: a command-line usage error, as a message string. Usage errors exit
133
- with status 2.
134
- - `Internal`: any other policy, platform, or system error, as an object of
135
- diagnostic key/value pairs (for example `source`, `file`, or platform API
136
- details).
127
+ - `filesystem`: a filesystem access denial. The stable `code` is
128
+ `FS_READ_DENIED` or `FS_WRITE_DENIED`; `operation` is `read` or `write`;
129
+ `path` is the resolved path; `requested_path` is the original path supplied by
130
+ the tool when available; `syscall`, `errno`, `flags`, `reason`,
131
+ `suggested_grant`, and `process` provide machine-readable routing context.
132
+ - `network`: a denied TCP connect or bind. The stable `code` is
133
+ `NET_CONNECT_DENIED` or `NET_BIND_DENIED`; `operation` is `connect` or `bind`;
134
+ `target` is `address:port`; `syscall`, `errno`, and `process` provide routing
135
+ context.
136
+ - `launch`: the tool could not be started. The stable `code` is `LAUNCH_FAILED`;
137
+ `program` and `message` give the program and the failure detail.
138
+ - `usage`: a command-line usage error. The stable `code` is `USAGE_ERROR`;
139
+ `message` is the error text. Usage errors exit with status 2.
140
+ - `internal`: any other policy, platform, or system error. The stable `code` is
141
+ `INTERNAL_ERROR`; `detail` is an object of diagnostic key/value pairs (for
142
+ example `source`, `file`, or platform API details).
143
+
144
+ The `reason` field is a platform-independent classification of the policy
145
+ decision, derived from the policy and the requested path rather than from the
146
+ enforcement mechanism. Its stable values are:
147
+
148
+ - `allow_miss`: the path matched no allow root and was denied by default.
149
+ - `deny_match`: the path matched an explicit deny root that overrides an allow.
150
+ - `unclassified`: a denial occurred but landstrip could not attribute it to a
151
+ specific rule.
152
+
153
+ Example of a filesystem denial:
154
+
155
+ ```json
156
+ {
157
+ "kind": "filesystem",
158
+ "code": "FS_WRITE_DENIED",
159
+ "operation": "write",
160
+ "path": "/repo/out",
161
+ "requested_path": "out",
162
+ "syscall": "openat",
163
+ "errno": "EACCES",
164
+ "flags": [
165
+ "O_WRONLY",
166
+ "O_CREAT",
167
+ "O_TRUNC"
168
+ ],
169
+ "reason": "allow_miss",
170
+ "suggested_grant": {
171
+ "allowWrite": "/repo/out"
172
+ },
173
+ "mechanism": "seccomp",
174
+ "process": {
175
+ "pid": 1234,
176
+ "exe": "/usr/bin/sh",
177
+ "cwd": "/repo"
178
+ }
179
+ }
180
+ ```
137
181
 
138
182
  Logs and sandboxed tool output are not part of the response. Normal successful
139
183
  tool execution does not print a landstrip response unless a write denial was
140
- observed (`{"Filesystem":["write","/repo/out","seccomp"]}`), because standard error
141
- belongs to landstrip; standard output belongs to the sandboxed tool.
184
+ observed, because standard error belongs to landstrip; standard output belongs
185
+ to the sandboxed tool.
142
186
 
143
187
  ## Trap FD
144
188
 
@@ -151,15 +195,55 @@ landstrip --trap-fd 3 -p policy.json cargo test 3>landstrip-traps.txt
151
195
  ```
152
196
 
153
197
  Linux filesystem and network denials observed by the seccomp broker are
154
- emitted with the same shapes as standard error:
198
+ emitted with the same object shapes as standard error:
155
199
 
156
200
  ```json
157
- {"Filesystem":["write","/repo/out","seccomp"]}
158
- {"Network":["connect","127.0.0.1:9999","seccomp"]}
201
+ {
202
+ "kind": "filesystem",
203
+ "code": "FS_WRITE_DENIED",
204
+ "operation": "write",
205
+ "path": "/repo/out",
206
+ "requested_path": "out",
207
+ "syscall": "openat",
208
+ "errno": "EACCES",
209
+ "flags": [
210
+ "O_WRONLY",
211
+ "O_CREAT",
212
+ "O_TRUNC"
213
+ ],
214
+ "reason": "allow_miss",
215
+ "suggested_grant": {
216
+ "allowWrite": "/repo/out"
217
+ },
218
+ "mechanism": "seccomp",
219
+ "process": {
220
+ "pid": 1234,
221
+ "exe": "/usr/bin/sh",
222
+ "cwd": "/repo"
223
+ }
224
+ }
225
+ {
226
+ "kind": "network",
227
+ "code": "NET_CONNECT_DENIED",
228
+ "operation": "connect",
229
+ "target": "127.0.0.1:9999",
230
+ "syscall": "connect",
231
+ "errno": "EACCES",
232
+ "mechanism": "seccomp",
233
+ "process": {
234
+ "pid": 1234,
235
+ "exe": "/usr/bin/nc",
236
+ "cwd": "/repo"
237
+ }
238
+ }
159
239
  ```
160
240
 
161
- The mechanism element records the kernel enforcement layer that detected
162
- the denial (e.g. `seccomp` or `landlock`).
241
+ The `mechanism` field records the kernel enforcement layer that detected the
242
+ denial. Per-denial `Filesystem` and `Network` traps are always `seccomp`,
243
+ because the user-notification broker is the only layer with a per-denial
244
+ callback; Landlock enforces in-kernel without one. The `landlock` value
245
+ appears only as a `mechanism` detail in an `Internal` trap when Landlock
246
+ ruleset setup fails.
163
247
 
164
248
  This stream is separate from the sandboxed tool's output. If the option is
165
249
  omitted, landstrip is quiet unless it has to report a policy, launch, or
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@landstrip/landstrip",
3
- "version": "0.14.8",
3
+ "version": "0.15.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",
@@ -24,10 +24,10 @@
24
24
  "LICENSE-LGPL-2.1"
25
25
  ],
26
26
  "optionalDependencies": {
27
- "@landstrip/landstrip-darwin-arm64": "0.14.8",
28
- "@landstrip/landstrip-darwin-x64": "0.14.8",
29
- "@landstrip/landstrip-linux-x64": "0.14.8",
30
- "@landstrip/landstrip-win32-x64": "0.14.8"
27
+ "@landstrip/landstrip-darwin-arm64": "0.15.1",
28
+ "@landstrip/landstrip-darwin-x64": "0.15.1",
29
+ "@landstrip/landstrip-linux-x64": "0.15.1",
30
+ "@landstrip/landstrip-win32-x64": "0.15.1"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public"