@descryy/runtime-controller 0.2.1 → 0.3.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/LICENSE +6 -0
- package/dist/attach-fencing.d.ts +109 -0
- package/dist/attach-fencing.d.ts.map +1 -0
- package/dist/attach-fencing.js +215 -0
- package/dist/attach-fencing.js.map +1 -0
- package/dist/capability-registry.d.ts +0 -15
- package/dist/capability-registry.d.ts.map +1 -1
- package/dist/capability-registry.js +9 -19
- package/dist/capability-registry.js.map +1 -1
- package/dist/collector-version.d.ts +1 -8
- package/dist/collector-version.d.ts.map +1 -1
- package/dist/collector-version.js +1 -8
- package/dist/collector-version.js.map +1 -1
- package/dist/container-sandbox.d.ts +66 -150
- package/dist/container-sandbox.d.ts.map +1 -1
- package/dist/container-sandbox.js +62 -143
- package/dist/container-sandbox.js.map +1 -1
- package/dist/controller.d.ts +49 -106
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +65 -123
- package/dist/controller.js.map +1 -1
- package/dist/dependency-version-check.d.ts +19 -73
- package/dist/dependency-version-check.d.ts.map +1 -1
- package/dist/dependency-version-check.js +18 -67
- package/dist/dependency-version-check.js.map +1 -1
- package/dist/env.d.ts +4 -10
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +4 -10
- package/dist/env.js.map +1 -1
- package/dist/environment-metadata.d.ts +9 -17
- package/dist/environment-metadata.d.ts.map +1 -1
- package/dist/environment-metadata.js +12 -29
- package/dist/environment-metadata.js.map +1 -1
- package/dist/environment-version-check.d.ts +22 -65
- package/dist/environment-version-check.d.ts.map +1 -1
- package/dist/environment-version-check.js +24 -66
- package/dist/environment-version-check.js.map +1 -1
- package/dist/execution-safety.d.ts +54 -112
- package/dist/execution-safety.d.ts.map +1 -1
- package/dist/execution-safety.js +48 -102
- package/dist/execution-safety.js.map +1 -1
- package/dist/index.d.ts +2 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/orchestration.d.ts +24 -39
- package/dist/orchestration.d.ts.map +1 -1
- package/dist/orchestration.js +39 -75
- package/dist/orchestration.js.map +1 -1
- package/dist/process-collector.d.ts +8 -22
- package/dist/process-collector.d.ts.map +1 -1
- package/dist/process-collector.js +23 -55
- package/dist/process-collector.js.map +1 -1
- package/dist/process-manager.d.ts +65 -80
- package/dist/process-manager.d.ts.map +1 -1
- package/dist/process-manager.js +80 -103
- package/dist/process-manager.js.map +1 -1
- package/dist/readiness.d.ts +28 -70
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +73 -95
- package/dist/readiness.js.map +1 -1
- package/dist/sandbox.d.ts +60 -105
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +78 -121
- package/dist/sandbox.js.map +1 -1
- package/package.json +8 -3
|
@@ -1,62 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `DEC-NEXT-fault-layer-empirical-confirmation.md`'s `environment`
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* comparison -- cheap, always available, no rerun needed.
|
|
2
|
+
* `DEC-NEXT-fault-layer-empirical-confirmation.md`'s `environment` mechanism:
|
|
3
|
+
* declared/expected runner version vs observed, at execution. Same shape as
|
|
4
|
+
* `dependency-version-check.ts` -- cheap, always available, no rerun needed.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
* CI-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* YAML parser (or a regex sketch of one) for a signal that is, in every
|
|
18
|
-
* real Node project, already restated in `package.json` -- `.nvmrc` and
|
|
19
|
-
* `engines.node` are the actual, load-bearing declarations `nvm`/`npm`
|
|
20
|
-
* themselves read, checked directly against this repo's own root
|
|
21
|
-
* `package.json` (`engines: { node: ">=22.5" }`) and every fixture app
|
|
22
|
-
* under `fixture-apps/`, which all carry the same field. A future CI-file
|
|
23
|
-
* reader is a real, disclosed extension point, not a silent omission --
|
|
24
|
-
* this function's `declaredSource` is a closed union specifically so a
|
|
25
|
-
* third source can be added later without changing the shape callers
|
|
26
|
-
* already read.
|
|
27
|
-
*
|
|
28
|
-
* ## `satisfiesDeclaredNodeVersion`'s grammar is a real, narrower subset
|
|
29
|
-
*
|
|
30
|
-
* Supports `^x.y.z`, `~x.y.z`, `>=`/`<=`/`>`/`<` clauses, a bare version at
|
|
31
|
-
* any precision (`"20"`, `"20.11"`, `"20.11.5"`, each an x-range at that
|
|
32
|
-
* precision -- `"20"` means "any 20.x.y", matching what `actions/setup-node`
|
|
33
|
-
* itself does for a bare major), and space-separated AND clauses
|
|
34
|
-
* (`">=20.0.0 <21.0.0"`), npm's own shape for a bounded range. Does **not**
|
|
35
|
-
* support `||` (OR), hyphen ranges (`"1.2.3 - 2.3.4"`), prerelease/build
|
|
36
|
-
* tags, or the `x`/`*` wildcard tokens (`"20.x"`) -- an input using any of
|
|
37
|
-
* those parses to `null` ("cannot say") rather than a silently wrong
|
|
38
|
-
* true/false, the same "disclosed narrower scope, not a guess" pattern this
|
|
39
|
-
* repo already applies to `EnvironmentMetadata.toolchainVersions`' `null`
|
|
40
|
-
* entries.
|
|
6
|
+
* - "Declared" reads `.nvmrc`/`package.json engines.node`, not a CI-workflow parser
|
|
7
|
+
* -- nothing here already parses CI YAML, and these are the load-bearing
|
|
8
|
+
* declarations `nvm`/`npm` themselves read. A future CI-file reader is a
|
|
9
|
+
* disclosed extension point: `declaredSource` is a closed union so a third source
|
|
10
|
+
* can be added without changing callers' shape.
|
|
11
|
+
* - `satisfiesDeclaredNodeVersion`'s grammar supports `^x.y.z`, `~x.y.z`,
|
|
12
|
+
* `>=`/`<=`/`>`/`<`, a bare version at any precision (x-range at that precision,
|
|
13
|
+
* matching `actions/setup-node`), and space-separated AND clauses. Does NOT
|
|
14
|
+
* support `||`, hyphen ranges, prerelease/build tags, or `x`/`*` wildcards --
|
|
15
|
+
* those parse to `null` ("cannot say"), never a guessed true/false.
|
|
41
16
|
*/
|
|
42
17
|
import { existsSync, readFileSync } from "node:fs";
|
|
43
18
|
import { join } from "node:path";
|
|
44
19
|
export const DECLARED_VERSION_SOURCES = ["nvmrc", "package.json engines.node"];
|
|
45
20
|
/**
|
|
46
|
-
* Reads the declared Node version for the project
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* "always known, never probed" value this repo already captures elsewhere;
|
|
50
|
-
* this function never probes for it itself).
|
|
21
|
+
* Reads the declared Node version for the project at `cwd`, compares against
|
|
22
|
+
* `observedVersion` (`process.version`/`EnvironmentMetadata.nodeVersion` -- never
|
|
23
|
+
* probed here).
|
|
51
24
|
*
|
|
52
|
-
* `.nvmrc` takes precedence over `
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* more specific declaration wins, the same precedence
|
|
57
|
-
* `classifyFaultLayer` (`descry-core`) already applies between `dependency`
|
|
58
|
-
* and `environment` themselves ("the narrower, more specific structural
|
|
59
|
-
* fact... is checked first").
|
|
25
|
+
* `.nvmrc` takes precedence over `engines.node` when both exist -- it names one
|
|
26
|
+
* exact version a developer runs locally, vs. a more often permissive compatibility
|
|
27
|
+
* range. Narrower/more specific wins, same precedence `classifyFaultLayer`
|
|
28
|
+
* (`descry-core`) applies between `dependency` and `environment`.
|
|
60
29
|
*/
|
|
61
30
|
export function checkEnvironmentVersion(cwd, observedVersion) {
|
|
62
31
|
const notApplicable = {
|
|
@@ -98,9 +67,8 @@ export function checkEnvironmentVersion(cwd, observedVersion) {
|
|
|
98
67
|
}
|
|
99
68
|
const satisfies = satisfiesDeclaredNodeVersion(declaredVersion, observedVersion);
|
|
100
69
|
if (satisfies === null) {
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// implying a comparison was actually made -- see this module's header.
|
|
70
|
+
// Grammar not covered (or observed string unparseable) -- "not applicable",
|
|
71
|
+
// not a comparison that was actually made.
|
|
104
72
|
return { applicable: false, mismatch: false, declaredVersion, declaredSource, observedVersion };
|
|
105
73
|
}
|
|
106
74
|
return { applicable: true, mismatch: !satisfies, declaredVersion, declaredSource, observedVersion };
|
|
@@ -132,11 +100,7 @@ function compareVersions(a, b) {
|
|
|
132
100
|
const CARET_PATTERN = /^\^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
133
101
|
const TILDE_PATTERN = /^~(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
134
102
|
const COMPARATOR_PATTERN = /^(>=|<=|>|<|=)?(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
135
|
-
/**
|
|
136
|
-
* `null` means "this clause's grammar is not one of the ones documented in
|
|
137
|
-
* this module's header" -- propagated up as `null`, never coerced to a
|
|
138
|
-
* guessed `true`/`false`.
|
|
139
|
-
*/
|
|
103
|
+
/** `null` means the clause's grammar isn't covered -- propagated up, never coerced to a guessed true/false. */
|
|
140
104
|
function satisfiesClause(clause, observed) {
|
|
141
105
|
const trimmed = clause.trim();
|
|
142
106
|
if (trimmed.length === 0)
|
|
@@ -196,13 +160,7 @@ function satisfiesClause(clause, observed) {
|
|
|
196
160
|
return null;
|
|
197
161
|
}
|
|
198
162
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Whether `observedVersion` satisfies `declaredRange` under the grammar
|
|
201
|
-
* documented in this module's header. `null` means the comparison could not
|
|
202
|
-
* be made at all (either string used a construct this reader does not
|
|
203
|
-
* cover) -- distinct from `false`, which is a real, positive "does not
|
|
204
|
-
* satisfy" answer.
|
|
205
|
-
*/
|
|
163
|
+
/** Whether `observedVersion` satisfies `declaredRange` under the grammar above. `null` means the comparison couldn't be made -- distinct from `false`, a real "does not satisfy" answer. */
|
|
206
164
|
export function satisfiesDeclaredNodeVersion(declaredRange, observedVersion) {
|
|
207
165
|
const observed = parseVersion(observedVersion);
|
|
208
166
|
if (observed === null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-version-check.js","sourceRoot":"","sources":["../src/environment-version-check.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"environment-version-check.js","sourceRoot":"","sources":["../src/environment-version-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,153 +1,95 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* §21's execution boundary
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
-
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
-
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
-
* decision this module does not invent (plan §29's own instruction).
|
|
2
|
+
* §21/RT-070's execution boundary: resource limits and privilege reporting for a
|
|
3
|
+
* runtime declared trusted-local -- every spawned process runs with the invoking
|
|
4
|
+
* user's own OS privileges, no filesystem/network restriction. Names the boundary
|
|
5
|
+
* rather than leaving it absent (§38); real isolation (containers/namespaces) is a
|
|
6
|
+
* separate decision this module does not invent (§29).
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
-
* never assumed.
|
|
8
|
+
* Enforces for real, via the OS: CPU time, virtual memory, process count, through
|
|
9
|
+
* `prlimit` -- an exec wrapper, never a shell (a shell would undo RT-036's
|
|
10
|
+
* `tokenizeCommand` refusal of shell metacharacters). `prlimit` is util-linux, absent
|
|
11
|
+
* on macOS, so it's reported as a capability, never assumed.
|
|
18
12
|
*/
|
|
19
13
|
import type { CapabilityStatus, ResourceLimits } from "@descryy/runtime-contracts";
|
|
20
|
-
/**
|
|
21
|
-
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
22
|
-
* a parameter (defaulting to `process.env`) rather than reading it
|
|
23
|
-
* internally so the "unavailable" branch is directly testable without
|
|
24
|
-
* mutating this process's own real environment or depending on running on
|
|
25
|
-
* a platform that genuinely lacks it.
|
|
26
|
-
*/
|
|
14
|
+
/** Whether `prlimit` is reachable on PATH. `env` is a parameter (default `process.env`) so the "unavailable" branch is testable without mutating the real environment. */
|
|
27
15
|
export declare function resourceLimitCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
28
16
|
/**
|
|
29
|
-
* RT-193 originally made this always `unavailable
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* every existing caller (`ExecutionController.run()`, this package's own
|
|
34
|
-
* tests) already imports, delegating rather than duplicating the check --
|
|
35
|
-
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
36
|
-
* is ever built, this one function changes and every caller keeps working
|
|
37
|
-
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
38
|
-
* nothing enforces it yet.
|
|
17
|
+
* RT-193 originally made this always `unavailable`. Now delegates to
|
|
18
|
+
* `networkIsolationCapability()` (`./sandbox.ts`), real on Linux via a bwrap network
|
|
19
|
+
* namespace -- kept as the stable name every caller already imports (the seam
|
|
20
|
+
* RT-193 anticipated). Still unconditionally `unavailable` on macOS/Windows.
|
|
39
21
|
*/
|
|
40
22
|
export declare function networkPolicyCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
41
23
|
/**
|
|
42
|
-
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
43
|
-
*
|
|
44
|
-
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
45
|
-
* opts in.
|
|
24
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`. `undefined` or
|
|
25
|
+
* empty `limits` returns them unchanged -- opt-in only.
|
|
46
26
|
*
|
|
47
|
-
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
52
|
-
* sandbox" shape §38 bans, one row up from this one.
|
|
27
|
+
* **Throws rather than silently spawning unconstrained** when a limit was requested
|
|
28
|
+
* and `prlimit` is unavailable (refuse-not-guess, per RT-036) -- the alternative is a
|
|
29
|
+
* caller asking for a memory cap and silently getting an unbounded process, the
|
|
30
|
+
* "sandbox that doesn't sandbox" shape §38 bans.
|
|
53
31
|
*/
|
|
54
32
|
export declare function applyResourceLimits(command: string, args: readonly string[], limits: ResourceLimits | undefined, env?: NodeJS.ProcessEnv): {
|
|
55
33
|
readonly command: string;
|
|
56
34
|
readonly args: readonly string[];
|
|
57
35
|
};
|
|
58
36
|
/**
|
|
59
|
-
* DEC-272
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* regardless of which privilege level was found; only the observed fact
|
|
63
|
-
* changes.
|
|
37
|
+
* DEC-272: the sandbox boundary (RT-070) must be stated to the user directly, not
|
|
38
|
+
* left as a silent doc gap. Fixed, not derived from `runningAsRoot` -- the boundary
|
|
39
|
+
* is the same regardless of privilege level found.
|
|
64
40
|
*
|
|
65
|
-
* **Scope
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
73
|
-
* genuinely more contained than "the same as if you started it yourself"
|
|
74
|
-
* says. Using this constant unconditionally for that process would be a
|
|
75
|
-
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
76
|
-
* direction to be wrong in, it just happens to be a less alarming one.
|
|
77
|
-
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
78
|
-
* returns this exact string when no policy was applied (attach-mode always,
|
|
79
|
-
* and any spawn that declared none -- unchanged from before this lane), and
|
|
80
|
-
* a real, specific description of what is and is not contained when a
|
|
81
|
-
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
82
|
-
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
83
|
-
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
41
|
+
* **Scope: this is the unconditional-unisolated text, not a universal one.** Accurate
|
|
42
|
+
* for every execution before `sandbox.ts` existed; no longer true once spawn-mode got
|
|
43
|
+
* real bwrap-backed isolation (`applySandbox`) -- using this unconditionally for an
|
|
44
|
+
* isolated process would understate its boundary, which is not the safe direction to
|
|
45
|
+
* be wrong in. `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement;
|
|
46
|
+
* this constant remains its no-policy-applied return value and attach-mode's own
|
|
47
|
+
* disclosure (attach-mode never has anything more accurate to say).
|
|
84
48
|
*/
|
|
85
49
|
export declare const SANDBOX_BOUNDARY_DISCLOSURE: string;
|
|
86
50
|
/**
|
|
87
|
-
* Whether a real
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* comment), so by the time a caller can observe a successfully spawned
|
|
92
|
-
* process, "declared" and "applied" are the same fact; this type exists so
|
|
93
|
-
* a caller states that fact explicitly rather than this function silently
|
|
94
|
-
* assuming it.
|
|
51
|
+
* Whether a real policy was actually enforced, not merely requested. `applySandbox`
|
|
52
|
+
* already throws rather than proceed unconstrained when a declared policy can't be
|
|
53
|
+
* enforced, so by the time a process is observed running, "declared" and "applied"
|
|
54
|
+
* are the same fact -- this type makes the caller state it explicitly.
|
|
95
55
|
*/
|
|
96
56
|
export interface AppliedIsolationPolicies {
|
|
97
57
|
readonly filesystemPolicyApplied: boolean;
|
|
98
58
|
readonly networkPolicyApplied: boolean;
|
|
99
59
|
}
|
|
100
60
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* this with no argument at all is identical to the pre-existing constant,
|
|
104
|
-
* the same non-regression contract every other opt-in in this file
|
|
105
|
-
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
61
|
+
* Mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE` unconditionally.
|
|
62
|
+
* Defaults to no-policy-applied, so a no-arg call matches the old constant exactly.
|
|
106
63
|
*
|
|
107
|
-
* **
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* in this function. A caller in attach-mode should simply never pass
|
|
112
|
-
* anything but the default here, and the default's return value is this
|
|
113
|
-
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
64
|
+
* **Only ever true for spawn-mode.** Attach-mode has no path to produce
|
|
65
|
+
* `filesystemPolicyApplied`/`networkPolicyApplied: true` for a process it didn't
|
|
66
|
+
* spawn (structural, see `sandbox.ts`) -- attach-mode callers should never pass
|
|
67
|
+
* anything but the default.
|
|
114
68
|
*/
|
|
115
69
|
export declare function sandboxBoundaryDisclosureFor(policies?: AppliedIsolationPolicies): string;
|
|
116
70
|
/**
|
|
117
|
-
* Attach mode's
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
122
|
-
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
123
|
-
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
124
|
-
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
125
|
-
* identical sentence rather than each writing its own paraphrase.
|
|
71
|
+
* Attach mode's contractual scope guarantee -- distinct from the sandbox-boundary
|
|
72
|
+
* disclosure above: this is what an attach-mode `Collector` is permitted to *do*, not
|
|
73
|
+
* what OS boundary wraps it. Mirrors `Collector` in `@descryy/runtime-contracts`.
|
|
74
|
+
* Stated once so every attach-mode caller surfaces the identical sentence.
|
|
126
75
|
*/
|
|
127
76
|
export declare const ATTACH_MODE_SCOPE_DISCLOSURE: string;
|
|
128
77
|
export interface PrivilegeReport {
|
|
129
|
-
/** Null when
|
|
78
|
+
/** Null when the platform has no uid concept (`process.getuid` undefined on Windows) -- distinct from `false`, a real answer. */
|
|
130
79
|
readonly runningAsRoot: boolean | null;
|
|
131
|
-
/** DEC-272: plain-language
|
|
80
|
+
/** DEC-272: plain-language sandbox boundary statement, carried on this result rather than a new return path. Always populated, independent of `runningAsRoot`. */
|
|
132
81
|
readonly disclosure: string;
|
|
133
82
|
}
|
|
134
83
|
/**
|
|
135
|
-
* Reports, never enforces. §21's
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* privilege level becomes an observable fact instead of an invisible one,
|
|
140
|
-
* which is what nothing before RT-070 made it.
|
|
84
|
+
* Reports, never enforces. §21's policy for trusted-local (RT-070) is not "refuse to
|
|
85
|
+
* run as root" -- CI containers commonly do, and a hard refusal would turn a
|
|
86
|
+
* documented boundary into an undocumented outage. The privilege level just becomes
|
|
87
|
+
* observable instead of invisible.
|
|
141
88
|
*
|
|
142
|
-
* A required parameter, not
|
|
143
|
-
*
|
|
144
|
-
* (`
|
|
145
|
-
*
|
|
146
|
-
* "caller omitted the argument" -- both look identical to the function.
|
|
147
|
-
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
148
|
-
* real callers use; this is what makes both branches -- root, and no uid
|
|
149
|
-
* concept at all -- directly testable without this process actually
|
|
150
|
-
* needing to run as root or on Windows.
|
|
89
|
+
* A required parameter, not defaulted: `undefined` is the real value a no-uid-concept
|
|
90
|
+
* platform produces, and a default can't distinguish "explicitly undefined" from
|
|
91
|
+
* "omitted." `currentPrivilegeReport()` below is the convenience wrapper; this makes
|
|
92
|
+
* both branches testable without actually running as root or on Windows.
|
|
151
93
|
*/
|
|
152
94
|
export declare function privilegeReportFor(getuid: (() => number) | undefined): PrivilegeReport;
|
|
153
95
|
export declare function currentPrivilegeReport(): PrivilegeReport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-safety.d.ts","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"execution-safety.d.ts","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGnF,0KAA0K;AAC1K,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAU9F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAE9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAchE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,QAGT,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC;AAID;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,GAAE,wBAA8C,GAAG,MAAM,CAwB7G;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAKoC,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,iIAAiI;IACjI,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,kKAAkK;IAClK,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,GAAG,eAAe,CAGtF;AAED,wBAAgB,sBAAsB,IAAI,eAAe,CAExD"}
|
package/dist/execution-safety.js
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* §21's execution boundary
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
-
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
-
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
-
* decision this module does not invent (plan §29's own instruction).
|
|
2
|
+
* §21/RT-070's execution boundary: resource limits and privilege reporting for a
|
|
3
|
+
* runtime declared trusted-local -- every spawned process runs with the invoking
|
|
4
|
+
* user's own OS privileges, no filesystem/network restriction. Names the boundary
|
|
5
|
+
* rather than leaving it absent (§38); real isolation (containers/namespaces) is a
|
|
6
|
+
* separate decision this module does not invent (§29).
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
-
* never assumed.
|
|
8
|
+
* Enforces for real, via the OS: CPU time, virtual memory, process count, through
|
|
9
|
+
* `prlimit` -- an exec wrapper, never a shell (a shell would undo RT-036's
|
|
10
|
+
* `tokenizeCommand` refusal of shell metacharacters). `prlimit` is util-linux, absent
|
|
11
|
+
* on macOS, so it's reported as a capability, never assumed.
|
|
18
12
|
*/
|
|
19
13
|
import { execFileSync } from "node:child_process";
|
|
20
14
|
import { networkIsolationCapability } from "./sandbox.js";
|
|
21
|
-
/**
|
|
22
|
-
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
23
|
-
* a parameter (defaulting to `process.env`) rather than reading it
|
|
24
|
-
* internally so the "unavailable" branch is directly testable without
|
|
25
|
-
* mutating this process's own real environment or depending on running on
|
|
26
|
-
* a platform that genuinely lacks it.
|
|
27
|
-
*/
|
|
15
|
+
/** Whether `prlimit` is reachable on PATH. `env` is a parameter (default `process.env`) so the "unavailable" branch is testable without mutating the real environment. */
|
|
28
16
|
export function resourceLimitCapability(env = process.env) {
|
|
29
17
|
try {
|
|
30
18
|
execFileSync("prlimit", ["--version"], { env, stdio: "ignore" });
|
|
@@ -38,32 +26,22 @@ export function resourceLimitCapability(env = process.env) {
|
|
|
38
26
|
}
|
|
39
27
|
}
|
|
40
28
|
/**
|
|
41
|
-
* RT-193 originally made this always `unavailable
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* every existing caller (`ExecutionController.run()`, this package's own
|
|
46
|
-
* tests) already imports, delegating rather than duplicating the check --
|
|
47
|
-
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
48
|
-
* is ever built, this one function changes and every caller keeps working
|
|
49
|
-
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
50
|
-
* nothing enforces it yet.
|
|
29
|
+
* RT-193 originally made this always `unavailable`. Now delegates to
|
|
30
|
+
* `networkIsolationCapability()` (`./sandbox.ts`), real on Linux via a bwrap network
|
|
31
|
+
* namespace -- kept as the stable name every caller already imports (the seam
|
|
32
|
+
* RT-193 anticipated). Still unconditionally `unavailable` on macOS/Windows.
|
|
51
33
|
*/
|
|
52
34
|
export function networkPolicyCapability(env = process.env) {
|
|
53
35
|
return networkIsolationCapability(env);
|
|
54
36
|
}
|
|
55
37
|
/**
|
|
56
|
-
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
57
|
-
*
|
|
58
|
-
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
59
|
-
* opts in.
|
|
38
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`. `undefined` or
|
|
39
|
+
* empty `limits` returns them unchanged -- opt-in only.
|
|
60
40
|
*
|
|
61
|
-
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
66
|
-
* sandbox" shape §38 bans, one row up from this one.
|
|
41
|
+
* **Throws rather than silently spawning unconstrained** when a limit was requested
|
|
42
|
+
* and `prlimit` is unavailable (refuse-not-guess, per RT-036) -- the alternative is a
|
|
43
|
+
* caller asking for a memory cap and silently getting an unbounded process, the
|
|
44
|
+
* "sandbox that doesn't sandbox" shape §38 bans.
|
|
67
45
|
*/
|
|
68
46
|
export function applyResourceLimits(command, args, limits, env = process.env) {
|
|
69
47
|
if (limits === undefined)
|
|
@@ -84,50 +62,30 @@ export function applyResourceLimits(command, args, limits, env = process.env) {
|
|
|
84
62
|
return { command: "prlimit", args: [...flags, "--", command, ...args] };
|
|
85
63
|
}
|
|
86
64
|
/**
|
|
87
|
-
* DEC-272
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* regardless of which privilege level was found; only the observed fact
|
|
91
|
-
* changes.
|
|
65
|
+
* DEC-272: the sandbox boundary (RT-070) must be stated to the user directly, not
|
|
66
|
+
* left as a silent doc gap. Fixed, not derived from `runningAsRoot` -- the boundary
|
|
67
|
+
* is the same regardless of privilege level found.
|
|
92
68
|
*
|
|
93
|
-
* **Scope
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
101
|
-
* genuinely more contained than "the same as if you started it yourself"
|
|
102
|
-
* says. Using this constant unconditionally for that process would be a
|
|
103
|
-
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
104
|
-
* direction to be wrong in, it just happens to be a less alarming one.
|
|
105
|
-
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
106
|
-
* returns this exact string when no policy was applied (attach-mode always,
|
|
107
|
-
* and any spawn that declared none -- unchanged from before this lane), and
|
|
108
|
-
* a real, specific description of what is and is not contained when a
|
|
109
|
-
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
110
|
-
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
111
|
-
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
69
|
+
* **Scope: this is the unconditional-unisolated text, not a universal one.** Accurate
|
|
70
|
+
* for every execution before `sandbox.ts` existed; no longer true once spawn-mode got
|
|
71
|
+
* real bwrap-backed isolation (`applySandbox`) -- using this unconditionally for an
|
|
72
|
+
* isolated process would understate its boundary, which is not the safe direction to
|
|
73
|
+
* be wrong in. `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement;
|
|
74
|
+
* this constant remains its no-policy-applied return value and attach-mode's own
|
|
75
|
+
* disclosure (attach-mode never has anything more accurate to say).
|
|
112
76
|
*/
|
|
113
77
|
export const SANDBOX_BOUNDARY_DISCLOSURE = "This app runs with your own user permissions, the same as if you started it yourself. " +
|
|
114
78
|
"The filesystem and network are not isolated -- anything your own account could read, write, " +
|
|
115
79
|
"or reach, this run can too.";
|
|
116
80
|
const NO_POLICIES_APPLIED = { filesystemPolicyApplied: false, networkPolicyApplied: false };
|
|
117
81
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* this with no argument at all is identical to the pre-existing constant,
|
|
121
|
-
* the same non-regression contract every other opt-in in this file
|
|
122
|
-
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
82
|
+
* Mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE` unconditionally.
|
|
83
|
+
* Defaults to no-policy-applied, so a no-arg call matches the old constant exactly.
|
|
123
84
|
*
|
|
124
|
-
* **
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* in this function. A caller in attach-mode should simply never pass
|
|
129
|
-
* anything but the default here, and the default's return value is this
|
|
130
|
-
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
85
|
+
* **Only ever true for spawn-mode.** Attach-mode has no path to produce
|
|
86
|
+
* `filesystemPolicyApplied`/`networkPolicyApplied: true` for a process it didn't
|
|
87
|
+
* spawn (structural, see `sandbox.ts`) -- attach-mode callers should never pass
|
|
88
|
+
* anything but the default.
|
|
131
89
|
*/
|
|
132
90
|
export function sandboxBoundaryDisclosureFor(policies = NO_POLICIES_APPLIED) {
|
|
133
91
|
const { filesystemPolicyApplied, networkPolicyApplied } = policies;
|
|
@@ -150,15 +108,10 @@ export function sandboxBoundaryDisclosureFor(policies = NO_POLICIES_APPLIED) {
|
|
|
150
108
|
"it can read, write, or reach anything your own account's filesystem could.");
|
|
151
109
|
}
|
|
152
110
|
/**
|
|
153
|
-
* Attach mode's
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
158
|
-
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
159
|
-
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
160
|
-
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
161
|
-
* identical sentence rather than each writing its own paraphrase.
|
|
111
|
+
* Attach mode's contractual scope guarantee -- distinct from the sandbox-boundary
|
|
112
|
+
* disclosure above: this is what an attach-mode `Collector` is permitted to *do*, not
|
|
113
|
+
* what OS boundary wraps it. Mirrors `Collector` in `@descryy/runtime-contracts`.
|
|
114
|
+
* Stated once so every attach-mode caller surfaces the identical sentence.
|
|
162
115
|
*/
|
|
163
116
|
export const ATTACH_MODE_SCOPE_DISCLOSURE = "Attach mode observes an already-running process; it never executes code in it or applies changes to it. " +
|
|
164
117
|
"This is a permanent, documented architectural limitation, not a temporary gap -- there is no honest way to " +
|
|
@@ -166,22 +119,15 @@ export const ATTACH_MODE_SCOPE_DISCLOSURE = "Attach mode observes an already-run
|
|
|
166
119
|
"Respawn-and-supervise and the cgroup resource-limit move are real alternatives next to attach mode, not " +
|
|
167
120
|
"fixes to it; see their own documentation for what each actually gets you.";
|
|
168
121
|
/**
|
|
169
|
-
* Reports, never enforces. §21's
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* privilege level becomes an observable fact instead of an invisible one,
|
|
174
|
-
* which is what nothing before RT-070 made it.
|
|
122
|
+
* Reports, never enforces. §21's policy for trusted-local (RT-070) is not "refuse to
|
|
123
|
+
* run as root" -- CI containers commonly do, and a hard refusal would turn a
|
|
124
|
+
* documented boundary into an undocumented outage. The privilege level just becomes
|
|
125
|
+
* observable instead of invisible.
|
|
175
126
|
*
|
|
176
|
-
* A required parameter, not
|
|
177
|
-
*
|
|
178
|
-
* (`
|
|
179
|
-
*
|
|
180
|
-
* "caller omitted the argument" -- both look identical to the function.
|
|
181
|
-
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
182
|
-
* real callers use; this is what makes both branches -- root, and no uid
|
|
183
|
-
* concept at all -- directly testable without this process actually
|
|
184
|
-
* needing to run as root or on Windows.
|
|
127
|
+
* A required parameter, not defaulted: `undefined` is the real value a no-uid-concept
|
|
128
|
+
* platform produces, and a default can't distinguish "explicitly undefined" from
|
|
129
|
+
* "omitted." `currentPrivilegeReport()` below is the convenience wrapper; this makes
|
|
130
|
+
* both branches testable without actually running as root or on Windows.
|
|
185
131
|
*/
|
|
186
132
|
export function privilegeReportFor(getuid) {
|
|
187
133
|
if (getuid === undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-safety.js","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"execution-safety.js","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"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"}
|