@namzu/sandbox 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +234 -0
- package/README.md +205 -105
- package/dist/backends/aci-standby-pool/__tests__/unenforceable-controls.test.d.ts +2 -0
- package/dist/backends/aci-standby-pool/__tests__/unenforceable-controls.test.d.ts.map +1 -0
- package/dist/backends/aci-standby-pool/__tests__/unenforceable-controls.test.js +61 -0
- package/dist/backends/aci-standby-pool/__tests__/unenforceable-controls.test.js.map +1 -0
- package/dist/backends/aci-standby-pool/index.d.ts +2 -1
- package/dist/backends/aci-standby-pool/index.d.ts.map +1 -1
- package/dist/backends/aci-standby-pool/index.js +36 -1
- package/dist/backends/aci-standby-pool/index.js.map +1 -1
- package/dist/backends/docker/__tests__/hardening.test.d.ts +2 -0
- package/dist/backends/docker/__tests__/hardening.test.d.ts.map +1 -0
- package/dist/backends/docker/__tests__/hardening.test.js +32 -0
- package/dist/backends/docker/__tests__/hardening.test.js.map +1 -0
- package/dist/backends/docker/__tests__/leaf-permissions.smoke.test.d.ts +1 -1
- package/dist/backends/docker/__tests__/leaf-permissions.smoke.test.js +1 -1
- package/dist/backends/docker/index.d.ts +47 -3
- package/dist/backends/docker/index.d.ts.map +1 -1
- package/dist/backends/docker/index.js +138 -5
- package/dist/backends/docker/index.js.map +1 -1
- package/dist/backends/firecracker/__tests__/agent-timeout-clamp.test.d.ts +16 -0
- package/dist/backends/firecracker/__tests__/agent-timeout-clamp.test.d.ts.map +1 -0
- package/dist/backends/firecracker/__tests__/agent-timeout-clamp.test.js +37 -0
- package/dist/backends/firecracker/__tests__/agent-timeout-clamp.test.js.map +1 -0
- package/dist/backends/firecracker/__tests__/backend.test.js +11 -3
- package/dist/backends/firecracker/__tests__/backend.test.js.map +1 -1
- package/dist/backends/firecracker/__tests__/control-plane-mtls.test.js +10 -2
- package/dist/backends/firecracker/__tests__/control-plane-mtls.test.js.map +1 -1
- package/dist/backends/firecracker/__tests__/egress-policy.test.d.ts +2 -0
- package/dist/backends/firecracker/__tests__/egress-policy.test.d.ts.map +1 -0
- package/dist/backends/firecracker/__tests__/egress-policy.test.js +67 -0
- package/dist/backends/firecracker/__tests__/egress-policy.test.js.map +1 -0
- package/dist/backends/firecracker/__tests__/fixtures/ipc-path.d.ts +21 -0
- package/dist/backends/firecracker/__tests__/fixtures/ipc-path.d.ts.map +1 -0
- package/dist/backends/firecracker/__tests__/fixtures/ipc-path.js +30 -0
- package/dist/backends/firecracker/__tests__/fixtures/ipc-path.js.map +1 -0
- package/dist/backends/firecracker/__tests__/protocol.test.js +7 -17
- package/dist/backends/firecracker/__tests__/protocol.test.js.map +1 -1
- package/dist/backends/firecracker/__tests__/transport.test.js +11 -3
- package/dist/backends/firecracker/__tests__/transport.test.js.map +1 -1
- package/dist/backends/firecracker/index.d.ts +20 -1
- package/dist/backends/firecracker/index.d.ts.map +1 -1
- package/dist/backends/firecracker/index.js +60 -15
- package/dist/backends/firecracker/index.js.map +1 -1
- package/dist/egress/__tests__/allowlist.test.d.ts +2 -0
- package/dist/egress/__tests__/allowlist.test.d.ts.map +1 -0
- package/dist/egress/__tests__/allowlist.test.js +85 -0
- package/dist/egress/__tests__/allowlist.test.js.map +1 -0
- package/dist/egress/__tests__/proxy.test.d.ts +2 -0
- package/dist/egress/__tests__/proxy.test.d.ts.map +1 -0
- package/dist/egress/__tests__/proxy.test.js +177 -0
- package/dist/egress/__tests__/proxy.test.js.map +1 -0
- package/dist/egress/allowlist.d.ts +40 -0
- package/dist/egress/allowlist.d.ts.map +1 -0
- package/dist/egress/allowlist.js +81 -0
- package/dist/egress/allowlist.js.map +1 -0
- package/dist/egress/index.d.ts +4 -0
- package/dist/egress/index.d.ts.map +1 -0
- package/dist/egress/index.js +3 -0
- package/dist/egress/index.js.map +1 -0
- package/dist/egress/proxy.d.ts +90 -0
- package/dist/egress/proxy.d.ts.map +1 -0
- package/dist/egress/proxy.js +194 -0
- package/dist/egress/proxy.js.map +1 -0
- package/dist/index.d.ts +101 -190
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -80
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +18 -39
- package/dist/index.test.js.map +1 -1
- package/package.json +5 -4
- package/src/backends/aci-standby-pool/__tests__/unenforceable-controls.test.ts +69 -0
- package/src/backends/aci-standby-pool/index.ts +42 -1
- package/src/backends/docker/__tests__/hardening.test.ts +43 -0
- package/src/backends/docker/__tests__/leaf-permissions.smoke.test.ts +1 -1
- package/src/backends/docker/index.ts +204 -12
- package/src/backends/firecracker/__tests__/agent-timeout-clamp.test.ts +48 -0
- package/src/backends/firecracker/__tests__/backend.test.ts +76 -65
- package/src/backends/firecracker/__tests__/control-plane-mtls.test.ts +10 -2
- package/src/backends/firecracker/__tests__/egress-policy.test.ts +91 -0
- package/src/backends/firecracker/__tests__/fixtures/ipc-path.ts +31 -0
- package/src/backends/firecracker/__tests__/protocol.test.ts +8 -23
- package/src/backends/firecracker/__tests__/transport.test.ts +11 -3
- package/src/backends/firecracker/index.ts +66 -13
- package/src/egress/__tests__/allowlist.test.ts +103 -0
- package/src/egress/__tests__/proxy.test.ts +212 -0
- package/src/egress/allowlist.ts +82 -0
- package/src/egress/index.ts +7 -0
- package/src/egress/proxy.ts +294 -0
- package/src/index.test.ts +19 -41
- package/src/index.ts +170 -259
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { assertEnforceable } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The claim API rejects every property override that is not a config map,
|
|
5
|
+
* so a memory cap, a process cap, environment variables and an egress
|
|
6
|
+
* policy have nowhere to ride through on this backend. They were accepted
|
|
7
|
+
* and dropped: a host that asked for `deny-all` and 512 MB got full
|
|
8
|
+
* outbound network and no cap, with no error and no warning — from the same
|
|
9
|
+
* call shape that IS enforced on the sibling container backend.
|
|
10
|
+
*
|
|
11
|
+
* Switching backends therefore removed the blast-radius controls silently,
|
|
12
|
+
* which is the worst way to lose them. namzu already holds the norm for
|
|
13
|
+
* this next door: a policy accepted and quietly ignored is worse than one
|
|
14
|
+
* that is refused.
|
|
15
|
+
*/
|
|
16
|
+
const opts = (extra = {}) => ({
|
|
17
|
+
workingDirectory: '/w',
|
|
18
|
+
...extra,
|
|
19
|
+
});
|
|
20
|
+
describe('controls this backend cannot apply', () => {
|
|
21
|
+
it.each([
|
|
22
|
+
['an egress policy', { egress: { kind: 'deny-all' } }],
|
|
23
|
+
['a memory limit', { memoryLimitMb: 512 }],
|
|
24
|
+
['a process limit', { maxProcesses: 32 }],
|
|
25
|
+
['environment variables', { env: { SECRET: 'x' } }],
|
|
26
|
+
])('refuses %s', (_name, extra) => {
|
|
27
|
+
expect(() => assertEnforceable(opts(extra))).toThrow(/cannot enforce per-sandbox/);
|
|
28
|
+
});
|
|
29
|
+
it('names every field it cannot honour, not just the first', () => {
|
|
30
|
+
try {
|
|
31
|
+
assertEnforceable(opts({ egress: { kind: 'deny-all' }, memoryLimitMb: 512, maxProcesses: 8 }));
|
|
32
|
+
expect.unreachable();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
const message = err.message;
|
|
36
|
+
// A host fixing one and hitting the next on the following run
|
|
37
|
+
// learns the shape one failure at a time.
|
|
38
|
+
expect(message).toContain('egress');
|
|
39
|
+
expect(message).toContain('memory');
|
|
40
|
+
expect(message).toContain('process');
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
it('says where the limits do belong', () => {
|
|
44
|
+
// Refusing without saying what to do instead is a dead end; these
|
|
45
|
+
// are a property of the pooled profile.
|
|
46
|
+
expect(() => assertEnforceable(opts({ memoryLimitMb: 512 }))).toThrow(/container group profile/);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('what it does allow through', () => {
|
|
50
|
+
it('accepts a request that asks for nothing it cannot apply', () => {
|
|
51
|
+
expect(() => assertEnforceable(opts())).not.toThrow();
|
|
52
|
+
});
|
|
53
|
+
it('accepts a timeout, which is applied by the caller not the pool', () => {
|
|
54
|
+
expect(() => assertEnforceable(opts({ timeoutMs: 30_000 }))).not.toThrow();
|
|
55
|
+
});
|
|
56
|
+
it('treats an empty env bag as asking for nothing', () => {
|
|
57
|
+
// A host spreading an empty object should not be refused for it.
|
|
58
|
+
expect(() => assertEnforceable(opts({ env: {} }))).not.toThrow();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=unenforceable-controls.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unenforceable-controls.test.js","sourceRoot":"","sources":["../../../../src/backends/aci-standby-pool/__tests__/unenforceable-controls.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* chooses; it just PUTs against whichever pool the caller named.
|
|
37
37
|
*/
|
|
38
38
|
import type { ResolvedContainerSandboxLayout } from '@namzu/sdk';
|
|
39
|
-
import type { SandboxBackend } from '../../index.js';
|
|
39
|
+
import type { SandboxBackend, SandboxBackendOptions } from '../../index.js';
|
|
40
40
|
/**
|
|
41
41
|
* Authentication callback. Caller returns a fresh Azure Resource
|
|
42
42
|
* Manager bearer token (audience `https://management.azure.com/`).
|
|
@@ -101,4 +101,5 @@ export interface ACIStandbyPoolBackendInternalConfig {
|
|
|
101
101
|
* the first `create()`.
|
|
102
102
|
*/
|
|
103
103
|
export declare function buildAciStandbyPoolBackend(config: ACIStandbyPoolBackendInternalConfig): SandboxBackend;
|
|
104
|
+
export declare function assertEnforceable(options: SandboxBackendOptions): void;
|
|
104
105
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backends/aci-standby-pool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAEX,8BAA8B,EAQ9B,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backends/aci-standby-pool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAEX,8BAA8B,EAQ9B,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;AAEpD,MAAM,WAAW,mCAAmC;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,+BAA+B,EAAE,MAAM,CAAA;IAChD;;;OAGG;IACH,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAA;IAC/C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAA;IAC/C;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAA;IACtC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CACrC;AASD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,mCAAmC,GACzC,cAAc,CAQhB;AA2LD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CActE"}
|
|
@@ -165,7 +165,42 @@ async function armCall(url, method, getToken, body) {
|
|
|
165
165
|
}
|
|
166
166
|
return undefined;
|
|
167
167
|
}
|
|
168
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Per-sandbox controls this backend cannot express, and must therefore
|
|
170
|
+
* refuse rather than accept.
|
|
171
|
+
*
|
|
172
|
+
* The claim API rejects every property override that is not a config map
|
|
173
|
+
* (see the note in `spawnAciSandbox`), so a memory cap, a process cap,
|
|
174
|
+
* environment variables and an egress policy have nowhere to ride through.
|
|
175
|
+
* They were accepted and dropped: a host that asked for `deny-all` and
|
|
176
|
+
* 512 MB got full outbound network and no cap, with no error and no
|
|
177
|
+
* warning — from the same call shape that IS enforced on the sibling
|
|
178
|
+
* container backend. Switching backends silently removed the
|
|
179
|
+
* blast-radius controls, which is the worst way to lose them.
|
|
180
|
+
*
|
|
181
|
+
* Refusing is the honest fix rather than a missing feature: the limits are
|
|
182
|
+
* a property of the pooled profile, so the answer is to configure them
|
|
183
|
+
* there, not to pretend they can be set per claim.
|
|
184
|
+
*/
|
|
185
|
+
const UNSUPPORTED_PER_SANDBOX_CONTROLS = [
|
|
186
|
+
['egress', 'network egress policy'],
|
|
187
|
+
['memoryLimitMb', 'memory limit'],
|
|
188
|
+
['maxProcesses', 'process limit'],
|
|
189
|
+
['env', 'environment variables'],
|
|
190
|
+
];
|
|
191
|
+
export function assertEnforceable(options) {
|
|
192
|
+
const unenforceable = UNSUPPORTED_PER_SANDBOX_CONTROLS.filter(([key]) => {
|
|
193
|
+
const value = options[key];
|
|
194
|
+
return value !== undefined && (key !== 'env' || Object.keys(value).length > 0);
|
|
195
|
+
});
|
|
196
|
+
if (unenforceable.length === 0)
|
|
197
|
+
return;
|
|
198
|
+
throw new Error(`The standby-pool sandbox backend cannot enforce per-sandbox ${unenforceable
|
|
199
|
+
.map(([, label]) => label)
|
|
200
|
+
.join(', ')}: the pool's claim API rejects every property override except a config map, so these would be accepted and silently dropped. Set them on the container group profile the pool is built from, or use a backend that applies them per sandbox. Refusing rather than silently granting more than was asked for.`);
|
|
201
|
+
}
|
|
202
|
+
async function spawnAciSandbox(config, options) {
|
|
203
|
+
assertEnforceable(options);
|
|
169
204
|
const id = generateSandboxId();
|
|
170
205
|
const prefix = config.containerNamePrefix ?? DEFAULT_CONTAINER_NAME_PREFIX;
|
|
171
206
|
const cgName = `${prefix}-${id
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/backends/aci-standby-pool/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/backends/aci-standby-pool/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AA4EH,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACjC,MAAM,wBAAwB,GAAG,MAAM,CAAA;AACvC,MAAM,mBAAmB,GAAG,IAAI,CAAA;AAChC,MAAM,uBAAuB,GAAG,oBAAoB,CAAA;AACpD,MAAM,QAAQ,GAAG,8BAA8B,CAAA;AAC/C,MAAM,6BAA6B,GAAG,YAAY,CAAA;AAElD;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACzC,MAA2C;IAE3C,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,kBAAkB;QACxB,KAAK,CAAC,MAAM,CAAC,OAA8B;YAC1C,OAAO,MAAM,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC9C,CAAC;KACD,CAAA;AACF,CAAC;AAQD;;;;;;;;;;;GAWG;AACH,SAAS,eAAe,CACvB,MAAmC,EACnC,KAAa;IAEb,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACtC,OAAO;YACN,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE;gBACP,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;gBAC7C,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;aAC3C;SACD,CAAA;IACF,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC3B,CAAC;IACD,MAAM,IAAI,KAAK,CACd,6DAA6D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,8FAA8F,CACnM,CAAA;AACF,CAAC;AAmBD,SAAS,+BAA+B,CAAC,MAAsC;IAC9E,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,MAAM,YAAY,GAAiC,EAAE,CAAA;IACrD,IAAI,OAAO,GAAG,CAAC,CAAA;IAEf,SAAS,GAAG,CACX,KAAuF,EACvF,KAAa,EACb,QAAiB;QAEjB,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACxD,6DAA6D;QAC7D,6DAA6D;QAC7D,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS;YAAE,OAAM;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;QACjC,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,OAAO,EAAE,EAAE,CAAA;QACxC,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI;YACJ,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;gBAC7C,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;gBAC3C,QAAQ;aACR;SACD,CAAC,CAAA;QACF,YAAY,CAAC,IAAI,CAAC;YACjB,IAAI;YACJ,SAAS,EAAE,KAAK,CAAC,aAAa;YAC9B,QAAQ;SACR,CAAC,CAAA;IACH,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IACrC,IAAI,MAAM,CAAC,OAAO;QAAE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;IACxD,IAAI,MAAM,CAAC,OAAO;QAAE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IACzD,IAAI,MAAM,CAAC,WAAW;QAAE,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,CAAA;IACpE,IAAI,MAAM,CAAC,WAAW;QAAE,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,CAAA;IACpE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;QAC7F,CAAC;IACF,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAA;AACjC,CAAC;AAED,SAAS,iBAAiB;IACzB,iEAAiE;IACjE,gEAAgE;IAChE,kEAAkE;IAClE,UAAU;IACV,OAAO,iBAAiB,CAAA;AACzB,CAAC;AAED,IAAI,iBAAiB,GAAG,CAAC,CAAA;AACzB,SAAS,iBAAiB;IACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACnD,iBAAiB,IAAI,CAAC,CAAA;IACtB,OAAO,OAAO,EAAE,IAAI,IAAI,IAAI,iBAAiB,EAAe,CAAA;AAC7D,CAAC;AAED,KAAK,UAAU,OAAO,CACrB,GAAW,EACX,MAAgC,EAChC,QAA0B,EAC1B,IAAc;IAEd,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAgB;QACzB,MAAM;QACN,OAAO,EAAE;YACR,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,kBAAkB;SAClC;KACD,CAAA;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAA;IACjE,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,SAAS,CAAA;IAC9D,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;IAChD,IAAI,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAA;IAC/B,CAAC;IACD,OAAO,SAAS,CAAA;AACjB,CAAC;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,gCAAgC,GAAG;IACxC,CAAC,QAAQ,EAAE,uBAAuB,CAAC;IACnC,CAAC,eAAe,EAAE,cAAc,CAAC;IACjC,CAAC,cAAc,EAAE,eAAe,CAAC;IACjC,CAAC,KAAK,EAAE,uBAAuB,CAAC;CACvB,CAAA;AAEV,MAAM,UAAU,iBAAiB,CAAC,OAA8B;IAC/D,MAAM,aAAa,GAAG,gCAAgC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;QACvE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC1B,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC/E,CAAC,CAAC,CAAA;IACF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAEtC,MAAM,IAAI,KAAK,CACd,+DAA+D,aAAa;SAC1E,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;SACzB,IAAI,CACJ,IAAI,CACJ,8SAA8S,CAChT,CAAA;AACF,CAAC;AAED,KAAK,UAAU,eAAe,CAC7B,MAA2C,EAC3C,OAA8B;IAE9B,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAA;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,IAAI,6BAA6B,CAAA;IAC1E,MAAM,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE;SAC5B,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,WAAW,EAAE;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;IAChB,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,IAAI,uBAAuB,CAAA;IAClE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAA;IAC3D,MAAM,MAAM,GAAG,GAAG,QAAQ,kBAAkB,MAAM,CAAC,cAAc,mBAAmB,MAAM,CAAC,aAAa,0DAA0D,MAAM,gBAAgB,UAAU,EAAE,CAAA;IAEpM,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,+BAA+B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAEhF,gEAAgE;IAChE,iEAAiE;IACjE,iEAAiE;IACjE,4DAA4D;IAC5D,8DAA8D;IAC9D,+DAA+D;IAC/D,iEAAiE;IACjE,qDAAqD;IACrD,MAAM,UAAU,GAA4B;QAC3C,qBAAqB,EAAE;YACtB,EAAE,EAAE,MAAM,CAAC,+BAA+B;YAC1C,QAAQ,EAAE,MAAM,CAAC,6BAA6B,IAAI,CAAC;SACnD;QACD,kBAAkB,EAAE;YACnB,EAAE,EAAE,MAAM,CAAC,qBAAqB;SAChC;QACD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAA;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;QAC5B,UAAU,CAAC,UAAU,GAAG;YACvB;gBACC,IAAI,EAAE,GAAG,MAAM,SAAS;gBACxB,UAAU,EAAE,EAAE,YAAY,EAAE;aAC5B;SACD,CAAA;IACF,CAAC;IAED,MAAM,IAAI,GAA4B;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU;KACV,CAAA;IAED,IAAI,OAAsC,CAAA;IAC1C,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,OAAO,CAAoB,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACpF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACd,iDAAiD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACnG,CAAA;IACF,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAA;IACpD,IAAI,EAAE,GAAG,SAAS,CAAA;IAClB,IAAI,CAAC;QACJ,IAAI,CAAC,EAAE,EAAE,CAAC;YACT,EAAE,GAAG,MAAM,gBAAgB,CAC1B,MAAM,EACN,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,mBAAmB,IAAI,qBAAqB,EACnD,MAAM,CAAC,cAAc,IAAI,wBAAwB,CACjD,CAAA;QACF,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,EAAE,IAAI,UAAU,EAAE,CAAA;QAC5C,MAAM,kBAAkB,CACvB,OAAO,EACP,MAAM,CAAC,cAAc,IAAI,wBAAwB,EACjD,MAAM,CAAC,mBAAmB,IAAI,qBAAqB,CACnD,CAAA;QAED,IAAI,MAAM,GAAkB,OAAO,CAAA;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAA;QAEnD,OAAO;YACN,EAAE;YACF,IAAI,MAAM;gBACT,OAAO,MAAM,CAAA;YACd,CAAC;YACD,OAAO;YACP,WAAW,EAAE,iBAAiB,EAAE;YAEhC,KAAK,CAAC,IAAI,CACT,OAAe,EACf,IAAe,EACf,IAAyB;gBAEzB,MAAM,GAAG,MAAM,CAAA;gBACf,IAAI,CAAC;oBACJ,OAAO,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;gBACzD,CAAC;wBAAS,CAAC;oBACV,MAAM,GAAG,OAAO,CAAA;gBACjB,CAAC;YACF,CAAC;YAED,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,OAAwB;gBACrD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC7E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,aAAa,EAAE;oBAChD,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACpB,IAAI;wBACJ,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC/B,QAAQ,EAAE,QAAQ;qBAClB,CAAC;iBACF,CAAC,CAAA;gBACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;gBAC7E,CAAC;YACF,CAAC;YAED,KAAK,CAAC,QAAQ,CAAC,IAAY;gBAC1B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,YAAY,EAAE;oBAC/C,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;iBAClD,CAAC,CAAA;gBACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;gBAC5E,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsD,CAAA;gBACpF,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAClD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAA;gBACvD,CAAC;gBACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YAC3C,CAAC;YAED,KAAK,CAAC,SAAS,CAAC,QAAgB;gBAC/B,OAAO,MAAM,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YACnD,CAAC;YAED,KAAK,CAAC,OAAO;gBACZ,MAAM,GAAG,WAAW,CAAA;gBACpB,uDAAuD;gBACvD,0DAA0D;gBAC1D,sDAAsD;gBACtD,yDAAyD;gBACzD,2DAA2D;gBAC3D,uDAAuD;gBACvD,2DAA2D;gBAC3D,4BAA4B;gBAC5B,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;YACpD,CAAC;SACD,CAAA;IACF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QACpD,CAAC;QAAC,MAAM,CAAC;YACR,2DAA2D;YAC3D,6DAA6D;YAC7D,4DAA4D;QAC7D,CAAC;QACD,MAAM,GAAG,CAAA;IACV,CAAC;AACF,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,MAAc,EACd,QAA0B,EAC1B,cAAsB,EACtB,SAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACvC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,OAAO,CAAoB,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;QACpE,MAAM,KAAK,GAAG,EAAE,EAAE,UAAU,EAAE,iBAAiB,CAAA;QAC/C,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAA;QACxC,IAAI,KAAK,KAAK,WAAW,IAAI,EAAE;YAAE,OAAO,EAAE,CAAA;QAC1C,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;QACzE,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAA;IACxD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,+DAA+D,SAAS,KAAK,CAAC,CAAA;AAC/F,CAAC;AAED,KAAK,UAAU,kBAAkB,CAChC,OAAe,EACf,SAAiB,EACjB,cAAsB;IAEtB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACvC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,UAAU,EAAE;gBAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;aACjC,CAAC,CAAA;YACF,IAAI,GAAG,CAAC,EAAE;gBAAE,OAAM;QACnB,CAAC;QAAC,MAAM,CAAC;YACR,oCAAoC;QACrC,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAA;IACxD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sDAAsD,SAAS,KAAK,CAAC,CAAA;AACtF,CAAC;AAED,KAAK,UAAU,aAAa,CAC3B,OAAe,EACf,OAAe,EACf,IAA0B,EAC1B,IAAoC;IAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,UAAU,EAAE;QAC7C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACpB,OAAO;YACP,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,GAAG,EAAE,IAAI,EAAE,GAAG;YACd,GAAG,EAAE,IAAI,EAAE,GAAG;YACd,SAAS,EAAE,IAAI,EAAE,OAAO;SACxB,CAAC;KACF,CAAC,CAAA;IACF,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAC1E,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAA;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA;IACnC,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,SAAS,CAAC;QACT,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QAC3C,IAAI,IAAI;YAAE,MAAK;QACf,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACnD,IAAI,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;YACjD,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;YACzC,IAAI,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC;oBACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAIM,CAAA;oBACnC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;wBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAA;yBAClD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;wBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAA;yBACvD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAClC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;wBACzB,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;oBAC1B,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBACnC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBAC7B,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC,CAAC,GAAG,YAAY,WAAW,CAAC;wBAAE,MAAM,GAAG,CAAA;gBAC7C,CAAC;YACF,CAAC;YACD,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACpC,CAAC;IACF,CAAC;IAED,OAAO;QACN,MAAM;QACN,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;KACT,CAAA;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,kBAAkB,CAChC,OAAe,EACf,QAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,aAAa,CACjC,OAAO,EACP,MAAM,EACN,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,EAC/C,SAAS,CACT,CAAA;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAA;IACV,CAAC;IACD,MAAM,OAAO,GAAuB,EAAE,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,OAAO;YAAE,SAAQ;QACtB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,GAAG,GAAG,CAAC;YAAE,SAAQ;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC7C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,OAAO,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardening.test.d.ts","sourceRoot":"","sources":["../../../../src/backends/docker/__tests__/hardening.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { resolveNetwork } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* `EgressPolicy` was accepted by the type, threaded through the options,
|
|
5
|
+
* and silently ignored by this backend. That is worse than not supporting
|
|
6
|
+
* it: a host that set `deny-all` believed the container had no network,
|
|
7
|
+
* and it had whatever `config.network` said.
|
|
8
|
+
*/
|
|
9
|
+
describe('resolveNetwork', () => {
|
|
10
|
+
it('leaves the configured network alone when no policy is supplied', () => {
|
|
11
|
+
expect(resolveNetwork('bridge', undefined)).toBe('bridge');
|
|
12
|
+
});
|
|
13
|
+
it('enforces deny-all natively', () => {
|
|
14
|
+
// Docker can actually do this one, so there is no excuse for
|
|
15
|
+
// accepting the policy and ignoring it.
|
|
16
|
+
expect(resolveNetwork('bridge', { kind: 'deny-all' })).toBe('none');
|
|
17
|
+
});
|
|
18
|
+
it('allow-all keeps the configured network', () => {
|
|
19
|
+
expect(resolveNetwork('my-bridge', { kind: 'allow-all' })).toBe('my-bridge');
|
|
20
|
+
});
|
|
21
|
+
it('REFUSES a host allowlist rather than silently granting full access', () => {
|
|
22
|
+
// This backend has no proxy to filter through. Downgrading a
|
|
23
|
+
// restrictive policy to "allow everything" is the failure mode that
|
|
24
|
+
// makes a security control worse than useless.
|
|
25
|
+
expect(() => resolveNetwork('bridge', { kind: 'static', allowedHosts: ['example.com'] })).toThrow(/cannot enforce an egress policy/);
|
|
26
|
+
expect(() => resolveNetwork('bridge', { kind: 'resolver', resolve: async () => [] })).toThrow(/cannot enforce an egress policy/);
|
|
27
|
+
});
|
|
28
|
+
it('names what it can do, so the failure is actionable', () => {
|
|
29
|
+
expect(() => resolveNetwork('bridge', { kind: 'static', allowedHosts: [] })).toThrow(/deny-all/);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=hardening.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardening.test.js","sourceRoot":"","sources":["../../../../src/backends/docker/__tests__/hardening.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;;;;GAKG;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACrC,6DAA6D;QAC7D,wCAAwC;QACxC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC7E,6DAA6D;QAC7D,oEAAoE;QACpE,+CAA+C;QAC/C,MAAM,CAAC,GAAG,EAAE,CACX,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAC3E,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAA;QAE5C,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAC5F,iCAAiC,CACjC,CAAA;IACF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACjG,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Docker smoke test — leaf-mount permission semantics.
|
|
3
3
|
*
|
|
4
|
-
* Concern
|
|
4
|
+
* Concern raised in review: the Dockerfile pre-creates only the parent
|
|
5
5
|
* dirs (`/mnt`, `/mnt/user-data`, `/mnt/skills`) as root-owned 0555.
|
|
6
6
|
* The runtime claim is that:
|
|
7
7
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Docker smoke test — leaf-mount permission semantics.
|
|
3
3
|
*
|
|
4
|
-
* Concern
|
|
4
|
+
* Concern raised in review: the Dockerfile pre-creates only the parent
|
|
5
5
|
* dirs (`/mnt`, `/mnt/user-data`, `/mnt/skills`) as root-owned 0555.
|
|
6
6
|
* The runtime claim is that:
|
|
7
7
|
*
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* the egress proxy when one is configured (P3.2).
|
|
22
22
|
*/
|
|
23
23
|
import { type ContainerSandboxLayout, type ResolvedContainerSandboxLayout } from '@namzu/sdk';
|
|
24
|
-
import {
|
|
24
|
+
import type { BrokeredCredential } from '../../egress/index.js';
|
|
25
|
+
import { type EgressPolicy, type SandboxBackend } from '../../index.js';
|
|
25
26
|
/**
|
|
26
27
|
* Backend-specific tuning. Most hosts use the defaults; advanced
|
|
27
28
|
* deployments override `image` to point at their own pre-built
|
|
@@ -43,6 +44,27 @@ export interface DockerBackendInternalConfig {
|
|
|
43
44
|
*/
|
|
44
45
|
readonly layout: ResolvedContainerSandboxLayout;
|
|
45
46
|
readonly dockerBinary?: string;
|
|
47
|
+
/**
|
|
48
|
+
* `--user` value for the container, e.g. `'1000:1000'` or `'nobody'`.
|
|
49
|
+
*
|
|
50
|
+
* Left unset by default because the correct uid depends on the image's
|
|
51
|
+
* own filesystem ownership, and forcing one would break every image
|
|
52
|
+
* that expects root at startup. Set it whenever the image supports a
|
|
53
|
+
* non-root user — a container running as root is one bind-mount
|
|
54
|
+
* misconfiguration away from writing the host.
|
|
55
|
+
*/
|
|
56
|
+
readonly runAsUser?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Credentials the egress proxy stamps on, per host.
|
|
59
|
+
*
|
|
60
|
+
* The point is that the real value never enters the sandbox. Any token
|
|
61
|
+
* the agent needs to reach an allowed host used to have to be in the
|
|
62
|
+
* container's environment — readable by the untrusted code it is meant
|
|
63
|
+
* to be isolated from, via `/proc/self/environ` or via a prompt
|
|
64
|
+
* injection that exfiltrates it over the very egress the policy
|
|
65
|
+
* permits. Here it is held host-side and applied at the boundary.
|
|
66
|
+
*/
|
|
67
|
+
readonly brokeredCredentials?: readonly BrokeredCredential[];
|
|
46
68
|
readonly network?: 'none' | 'bridge' | string;
|
|
47
69
|
readonly readyPollIntervalMs?: number;
|
|
48
70
|
readonly readyTimeoutMs?: number;
|
|
@@ -51,8 +73,8 @@ export interface DockerBackendInternalConfig {
|
|
|
51
73
|
* (vanilla Docker namespaces, what Docker Desktop ships). Linux
|
|
52
74
|
* production deployments that have registered gVisor on the host
|
|
53
75
|
* daemon can pass `runsc` to upgrade to a userspace-kernel trust
|
|
54
|
-
* boundary —
|
|
55
|
-
*
|
|
76
|
+
* boundary — the usual primitive for running untrusted code at
|
|
77
|
+
* scale. Hosts can also pass a custom runtime name registered in
|
|
56
78
|
* `daemon.json`. macOS Docker Desktop has no `runsc` runtime, so
|
|
57
79
|
* the default `runc` is the only option there; that's documented
|
|
58
80
|
* as the local-dev tier in the package README.
|
|
@@ -92,6 +114,28 @@ export interface DockerBackendInternalConfig {
|
|
|
92
114
|
* `create()` call.
|
|
93
115
|
*/
|
|
94
116
|
export declare function buildDockerBackend(config: DockerBackendInternalConfig): SandboxBackend;
|
|
117
|
+
/**
|
|
118
|
+
* Reconcile the configured docker network with the caller's egress policy.
|
|
119
|
+
*
|
|
120
|
+
* The policy used to be accepted and silently ignored, which is worse than
|
|
121
|
+
* not supporting it: a host that set `deny-all` believed the container had
|
|
122
|
+
* no network and it had the configured one. Docker can enforce `deny-all`
|
|
123
|
+
* natively (`--network none`); it cannot enforce a host allowlist without
|
|
124
|
+
* a proxy this backend does not have, so those policies are REFUSED rather
|
|
125
|
+
* than quietly downgraded to "allow everything".
|
|
126
|
+
*/
|
|
127
|
+
export declare function resolveNetwork(configured: string, egress: EgressPolicy | undefined, hasProxy?: boolean): string;
|
|
128
|
+
/**
|
|
129
|
+
* Hosts an allowlist policy permits.
|
|
130
|
+
*
|
|
131
|
+
* Only the two filtering kinds reach here. `deny-all` is enforced by the
|
|
132
|
+
* container runtime itself and `allow-all` needs no boundary, so routing
|
|
133
|
+
* either through an allowlist would answer a question nobody asked — and
|
|
134
|
+
* for `allow-all` it would answer "nothing", denying everything.
|
|
135
|
+
*/
|
|
136
|
+
export declare function resolveAllowedHosts(egress: EgressPolicy): Promise<readonly string[]>;
|
|
137
|
+
/** Whether a policy needs a boundary before it can be enforced at all. */
|
|
138
|
+
export declare function needsEgressProxy(egress: EgressPolicy | undefined): boolean;
|
|
95
139
|
/**
|
|
96
140
|
* Validate and resolve a {@link ContainerSandboxLayout}. Returns a
|
|
97
141
|
* {@link ResolvedContainerSandboxLayout} with every container path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backends/docker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EACN,KAAK,sBAAsB,EAE3B,KAAK,8BAA8B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backends/docker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EACN,KAAK,sBAAsB,EAE3B,KAAK,8BAA8B,EAenC,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,uBAAuB,CAAA;AAEnF,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,cAAc,EAEnB,MAAM,gBAAgB,CAAA;AAEvB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAA;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAE9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAE3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAE5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC7C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;IAC5C;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAAA;IAC7D;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAClD;AAOD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,2BAA2B,GAAG,cAAc,CAQtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,QAAQ,UAAQ,GACd,MAAM,CAmBR;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAM1F;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,CAE1E;AAsjBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,8BAA8B,CAmI5F;AAkCD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,EAAE,CA+BtF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CAUvF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CAKxF"}
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* the egress proxy when one is configured (P3.2).
|
|
22
22
|
*/
|
|
23
23
|
import { spawn } from 'node:child_process';
|
|
24
|
-
import { SANDBOX_DEFAULT_OUTPUTS_PATH, SANDBOX_DEFAULT_SCRATCH_PATH, SANDBOX_DEFAULT_SKILLS_PARENT, SANDBOX_DEFAULT_TOOL_RESULTS_PATH, SANDBOX_DEFAULT_TRANSCRIPTS_PATH, SANDBOX_DEFAULT_UPLOADS_PATH, } from '@namzu/sdk';
|
|
24
|
+
import { SANDBOX_DEFAULT_OUTPUTS_PATH, SANDBOX_DEFAULT_SCRATCH_PATH, SANDBOX_DEFAULT_SKILLS_PARENT, SANDBOX_DEFAULT_TOOL_RESULTS_PATH, SANDBOX_DEFAULT_TRANSCRIPTS_PATH, SANDBOX_DEFAULT_UPLOADS_PATH, withHint, } from '@namzu/sdk';
|
|
25
|
+
import { EgressProxy } from '../../egress/index.js';
|
|
25
26
|
import { ContainerSandboxLayoutValidationError, } from '../../index.js';
|
|
26
27
|
const DEFAULT_DOCKER_BINARY = 'docker';
|
|
27
28
|
const DEFAULT_READY_POLL_MS = 100;
|
|
@@ -41,11 +42,91 @@ export function buildDockerBackend(config) {
|
|
|
41
42
|
},
|
|
42
43
|
};
|
|
43
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Reconcile the configured docker network with the caller's egress policy.
|
|
47
|
+
*
|
|
48
|
+
* The policy used to be accepted and silently ignored, which is worse than
|
|
49
|
+
* not supporting it: a host that set `deny-all` believed the container had
|
|
50
|
+
* no network and it had the configured one. Docker can enforce `deny-all`
|
|
51
|
+
* natively (`--network none`); it cannot enforce a host allowlist without
|
|
52
|
+
* a proxy this backend does not have, so those policies are REFUSED rather
|
|
53
|
+
* than quietly downgraded to "allow everything".
|
|
54
|
+
*/
|
|
55
|
+
export function resolveNetwork(configured, egress, hasProxy = false) {
|
|
56
|
+
if (!egress)
|
|
57
|
+
return configured;
|
|
58
|
+
switch (egress.kind) {
|
|
59
|
+
case 'deny-all':
|
|
60
|
+
return 'none';
|
|
61
|
+
case 'allow-all':
|
|
62
|
+
return configured;
|
|
63
|
+
default:
|
|
64
|
+
// A host allowlist needs something to filter through. With the
|
|
65
|
+
// egress proxy the container keeps its network and every request
|
|
66
|
+
// crosses that boundary; without one there is nothing to enforce
|
|
67
|
+
// with, and accepting the policy would grant everything while
|
|
68
|
+
// reporting that it had been restricted.
|
|
69
|
+
if (hasProxy)
|
|
70
|
+
return configured;
|
|
71
|
+
throw new Error(`The docker sandbox backend cannot enforce an egress policy of kind '${egress.kind}' without an egress proxy: it has nothing to filter hosts through. Construct the provider with one, or use 'deny-all' / 'allow-all'. Refusing rather than silently granting full network access.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Hosts an allowlist policy permits.
|
|
76
|
+
*
|
|
77
|
+
* Only the two filtering kinds reach here. `deny-all` is enforced by the
|
|
78
|
+
* container runtime itself and `allow-all` needs no boundary, so routing
|
|
79
|
+
* either through an allowlist would answer a question nobody asked — and
|
|
80
|
+
* for `allow-all` it would answer "nothing", denying everything.
|
|
81
|
+
*/
|
|
82
|
+
export async function resolveAllowedHosts(egress) {
|
|
83
|
+
if (egress.kind === 'static')
|
|
84
|
+
return egress.allowedHosts;
|
|
85
|
+
if (egress.kind === 'resolver')
|
|
86
|
+
return await egress.resolve();
|
|
87
|
+
throw new Error(`Egress policy of kind "${egress.kind}" does not describe a host allowlist and must not be routed through the proxy.`);
|
|
88
|
+
}
|
|
89
|
+
/** Whether a policy needs a boundary before it can be enforced at all. */
|
|
90
|
+
export function needsEgressProxy(egress) {
|
|
91
|
+
return egress?.kind === 'static' || egress?.kind === 'resolver';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Confinement flags applied to every container.
|
|
95
|
+
*
|
|
96
|
+
* A sandbox whose containers run as root with the full default capability
|
|
97
|
+
* set is not confining much: `CAP_DAC_OVERRIDE` alone walks past the
|
|
98
|
+
* read-only bind mounts the layout sets up, and without
|
|
99
|
+
* `no-new-privileges` a setuid binary inside the image re-escalates. These
|
|
100
|
+
* are the defaults every container runtime hardening guide starts with,
|
|
101
|
+
* and none of them were present.
|
|
102
|
+
*
|
|
103
|
+
* `--cap-drop=ALL` is deliberately not softened by a re-add list: a
|
|
104
|
+
* workload that genuinely needs a capability should say so through
|
|
105
|
+
* `extraRunArgs` and be visible in review.
|
|
106
|
+
*/
|
|
107
|
+
const HARDENING_ARGS = ['--cap-drop=ALL', '--security-opt=no-new-privileges'];
|
|
108
|
+
/** Name the container reaches the host-side egress proxy by. */
|
|
109
|
+
const PROXY_HOST_ALIAS = 'namzu-egress';
|
|
44
110
|
async function spawnDockerSandbox(config, options) {
|
|
45
111
|
const resolvedLayout = config.layout;
|
|
46
112
|
const id = generateSandboxId();
|
|
47
113
|
const docker = config.dockerBinary ?? DEFAULT_DOCKER_BINARY;
|
|
48
|
-
|
|
114
|
+
// The boundary a host allowlist is actually enforced at. Started before
|
|
115
|
+
// the container so its address can be handed in as proxy environment,
|
|
116
|
+
// and torn down with the sandbox — a proxy holding real credentials
|
|
117
|
+
// must not outlive the thing it was filtering for.
|
|
118
|
+
let egressProxy;
|
|
119
|
+
if (needsEgressProxy(options.egress) && options.egress) {
|
|
120
|
+
const policy = options.egress;
|
|
121
|
+
egressProxy = await new EgressProxy({
|
|
122
|
+
// Re-resolved per request rather than captured once, so a
|
|
123
|
+
// `resolver` policy that rotates is honoured and
|
|
124
|
+
// `setNetworkPolicy` can swap it on a live sandbox.
|
|
125
|
+
allowedHosts: () => resolveAllowedHosts(policy),
|
|
126
|
+
credentials: config.brokeredCredentials ?? [],
|
|
127
|
+
}).listen();
|
|
128
|
+
}
|
|
129
|
+
const network = resolveNetwork(config.network ?? 'none', options.egress, egressProxy !== undefined);
|
|
49
130
|
const runtime = config.runtime;
|
|
50
131
|
const hostReachability = config.hostReachability ?? 'host-port';
|
|
51
132
|
const containerName = `namzu-sandbox-${id}`;
|
|
@@ -60,6 +141,17 @@ async function spawnDockerSandbox(config, options) {
|
|
|
60
141
|
if (containerStarted) {
|
|
61
142
|
await runOnceQuiet(docker, ['rm', '-f', containerName]);
|
|
62
143
|
}
|
|
144
|
+
// The proxy starts BEFORE the container and its only other close is
|
|
145
|
+
// in `destroy()`, which a create that never returned can never
|
|
146
|
+
// reach. So every failure between the two — a daemon that is down, a
|
|
147
|
+
// port that could not be read, a worker that missed its readiness
|
|
148
|
+
// deadline, a label the validator rejected — left a listening server
|
|
149
|
+
// on loopback stamping real credential headers, plus a retained
|
|
150
|
+
// event-loop handle, and a retry loop left one per attempt. That is
|
|
151
|
+
// exactly the invariant this file states where the proxy is started:
|
|
152
|
+
// it must not outlive the thing it was filtering for.
|
|
153
|
+
await egressProxy?.close().catch(() => undefined);
|
|
154
|
+
egressProxy = undefined;
|
|
63
155
|
}
|
|
64
156
|
let hostPort;
|
|
65
157
|
let baseUrl;
|
|
@@ -81,6 +173,8 @@ async function spawnDockerSandbox(config, options) {
|
|
|
81
173
|
containerName,
|
|
82
174
|
'--network',
|
|
83
175
|
network,
|
|
176
|
+
...HARDENING_ARGS,
|
|
177
|
+
...(config.runAsUser ? ['--user', config.runAsUser] : []),
|
|
84
178
|
];
|
|
85
179
|
// `--label key=value` flags. Validate first — an empty key or
|
|
86
180
|
// a key containing `=` would silently produce a malformed
|
|
@@ -104,6 +198,24 @@ async function spawnDockerSandbox(config, options) {
|
|
|
104
198
|
// log line. A skill loader that needs the manifest will
|
|
105
199
|
// write it to a bind path the worker reads at startup —
|
|
106
200
|
// avoids env-size limits, keeps the wire shape minimal.
|
|
201
|
+
if (egressProxy) {
|
|
202
|
+
// `host-gateway` is docker's own portable name for the host from
|
|
203
|
+
// inside a container; hard-coding a bridge address would break on
|
|
204
|
+
// every platform whose bridge is numbered differently. The proxy
|
|
205
|
+
// itself binds loopback, so this alias is the only way in.
|
|
206
|
+
args.push('--add-host', `${PROXY_HOST_ALIAS}:host-gateway`);
|
|
207
|
+
const proxyUrl = `http://${PROXY_HOST_ALIAS}:${egressProxy.port}`;
|
|
208
|
+
// Both spellings: tooling is split between them, and a workload
|
|
209
|
+
// that reads only the one that is missing bypasses the boundary
|
|
210
|
+
// entirely — which would look exactly like the policy working.
|
|
211
|
+
for (const key of ['HTTP_PROXY', 'http_proxy', 'HTTPS_PROXY', 'https_proxy']) {
|
|
212
|
+
args.push('--env', `${key}=${proxyUrl}`);
|
|
213
|
+
}
|
|
214
|
+
// Loopback must not be proxied, or the worker cannot talk to
|
|
215
|
+
// itself.
|
|
216
|
+
args.push('--env', 'NO_PROXY=localhost,127.0.0.1');
|
|
217
|
+
args.push('--env', 'no_proxy=localhost,127.0.0.1');
|
|
218
|
+
}
|
|
107
219
|
args.push('--env', `NAMZU_SANDBOX_WORKSPACE=${rootDir}`);
|
|
108
220
|
args.push('--env', `NAMZU_SANDBOX_READ_ROOTS=${renderLayoutReadRootsEnv(resolvedLayout)}`);
|
|
109
221
|
args.push('--env', `NAMZU_SANDBOX_WRITE_ROOTS=${renderLayoutWriteRootsEnv(resolvedLayout)}`);
|
|
@@ -164,6 +276,18 @@ async function spawnDockerSandbox(config, options) {
|
|
|
164
276
|
status = 'ready';
|
|
165
277
|
}
|
|
166
278
|
},
|
|
279
|
+
async setNetworkPolicy(policy) {
|
|
280
|
+
// Enforceable only through the egress proxy. Without one the
|
|
281
|
+
// container's network was fixed at creation — `--network none`
|
|
282
|
+
// or not — and there is nothing to narrow: accepting the policy
|
|
283
|
+
// here and doing nothing would leave the caller believing the
|
|
284
|
+
// sandbox had been confined when it had not. Same rule the
|
|
285
|
+
// egress-kind refusal above follows.
|
|
286
|
+
if (!egressProxy) {
|
|
287
|
+
throw withHint(new Error('This sandbox cannot change its network policy: it was created without an egress proxy, so its network was fixed at creation and there is nothing to narrow. Refusing rather than accepting a policy that would not be applied.'), 'Construct the provider with an egress proxy to make the policy mutable, or create a second sandbox under the narrower policy.');
|
|
288
|
+
}
|
|
289
|
+
egressProxy.setAllowedHosts(async () => policy.allowedHosts);
|
|
290
|
+
},
|
|
167
291
|
async writeFile(path, content) {
|
|
168
292
|
const buf = Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8');
|
|
169
293
|
let res;
|
|
@@ -212,6 +336,11 @@ async function spawnDockerSandbox(config, options) {
|
|
|
212
336
|
async destroy() {
|
|
213
337
|
status = 'destroyed';
|
|
214
338
|
await runOnceQuiet(docker, ['rm', '-f', containerName]);
|
|
339
|
+
// The proxy holds real credentials and a live allowlist. Leaving
|
|
340
|
+
// it listening after the sandbox it was filtering for is gone
|
|
341
|
+
// means a loopback port that still stamps a token onto anything
|
|
342
|
+
// that asks — outliving the only thing that justified it.
|
|
343
|
+
await egressProxy?.close();
|
|
215
344
|
// Backend never allocates host paths — every bind source
|
|
216
345
|
// comes from the consumer-supplied layout. Container
|
|
217
346
|
// teardown is sufficient; the consumer's own lifecycle
|
|
@@ -236,7 +365,7 @@ async function readMappedPort(docker, containerName) {
|
|
|
236
365
|
]);
|
|
237
366
|
const port = Number(inspectOutput.trim());
|
|
238
367
|
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
239
|
-
throw new Error(`docker inspect returned no usable host port mapping for ${containerName}: '${inspectOutput}'`);
|
|
368
|
+
throw withHint(new Error(`docker inspect returned no usable host port mapping for ${containerName}: '${inspectOutput}'`), 'The container started but its worker port was never published. Usually the container exited immediately — check its logs — or the host had no free port to bind.');
|
|
240
369
|
}
|
|
241
370
|
return port;
|
|
242
371
|
}
|
|
@@ -267,7 +396,7 @@ async function execViaWorker(baseUrl, command, argv, opts) {
|
|
|
267
396
|
: cause
|
|
268
397
|
? String(cause)
|
|
269
398
|
: 'unknown';
|
|
270
|
-
throw new Error(`namzu-sandbox /execute fetch failed (baseUrl=${baseUrl}): ${err instanceof Error ? err.message : String(err)} — cause: ${causeMsg}`, { cause: err });
|
|
399
|
+
throw withHint(new Error(`namzu-sandbox /execute fetch failed (baseUrl=${baseUrl}): ${err instanceof Error ? err.message : String(err)} — cause: ${causeMsg}`, { cause: err }), 'The container was reachable when it started, so it has most likely exited or been killed since — an out-of-memory kill under `memoryLimitMb` is the common cause. Check the container logs and its exit code.');
|
|
271
400
|
}
|
|
272
401
|
if (!res.ok || !res.body) {
|
|
273
402
|
throw new Error(`execute failed: HTTP ${res.status} ${await res.text()}`);
|
|
@@ -385,7 +514,11 @@ async function waitForWorkerReady(baseUrl, timeoutMs, pollMs) {
|
|
|
385
514
|
}
|
|
386
515
|
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
387
516
|
}
|
|
388
|
-
|
|
517
|
+
// A hint attached at the throw site, where the cause is actually known.
|
|
518
|
+
// The container runtime's own message says a request failed; it cannot
|
|
519
|
+
// say that the image may not be built or the daemon may not be running,
|
|
520
|
+
// which is what a reader needs.
|
|
521
|
+
throw withHint(new Error(`namzu-sandbox worker did not become ready within ${timeoutMs}ms: ${lastError instanceof Error ? lastError.message : String(lastError)}`), 'Check that the container runtime is running and that the sandbox worker image is built and reachable. A cold image pull can also exceed this window — raise the readiness timeout before assuming the worker is broken.');
|
|
389
522
|
}
|
|
390
523
|
function runOnce(binary, args) {
|
|
391
524
|
return new Promise((resolve, reject) => {
|