@descryy/runtime-controller 0.3.9 → 0.4.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 (85) hide show
  1. package/dist/attach-discovery.d.ts +120 -0
  2. package/dist/attach-discovery.d.ts.map +1 -0
  3. package/dist/attach-discovery.js +409 -0
  4. package/dist/attach-discovery.js.map +1 -0
  5. package/dist/attach-fencing.d.ts +1 -0
  6. package/dist/attach-fencing.d.ts.map +1 -1
  7. package/dist/attach-fencing.js +44 -22
  8. package/dist/attach-fencing.js.map +1 -1
  9. package/dist/attach-log-file.d.ts +21 -0
  10. package/dist/attach-log-file.d.ts.map +1 -0
  11. package/dist/attach-log-file.js +81 -0
  12. package/dist/attach-log-file.js.map +1 -0
  13. package/dist/bounded-file.d.ts +11 -0
  14. package/dist/bounded-file.d.ts.map +1 -0
  15. package/dist/bounded-file.js +41 -0
  16. package/dist/bounded-file.js.map +1 -0
  17. package/dist/bounded-output.d.ts +24 -0
  18. package/dist/bounded-output.d.ts.map +1 -0
  19. package/dist/bounded-output.js +79 -0
  20. package/dist/bounded-output.js.map +1 -0
  21. package/dist/container-sandbox.d.ts +7 -20
  22. package/dist/container-sandbox.d.ts.map +1 -1
  23. package/dist/container-sandbox.js +139 -8
  24. package/dist/container-sandbox.js.map +1 -1
  25. package/dist/controller.d.ts +24 -2
  26. package/dist/controller.d.ts.map +1 -1
  27. package/dist/controller.js +260 -84
  28. package/dist/controller.js.map +1 -1
  29. package/dist/dependency-version-check.d.ts +1 -0
  30. package/dist/dependency-version-check.d.ts.map +1 -1
  31. package/dist/dependency-version-check.js +43 -24
  32. package/dist/dependency-version-check.js.map +1 -1
  33. package/dist/environment-metadata.d.ts +13 -0
  34. package/dist/environment-metadata.d.ts.map +1 -1
  35. package/dist/environment-metadata.js +138 -24
  36. package/dist/environment-metadata.js.map +1 -1
  37. package/dist/environment-version-check.d.ts +1 -0
  38. package/dist/environment-version-check.d.ts.map +1 -1
  39. package/dist/environment-version-check.js +13 -7
  40. package/dist/environment-version-check.js.map +1 -1
  41. package/dist/execution-safety.d.ts +2 -0
  42. package/dist/execution-safety.d.ts.map +1 -1
  43. package/dist/execution-safety.js +36 -0
  44. package/dist/execution-safety.js.map +1 -1
  45. package/dist/index.d.ts +16 -5
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +9 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/node-options.d.ts +3 -0
  50. package/dist/node-options.d.ts.map +1 -0
  51. package/dist/node-options.js +34 -0
  52. package/dist/node-options.js.map +1 -0
  53. package/dist/orphan-reaper-process.d.ts +2 -0
  54. package/dist/orphan-reaper-process.d.ts.map +1 -0
  55. package/dist/orphan-reaper-process.js +98 -0
  56. package/dist/orphan-reaper-process.js.map +1 -0
  57. package/dist/orphan-reaper.d.ts +25 -0
  58. package/dist/orphan-reaper.d.ts.map +1 -0
  59. package/dist/orphan-reaper.js +161 -0
  60. package/dist/orphan-reaper.js.map +1 -0
  61. package/dist/process-identity.d.ts +1 -0
  62. package/dist/process-identity.d.ts.map +1 -1
  63. package/dist/process-identity.js +18 -4
  64. package/dist/process-identity.js.map +1 -1
  65. package/dist/process-manager.d.ts +12 -9
  66. package/dist/process-manager.d.ts.map +1 -1
  67. package/dist/process-manager.js +316 -125
  68. package/dist/process-manager.js.map +1 -1
  69. package/dist/readiness.d.ts +1 -0
  70. package/dist/readiness.d.ts.map +1 -1
  71. package/dist/readiness.js +77 -11
  72. package/dist/readiness.js.map +1 -1
  73. package/dist/sandbox.d.ts +21 -8
  74. package/dist/sandbox.d.ts.map +1 -1
  75. package/dist/sandbox.js +359 -49
  76. package/dist/sandbox.js.map +1 -1
  77. package/dist/spawn-environment.d.ts +16 -0
  78. package/dist/spawn-environment.d.ts.map +1 -0
  79. package/dist/spawn-environment.js +35 -0
  80. package/dist/spawn-environment.js.map +1 -0
  81. package/dist/target-pid.d.ts +6 -0
  82. package/dist/target-pid.d.ts.map +1 -0
  83. package/dist/target-pid.js +18 -0
  84. package/dist/target-pid.js.map +1 -0
  85. package/package.json +2 -2
package/dist/sandbox.js CHANGED
@@ -39,8 +39,64 @@
39
39
  * as covered.
40
40
  */
41
41
  import { execFileSync } from "node:child_process";
42
- import { accessSync, constants as fsConstants, readFileSync, realpathSync } from "node:fs";
43
- import { dirname, isAbsolute, join, relative } from "node:path";
42
+ import { accessSync, constants as fsConstants, existsSync, lstatSync, mkdtempSync, readFileSync, readlinkSync, realpathSync, rmSync, statSync, writeFileSync, } from "node:fs";
43
+ import { homedir, tmpdir } from "node:os";
44
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
45
+ /** The hostname a network-denied sandbox runs under, and resolves. The host's own name is not
46
+ * used: with the network denied it could not reach anything the host's name reaches anyway. */
47
+ export const SANDBOX_HOSTNAME = "descry-sandbox";
48
+ const ISOLATED_HOSTS = `127.0.0.1\tlocalhost ${SANDBOX_HOSTNAME}\n` + `::1\tlocalhost ip6-localhost ip6-loopback ${SANDBOX_HOSTNAME}\n`;
49
+ const ISOLATED_NSSWITCH = "hosts: files\n";
50
+ let isolatedNamesDir = null;
51
+ /**
52
+ * The hosts and nsswitch files a network-denied sandbox resolves names from: loopback and its
53
+ * own hostname, from files only. Written by Descry rather than bound from the host, because the
54
+ * host's hosts file names internal machines and the host's nsswitch can route a lookup to a
55
+ * resolver socket the sandbox does not have. One private (0700) directory per process, recreated
56
+ * if a temp cleaner removed it, removed at exit.
57
+ */
58
+ function isolatedNameResolutionFiles() {
59
+ const dir = isolatedNamesDir;
60
+ if (dir !== null && existsSync(join(dir, "hosts")) && existsSync(join(dir, "nsswitch.conf"))) {
61
+ return { hosts: join(dir, "hosts"), nsswitch: join(dir, "nsswitch.conf") };
62
+ }
63
+ const created = mkdtempSync(join(tmpdir(), "descry-sandbox-names-"));
64
+ writeFileSync(join(created, "hosts"), ISOLATED_HOSTS, { mode: 0o444 });
65
+ writeFileSync(join(created, "nsswitch.conf"), ISOLATED_NSSWITCH, { mode: 0o444 });
66
+ if (isolatedNamesDir === null) {
67
+ process.once("exit", () => {
68
+ if (isolatedNamesDir !== null)
69
+ rmSync(isolatedNamesDir, { recursive: true, force: true });
70
+ });
71
+ }
72
+ isolatedNamesDir = created;
73
+ return { hosts: join(created, "hosts"), nsswitch: join(created, "nsswitch.conf") };
74
+ }
75
+ /**
76
+ * Name resolution inside the sandbox, derived from the network policy it runs under.
77
+ * - Network denied: Descry's own loopback-only files, and no resolv.conf.
78
+ * - Network not restricted: the host's own files, resolv.conf included (bwrap follows a
79
+ * resolv.conf symlink into /run/systemd/resolve to its target) — a filesystem-only policy
80
+ * must not silently take DNS away with it.
81
+ * `-try` on the host files: a host without one of them still starts.
82
+ */
83
+ function nameResolutionBinds(networkDenied) {
84
+ if (networkDenied) {
85
+ const files = isolatedNameResolutionFiles();
86
+ return ["--ro-bind", files.hosts, "/etc/hosts", "--ro-bind", files.nsswitch, "/etc/nsswitch.conf"];
87
+ }
88
+ return [
89
+ "--ro-bind-try",
90
+ "/etc/hosts",
91
+ "/etc/hosts",
92
+ "--ro-bind-try",
93
+ "/etc/nsswitch.conf",
94
+ "/etc/nsswitch.conf",
95
+ "--ro-bind-try",
96
+ "/etc/resolv.conf",
97
+ "/etc/resolv.conf",
98
+ ];
99
+ }
44
100
  /**
45
101
  * Whether unprivileged user namespaces -- the kernel feature bwrap needs to build a
46
102
  * mount/network namespace without running setuid-root -- are actually enabled on
@@ -119,36 +175,31 @@ function isWithin(root, target) {
119
175
  const rel = relative(root, target);
120
176
  return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
121
177
  }
178
+ function locateExecutable(command, cwd, env) {
179
+ if (command.includes("/"))
180
+ return isAbsolute(command) ? command : join(cwd, command);
181
+ for (const dir of (env.PATH ?? "").split(":")) {
182
+ if (dir === "")
183
+ continue;
184
+ const full = join(dir, command);
185
+ try {
186
+ accessSync(full, fsConstants.X_OK);
187
+ return full;
188
+ }
189
+ catch {
190
+ continue;
191
+ }
192
+ }
193
+ return null;
194
+ }
122
195
  /**
123
196
  * Resolves the real, symlink-followed directory containing the executable
124
- * `command` would run as -- the one extra host path a sandboxed process needs
125
- * beyond standard OS dirs and whatever the caller declared. Computed generically,
126
- * not per-language: an interpreter installed outside `/usr` (nvm, rbenv, pyenv,
127
- * sdkman) would otherwise be invisible inside the sandbox regardless of language.
128
- * Returns `null` when unresolvable -- the caller proceeds without an extra bind;
129
- * the exec fails inside the sandbox the same honest way it would outside one.
197
+ * `command` would run as. Computed generically, not per-language. Returns `null` when
198
+ * unresolvable. `applySandbox` binds the wider installation through
199
+ * `planInterpreterRoots`; this is the narrow, single-directory answer.
130
200
  */
131
201
  export function resolveExecutableDirectory(command, cwd, env) {
132
- let candidate = null;
133
- if (command.includes("/")) {
134
- candidate = isAbsolute(command) ? command : join(cwd, command);
135
- }
136
- else {
137
- const pathVar = env.PATH ?? "";
138
- for (const dir of pathVar.split(":")) {
139
- if (dir === "")
140
- continue;
141
- const full = join(dir, command);
142
- try {
143
- accessSync(full, fsConstants.X_OK);
144
- candidate = full;
145
- break;
146
- }
147
- catch {
148
- continue;
149
- }
150
- }
151
- }
202
+ const candidate = locateExecutable(command, cwd, env);
152
203
  if (candidate === null)
153
204
  return null;
154
205
  try {
@@ -158,20 +209,258 @@ export function resolveExecutableDirectory(command, cwd, env) {
158
209
  return null;
159
210
  }
160
211
  }
161
- /**
162
- * Wraps `command`/`args` with `bwrap` so the OS enforces `filesystemPolicy`/
163
- * `networkPolicy`. Neither declared returns them unchanged -- same non-regression
164
- * contract as `applyResourceLimits`.
165
- *
166
- * **Throws rather than silently spawning unconstrained** when a policy is
167
- * requested and the real mechanism can't back it -- no mechanism on this platform,
168
- * or a declared shape this mechanism doesn't implement.
169
- *
170
- * Composes with `applyResourceLimits` by wrapping *outside* it (`bwrap … --
171
- * prlimit … -- realCommand`) -- the mount namespace must exist before `prlimit` or
172
- * the real command run inside it; `prlimit` (in `/usr/bin`) is reachable through
173
- * the same base OS binding every sandboxed process gets.
174
- */
212
+ export const NO_SANDBOX_DISCLOSURES = Object.freeze({ boundInterpreterRoots: [], refusedInterpreterRoots: [] });
213
+ const MAXIMUM_SYMLINK_HOPS = 40;
214
+ function canonicalOrSelf(path) {
215
+ try {
216
+ return realpathSync(path);
217
+ }
218
+ catch {
219
+ return path;
220
+ }
221
+ }
222
+ function symlinkChain(start) {
223
+ const files = [start];
224
+ const directories = [];
225
+ let current = start;
226
+ for (let hop = 0; hop < MAXIMUM_SYMLINK_HOPS; hop += 1) {
227
+ let isLink = false;
228
+ try {
229
+ isLink = lstatSync(current).isSymbolicLink();
230
+ }
231
+ catch {
232
+ break;
233
+ }
234
+ if (!isLink)
235
+ break;
236
+ const directory = dirname(current);
237
+ directories.push(directory);
238
+ let target;
239
+ try {
240
+ target = readlinkSync(current);
241
+ }
242
+ catch {
243
+ break;
244
+ }
245
+ current = resolve(directory, target);
246
+ if (files.includes(current))
247
+ break;
248
+ files.push(current);
249
+ }
250
+ return { files, directories };
251
+ }
252
+ function virtualenvRootOf(executable) {
253
+ const binDirectory = dirname(executable);
254
+ if (basename(binDirectory) !== "bin")
255
+ return null;
256
+ const root = dirname(binDirectory);
257
+ return existsSync(join(root, "pyvenv.cfg")) ? root : null;
258
+ }
259
+ function installationPrefixOf(executableDirectory) {
260
+ if (basename(executableDirectory) !== "bin")
261
+ return { path: executableDirectory };
262
+ return { path: dirname(executableDirectory), fallback: executableDirectory };
263
+ }
264
+ function virtualenvHome(virtualenvRoot) {
265
+ const configPath = join(virtualenvRoot, "pyvenv.cfg");
266
+ let text;
267
+ try {
268
+ text = readFileSync(configPath, "utf8");
269
+ }
270
+ catch (error) {
271
+ return { kind: "refusal", refusal: { path: configPath, reason: `pyvenv.cfg could not be read: ${error instanceof Error ? error.message : String(error)}` } };
272
+ }
273
+ for (const line of text.split(/\r?\n/)) {
274
+ const separator = line.indexOf("=");
275
+ if (separator === -1 || line.slice(0, separator).trim().toLowerCase() !== "home")
276
+ continue;
277
+ const home = line.slice(separator + 1).trim();
278
+ if (home === "")
279
+ break;
280
+ return { kind: "home", candidate: installationPrefixOf(home) };
281
+ }
282
+ return { kind: "refusal", refusal: { path: configPath, reason: "pyvenv.cfg has no home entry, so the interpreter it was built on cannot be located" } };
283
+ }
284
+ function interpreterRootCandidates(executable, refusals) {
285
+ const candidates = [];
286
+ let real;
287
+ try {
288
+ real = realpathSync(executable);
289
+ }
290
+ catch {
291
+ return candidates;
292
+ }
293
+ candidates.push(installationPrefixOf(dirname(real)));
294
+ const chain = symlinkChain(executable);
295
+ for (const file of chain.files) {
296
+ const virtualenvRoot = virtualenvRootOf(file);
297
+ if (virtualenvRoot === null)
298
+ continue;
299
+ candidates.push({ path: virtualenvRoot });
300
+ const home = virtualenvHome(virtualenvRoot);
301
+ if (home.kind === "home")
302
+ candidates.push(home.candidate);
303
+ else
304
+ refusals.push(home.refusal);
305
+ }
306
+ for (const directory of chain.directories)
307
+ candidates.push({ path: directory });
308
+ return candidates;
309
+ }
310
+ function homeDirectories(env) {
311
+ const homes = new Set();
312
+ const declared = env.HOME;
313
+ if (declared !== undefined && isAbsolute(declared))
314
+ homes.add(canonicalOrSelf(declared));
315
+ try {
316
+ homes.add(canonicalOrSelf(homedir()));
317
+ }
318
+ catch {
319
+ return [...homes];
320
+ }
321
+ return [...homes];
322
+ }
323
+ const SHARED_HOME_DIRECTORIES = new Set([".local", ".config", ".cache", ".var", "snap", "Library", ".npm", ".cargo"]);
324
+ export const CREDENTIAL_STORES = [
325
+ ".ssh",
326
+ ".gnupg",
327
+ ".aws",
328
+ ".azure",
329
+ ".kube",
330
+ ".docker",
331
+ ".netrc",
332
+ ".git-credentials",
333
+ ".password-store",
334
+ ".pypirc",
335
+ ".npmrc",
336
+ "share/keyrings",
337
+ ".config/gcloud",
338
+ ".descry/credentials",
339
+ ];
340
+ function credentialStoreInside(directory, ignoredEntries = new Set()) {
341
+ for (const entry of CREDENTIAL_STORES) {
342
+ if (ignoredEntries.has(entry))
343
+ continue;
344
+ if (existsSync(join(directory, entry)))
345
+ return entry;
346
+ }
347
+ return null;
348
+ }
349
+ const PROJECT_LEVEL_CREDENTIAL_FILES = new Set([".npmrc"]);
350
+ export function sandboxPathRefusalReason(path, role, env = process.env) {
351
+ if (typeof path !== "string" || path === "")
352
+ return `${role} is empty`;
353
+ if (!isAbsolute(path))
354
+ return `${role} ${path} is not an absolute path`;
355
+ const canonical = canonicalOrSelf(path);
356
+ if (canonical === "/")
357
+ return `${role} ${path} resolves to the filesystem root, which a sandbox never binds`;
358
+ for (const home of homeDirectories(env)) {
359
+ if (canonical === home)
360
+ return `${role} ${path} is the user's home directory, which holds credential stores a sandboxed run must never read`;
361
+ if (isWithin(canonical, home))
362
+ return `${role} ${path} is an ancestor of the user's home directory, which a sandbox never binds`;
363
+ }
364
+ const store = credentialStoreInside(canonical, PROJECT_LEVEL_CREDENTIAL_FILES);
365
+ if (store !== null)
366
+ return `${role} ${path} contains a credential store (${store}), which a sandboxed run must never read`;
367
+ return null;
368
+ }
369
+ function assertSandboxPathsAllowed(options, env) {
370
+ const policy = options.filesystemPolicy;
371
+ const candidates = [["working directory", options.cwd]];
372
+ for (const root of policy?.allowedRoots ?? [])
373
+ candidates.push(["allowed root", root]);
374
+ for (const root of policy?.readOnlyRoots ?? [])
375
+ candidates.push(["read-only root", root]);
376
+ for (const [role, path] of candidates) {
377
+ const reason = sandboxPathRefusalReason(path, role, env);
378
+ if (reason !== null)
379
+ throw new Error(`sandbox refused: ${reason}`);
380
+ }
381
+ }
382
+ function interpreterRootRefusalReason(path, canonical, homes, cwd, allowedRoots) {
383
+ if (!isAbsolute(path))
384
+ return `${path} is not an absolute path`;
385
+ if (canonical === null)
386
+ return `${path} does not exist`;
387
+ try {
388
+ if (!statSync(canonical).isDirectory())
389
+ return `${path} is not a directory`;
390
+ }
391
+ catch {
392
+ return `${path} does not exist`;
393
+ }
394
+ if (canonical === "/")
395
+ return "the filesystem root is never bound";
396
+ for (const home of homes) {
397
+ if (canonical === home)
398
+ return "the user's home directory itself is never bound";
399
+ if (isWithin(canonical, home))
400
+ return "an ancestor of the user's home directory is never bound";
401
+ if (dirname(canonical) === home && SHARED_HOME_DIRECTORIES.has(basename(canonical))) {
402
+ return `${basename(canonical)} in the home directory is shared by every program the user runs, so it is never bound whole`;
403
+ }
404
+ }
405
+ const store = credentialStoreInside(canonical);
406
+ if (store !== null)
407
+ return `it contains a credential store (${store}), which a sandboxed run must never read`;
408
+ const canonicalCwd = canonicalOrSelf(cwd);
409
+ if (canonical !== canonicalCwd && isWithin(canonical, canonicalCwd)) {
410
+ return "an ancestor of the working directory is never bound -- it would expose sibling projects";
411
+ }
412
+ for (const allowed of allowedRoots) {
413
+ const canonicalAllowed = canonicalOrSelf(allowed);
414
+ if (canonical !== canonicalAllowed && isWithin(canonical, canonicalAllowed)) {
415
+ return `it contains the allowed root ${allowed}, which a read-only bind would shadow`;
416
+ }
417
+ }
418
+ return null;
419
+ }
420
+ function planInterpreterRoots(input) {
421
+ const executable = locateExecutable(input.command, input.cwd, input.env);
422
+ if (executable === null)
423
+ return { binds: [], disclosures: NO_SANDBOX_DISCLOSURES };
424
+ const refusals = [];
425
+ const candidates = interpreterRootCandidates(executable, refusals);
426
+ const homes = homeDirectories(input.env);
427
+ const boundRoots = [...input.boundRoots];
428
+ const binds = [];
429
+ const alreadyBound = (path, canonical) => boundRoots.some((bound) => isWithin(bound, path) || (canonical !== null && (isWithin(bound, canonical) || isWithin(canonicalOrSelf(bound), canonical))));
430
+ function tryBind(path) {
431
+ let canonical = null;
432
+ try {
433
+ canonical = realpathSync(path);
434
+ }
435
+ catch {
436
+ canonical = null;
437
+ }
438
+ if (isAbsolute(path) && alreadyBound(path, canonical))
439
+ return "covered";
440
+ const reason = interpreterRootRefusalReason(path, canonical, homes, input.cwd, input.allowedRoots);
441
+ if (reason !== null || canonical === null) {
442
+ refusals.push({ path, reason: reason ?? `${path} does not exist` });
443
+ return "refused";
444
+ }
445
+ binds.push({ source: canonical, destination: path });
446
+ boundRoots.push(path);
447
+ return "bound";
448
+ }
449
+ for (const candidate of candidates) {
450
+ const outcome = tryBind(candidate.path);
451
+ if (outcome === "refused" && candidate.fallback !== undefined)
452
+ tryBind(candidate.fallback);
453
+ }
454
+ const seenRefusals = new Set();
455
+ const refusedInterpreterRoots = refusals.filter((refusal) => {
456
+ const key = JSON.stringify([refusal.path, refusal.reason]);
457
+ if (seenRefusals.has(key))
458
+ return false;
459
+ seenRefusals.add(key);
460
+ return true;
461
+ });
462
+ return { binds, disclosures: { boundInterpreterRoots: binds.map((bind) => bind.destination), refusedInterpreterRoots } };
463
+ }
175
464
  export function applySandbox(options) {
176
465
  const { filesystemPolicy, networkPolicy } = options;
177
466
  if (filesystemPolicy === undefined && networkPolicy === undefined) {
@@ -179,6 +468,7 @@ export function applySandbox(options) {
179
468
  }
180
469
  const env = options.env ?? process.env;
181
470
  const platform = options.platform ?? process.platform;
471
+ assertSandboxPathsAllowed(options, env);
182
472
  if (networkPolicy !== undefined) {
183
473
  const shapeReason = unsupportedNetworkPolicyReason(networkPolicy);
184
474
  if (shapeReason !== null) {
@@ -196,16 +486,33 @@ export function applySandbox(options) {
196
486
  }
197
487
  }
198
488
  const bwrapArgs = [];
489
+ let sandboxDisclosures = NO_SANDBOX_DISCLOSURES;
199
490
  if (filesystemPolicy !== undefined) {
200
- bwrapArgs.push("--ro-bind", "/usr", "/usr", "--symlink", "/usr/bin", "/bin", "--symlink", "/usr/lib", "/lib", "--symlink", "/usr/lib64", "/lib64", "--proc", "/proc", "--dev", "/dev", "--tmpfs", "/tmp", "--bind", options.cwd, options.cwd);
491
+ bwrapArgs.push("--ro-bind", "/usr", "/usr", "--symlink", "/usr/bin", "/bin", "--symlink", "/usr/lib", "/lib", "--symlink", "/usr/lib64", "/lib64", "--proc", "/proc", "--dev", "/dev", "--tmpfs", "/tmp", "--bind", options.cwd, options.cwd,
492
+ // Without these a suite that talks to its own local server fails with EAI_AGAIN.
493
+ ...nameResolutionBinds(networkPolicy !== undefined));
201
494
  const boundRoots = ["/usr", options.cwd, ...filesystemPolicy.allowedRoots];
202
495
  for (const root of filesystemPolicy.allowedRoots) {
203
496
  bwrapArgs.push("--bind", root, root);
204
497
  }
205
- const interpreterDir = resolveExecutableDirectory(options.interpreterCommand, options.cwd, env);
206
- if (interpreterDir !== null && !boundRoots.some((root) => isWithin(root, interpreterDir))) {
207
- bwrapArgs.push("--ro-bind", interpreterDir, interpreterDir);
498
+ // Read-only, and skipped when already inside a bound root: a nested --ro-bind under a
499
+ // read-write bind would make part of an allowed root read-only.
500
+ for (const root of filesystemPolicy.readOnlyRoots ?? []) {
501
+ if (boundRoots.some((bound) => isWithin(bound, root)))
502
+ continue;
503
+ bwrapArgs.push("--ro-bind-try", root, root);
504
+ boundRoots.push(root);
208
505
  }
506
+ const plan = planInterpreterRoots({
507
+ command: options.interpreterCommand,
508
+ cwd: options.cwd,
509
+ env,
510
+ boundRoots,
511
+ allowedRoots: filesystemPolicy.allowedRoots,
512
+ });
513
+ for (const bind of plan.binds)
514
+ bwrapArgs.push("--ro-bind", bind.source, bind.destination);
515
+ sandboxDisclosures = plan.disclosures;
209
516
  }
210
517
  else {
211
518
  // No filesystem restriction declared -- mirror the host root exactly (matches
@@ -214,15 +521,18 @@ export function applySandbox(options) {
214
521
  // /proc, /dev, /tmp are remounted explicitly -- a plain `--bind / /` is not
215
522
  // recursive and would leave them looking empty inside otherwise.
216
523
  bwrapArgs.push("--bind", "/", "/", "--dev", "/dev", "--proc", "/proc", "--bind", "/tmp", "/tmp");
524
+ // Reaching this branch means a network policy was declared (both absent returned above), so
525
+ // the host's own name files are overlaid, after the root bind so the root bind cannot cover them.
526
+ bwrapArgs.push(...nameResolutionBinds(true));
217
527
  }
218
- bwrapArgs.push("--chdir", options.cwd);
528
+ bwrapArgs.push("--chdir", options.cwd, "--unshare-pid", "--unshare-ipc", "--unshare-cgroup-try", "--cap-drop", "ALL");
219
529
  if (networkPolicy !== undefined) {
220
- bwrapArgs.push("--unshare-net");
530
+ bwrapArgs.push("--unshare-net", "--unshare-uts", "--hostname", SANDBOX_HOSTNAME);
221
531
  }
222
532
  // Kills the sandboxed tree if bwrap's parent (this Node process) dies
223
533
  // unexpectedly -- a second, independent backstop alongside process-manager.ts's
224
534
  // group-kill, not a replacement for it.
225
535
  bwrapArgs.push("--die-with-parent", "--", options.command, ...options.args);
226
- return { command: "bwrap", args: bwrapArgs };
536
+ return { command: "bwrap", args: bwrapArgs, sandboxDisclosures };
227
537
  }
228
538
  //# sourceMappingURL=sandbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface HostEnvironmentDisclosure {
2
+ readonly inherited: boolean;
3
+ readonly droppedNames: readonly string[];
4
+ }
5
+ export interface ChildEnvironment {
6
+ readonly env: NodeJS.ProcessEnv;
7
+ readonly hostEnvironment: HostEnvironmentDisclosure;
8
+ }
9
+ export interface ChildEnvironmentInput {
10
+ readonly host?: NodeJS.ProcessEnv;
11
+ readonly declared?: Readonly<Record<string, string | undefined>>;
12
+ readonly inheritHostEnvironment?: boolean;
13
+ readonly platform?: NodeJS.Platform;
14
+ }
15
+ export declare function buildChildEnvironment(input?: ChildEnvironmentInput): ChildEnvironment;
16
+ //# sourceMappingURL=spawn-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-environment.d.ts","sourceRoot":"","sources":["../src/spawn-environment.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,yBAAyB,CAAC;CACrD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACjE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrC;AAQD,wBAAgB,qBAAqB,CAAC,KAAK,GAAE,qBAA0B,GAAG,gBAAgB,CAwBzF"}
@@ -0,0 +1,35 @@
1
+ import { PASSED_ENV_NAMES, SECRET_LOOKING_NAME } from "./environment-metadata.js";
2
+ const ADDITIONAL_SPAWN_ENV_NAMES = /^(CI|NODE_ENV|NODE_PATH|NODE_EXTRA_CA_CERTS|NODE_NO_WARNINGS|NODE_DISABLE_COLORS|FORCE_COLOR|NO_COLOR|COLORTERM|SSL_CERT_FILE|SSL_CERT_DIR|REQUESTS_CA_BUNDLE|CURL_CA_BUNDLE|LD_LIBRARY_PATH|PYTHONPATH|PYTHONHOME|PYTHONUTF8|PYTHONIOENCODING|PYTHONDONTWRITEBYTECODE|PYTHONUNBUFFERED|XDG_[A-Z_]+|DOCKER_HOST|DOCKER_CONFIG|DOCKER_CONTEXT|DOCKER_TLS_VERIFY|DOCKER_CERT_PATH|GOCACHE|GOMODCACHE|GOENV|GOOS|GOARCH|CGO_[A-Z0-9_]+|GRADLE_[A-Z_]+|DOTNET_[A-Z0-9_]+|NUGET_[A-Z_]+|CARGO_[A-Z_]+|RUSTFLAGS)$/;
3
+ function isPassedHostName(name, platform) {
4
+ const comparable = platform === "win32" ? name.toUpperCase() : name;
5
+ if (SECRET_LOOKING_NAME.test(comparable))
6
+ return false;
7
+ return PASSED_ENV_NAMES.test(comparable) || ADDITIONAL_SPAWN_ENV_NAMES.test(comparable);
8
+ }
9
+ export function buildChildEnvironment(input = {}) {
10
+ const host = input.host ?? process.env;
11
+ const platform = input.platform ?? process.platform;
12
+ const inherit = input.inheritHostEnvironment === true;
13
+ const declared = input.declared ?? {};
14
+ const declaredNames = new Set(Object.keys(declared));
15
+ const env = {};
16
+ const droppedNames = [];
17
+ for (const [name, value] of Object.entries(host)) {
18
+ if (value === undefined)
19
+ continue;
20
+ if (inherit || isPassedHostName(name, platform)) {
21
+ env[name] = value;
22
+ }
23
+ else if (!declaredNames.has(name)) {
24
+ droppedNames.push(name);
25
+ }
26
+ }
27
+ for (const [name, value] of Object.entries(declared)) {
28
+ if (value === undefined)
29
+ delete env[name];
30
+ else
31
+ env[name] = value;
32
+ }
33
+ return { env, hostEnvironment: { inherited: inherit, droppedNames: droppedNames.sort() } };
34
+ }
35
+ //# sourceMappingURL=spawn-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-environment.js","sourceRoot":"","sources":["../src/spawn-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAElF,MAAM,0BAA0B,GAC9B,8eAA8e,CAAC;AAmBjf,SAAS,gBAAgB,CAAC,IAAY,EAAE,QAAyB;IAC/D,MAAM,UAAU,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAA+B,EAAE;IACrE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,sBAAsB,KAAK,IAAI,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IACtC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,OAAO,IAAI,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;;YACrC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface TargetPidOptions {
2
+ readonly allowOwnProcess?: boolean;
3
+ }
4
+ export declare function targetPidRefusalReason(pid: unknown, options?: TargetPidOptions): string | null;
5
+ export declare function assertTargetPid(pid: unknown, options?: TargetPidOptions): asserts pid is number;
6
+ //# sourceMappingURL=target-pid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-pid.d.ts","sourceRoot":"","sources":["../src/target-pid.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,GAAG,IAAI,CAWlG;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,CAGnG"}
@@ -0,0 +1,18 @@
1
+ export function targetPidRefusalReason(pid, options = {}) {
2
+ if (typeof pid !== "number" || !Number.isSafeInteger(pid)) {
3
+ return `pid ${String(pid)} is not an integer`;
4
+ }
5
+ if (pid <= 1) {
6
+ return `pid ${String(pid)} is not a process this runtime may target (0 and negative values address process groups, 1 is init)`;
7
+ }
8
+ if (options.allowOwnProcess !== true && (pid === process.pid || pid === process.ppid)) {
9
+ return `pid ${String(pid)} is this runtime's own process or its parent`;
10
+ }
11
+ return null;
12
+ }
13
+ export function assertTargetPid(pid, options = {}) {
14
+ const reason = targetPidRefusalReason(pid, options);
15
+ if (reason !== null)
16
+ throw new RangeError(`invalid target pid: ${reason}`);
17
+ }
18
+ //# sourceMappingURL=target-pid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-pid.js","sourceRoot":"","sources":["../src/target-pid.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,sBAAsB,CAAC,GAAY,EAAE,UAA4B,EAAE;IACjF,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,OAAO,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAChD,CAAC;IACD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACb,OAAO,OAAO,MAAM,CAAC,GAAG,CAAC,qGAAqG,CAAC;IACjI,CAAC;IACD,IAAI,OAAO,CAAC,eAAe,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACtF,OAAO,OAAO,MAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,UAA4B,EAAE;IAC1E,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,IAAI;QAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;AAC7E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descryy/runtime-controller",
3
- "version": "0.3.9",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "description": "Runtime controller: process manager, readiness, timeout/cancellation, execution IDs, cleanup. Deliverable 2 of the runtime phase — depends on @descryy/runtime-contracts, builds no collectors.",
6
6
  "license": "UNLICENSED",
@@ -26,7 +26,7 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@descryy/runtime-contracts": "0.3.3"
29
+ "@descryy/runtime-contracts": "0.4.1"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsc -b"