@namzu/sandbox 1.1.0 → 2.0.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/CHANGELOG.md +277 -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 +144 -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 +70 -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 +210 -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 +76 -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
package/dist/index.d.ts
CHANGED
|
@@ -1,69 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @namzu/sandbox — pluggable
|
|
3
|
-
*
|
|
4
|
-
* The SDK
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* commodity Linux without nested virt. Locally via Linux Docker
|
|
36
|
-
* runtime; not available on macOS Docker Desktop.
|
|
37
|
-
*
|
|
38
|
-
* • `passthrough` — no isolation, runs commands directly. For
|
|
39
|
-
* tests and trusted environments only. Off by default; opt-in.
|
|
40
|
-
*
|
|
41
|
-
* **What we deliberately do NOT build** is yet-another Firecracker
|
|
42
|
-
* scheduler — that is E2B's and Fly's entire product, and writing
|
|
43
|
-
* our own is a years-long detour. We adapt to theirs.
|
|
44
|
-
*
|
|
45
|
-
* **Cloud portability:** the backend interface is cloud-agnostic.
|
|
46
|
-
* `docker` works on every cloud; `e2b` and `fly-machines` are
|
|
47
|
-
* managed services not tied to any cloud; `firecracker` and
|
|
48
|
-
* `gvisor` need infrastructure the host chooses (GKE Sandbox, AWS
|
|
49
|
-
* Fargate, self-hosted KVM, etc.). Picking a stronger backend may
|
|
50
|
-
* imply moving cloud — that's the host's call, not the SDK's.
|
|
51
|
-
*
|
|
52
|
-
* **Local dev story:** Phase 1 (`docker`) runs everywhere. Phase 2
|
|
53
|
-
* (`e2b` / `fly-machines`) hits the managed service from a dev
|
|
54
|
-
* laptop with no infra setup. Phase 3 (`firecracker` / `gvisor`)
|
|
55
|
-
* needs Lima/Colima on macOS or native KVM on Linux — only the
|
|
56
|
-
* adversarial-multi-tenant prod path needs that and it's clearly
|
|
57
|
-
* documented as such.
|
|
58
|
-
*
|
|
59
|
-
* This file is the public surface. Concrete backend implementations
|
|
60
|
-
* land under `./backends/<kind>/` in subsequent commits — the
|
|
61
|
-
* `SandboxBackend` interface here is the contract they implement.
|
|
62
|
-
*
|
|
63
|
-
* Refs: `e2b.dev/docs/sandbox`, `fly.io/docs/machines`,
|
|
64
|
-
* `firecracker-microvm.github.io`, `gvisor.dev/docs`,
|
|
65
|
-
* `cloud.google.com/kubernetes-engine/docs/concepts/sandbox-pods`,
|
|
66
|
-
* `aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing`.
|
|
2
|
+
* @namzu/sandbox — pluggable containment for @namzu/sdk.
|
|
3
|
+
*
|
|
4
|
+
* The SDK declares the `SandboxProvider` shape
|
|
5
|
+
* (`packages/sdk/src/types/sandbox/index.ts`); this package implements
|
|
6
|
+
* it with concrete BACKENDS chosen at construction time. A backend is
|
|
7
|
+
* named for the mechanism it drives, because that is what it has to
|
|
8
|
+
* speak on the wire — never for a system whose ideas it borrowed.
|
|
9
|
+
*
|
|
10
|
+
* Two tiers, each a trust boundary:
|
|
11
|
+
*
|
|
12
|
+
* • `container` — one OCI container per task, seccomp on, tmpfs
|
|
13
|
+
* workdir, no network unless asked. The same path on a laptop and
|
|
14
|
+
* on a Linux replica anywhere. The tier for trusted prompts and
|
|
15
|
+
* contained workloads. Boundary: kernel namespaces, or a
|
|
16
|
+
* userspace-kernel runtime where one is installed.
|
|
17
|
+
*
|
|
18
|
+
* • `microvm` — one hardware-virtualized guest per task. The boundary
|
|
19
|
+
* to reach for when the prompt itself is adversarial, at the cost
|
|
20
|
+
* of running or renting the machinery that starts them.
|
|
21
|
+
*
|
|
22
|
+
* Every shape in {@link SandboxBackendConfig} has a backend behind it,
|
|
23
|
+
* which used not to be true: a `process` tier, a `passthrough` tier and
|
|
24
|
+
* two adapters to third-party schedulers were declared here and never
|
|
25
|
+
* written, so four of the shapes this package offered could only ever
|
|
26
|
+
* type-check and then throw. They are gone rather than pending.
|
|
27
|
+
* Confining an agent to the operator's own host is the SDK's local
|
|
28
|
+
* sandbox provider, which is implemented; a host that wants no
|
|
29
|
+
* confinement configures no sandbox.
|
|
30
|
+
*
|
|
31
|
+
* namzu does not build its own microVM scheduler. That is a years-long
|
|
32
|
+
* detour from an agent kernel, and the boundary a guest gives is the
|
|
33
|
+
* same whoever started it — so the microvm tier is an interface to a
|
|
34
|
+
* scheduler, not a scheduler.
|
|
67
35
|
*/
|
|
68
36
|
import type { ContainerSandboxLayout, Sandbox, SandboxProvider } from '@namzu/sdk';
|
|
69
37
|
export type { ContainerSandboxLayout, ContainerSandboxLayoutMount, ContainerSandboxMountSource, ContainerSandboxSkillMount, ResolvedContainerSandboxLayout, } from '@namzu/sdk';
|
|
@@ -71,48 +39,40 @@ export { SANDBOX_DEFAULT_OUTPUTS_PATH, SANDBOX_DEFAULT_SKILLS_PARENT, SANDBOX_DE
|
|
|
71
39
|
export type { FirecrackerBackendInternalConfig, OrchestratorTokenProvider, } from './backends/firecracker/index.js';
|
|
72
40
|
export { type SandboxAgentHandle, type VsockTransportOptions, VsockAgentTransport, } from './backends/firecracker/transport.js';
|
|
73
41
|
/**
|
|
74
|
-
* Top-level sandbox tier
|
|
75
|
-
*
|
|
76
|
-
* - `
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* per task. Hardware-virtualization trust boundary; the
|
|
90
|
-
* industry standard for adversarial multi-tenancy
|
|
91
|
-
* (AWS Lambda/Fargate, Fly Machines, Replit, E2B, Daytona
|
|
92
|
-
* all converged here). Sub-second cold-start via
|
|
93
|
-
* snapshot/restore.
|
|
94
|
-
*
|
|
95
|
-
* - `passthrough` — no isolation; for tests and explicitly
|
|
96
|
-
* trusted environments.
|
|
42
|
+
* Top-level sandbox tier, and the trust boundary it buys:
|
|
43
|
+
*
|
|
44
|
+
* - `container` — one OCI container per task. Namespaces. The
|
|
45
|
+
* default for trusted prompts and contained workloads, and the
|
|
46
|
+
* same code path on a laptop and on a Linux replica anywhere.
|
|
47
|
+
*
|
|
48
|
+
* - `microvm` — one hardware-virtualized guest per task. The
|
|
49
|
+
* boundary to reach for when the prompt itself is adversarial.
|
|
50
|
+
*
|
|
51
|
+
* Two tiers, not four. A `process` tier and a `passthrough` tier were
|
|
52
|
+
* declared here and never built: every construction threw, so the
|
|
53
|
+
* only thing they offered a caller was a shape that compiles and an
|
|
54
|
+
* exception at runtime. Confining the agent to the operator's own
|
|
55
|
+
* host is the SDK's local sandbox provider, which is implemented; a
|
|
56
|
+
* host that wants no confinement configures no sandbox.
|
|
97
57
|
*
|
|
98
58
|
* The concrete implementation inside a tier is picked via the
|
|
99
|
-
* tier-specific config (see {@link
|
|
100
|
-
* {@link
|
|
59
|
+
* tier-specific config (see {@link ContainerBackendConfig},
|
|
60
|
+
* {@link MicroVMBackendConfig}).
|
|
101
61
|
*/
|
|
102
|
-
export type SandboxTier = '
|
|
62
|
+
export type SandboxTier = 'container' | 'microvm';
|
|
103
63
|
/**
|
|
104
64
|
* Discriminated union of sandbox backend configurations. Each
|
|
105
65
|
* tier has its own configuration shape — picking a tier picks the
|
|
106
66
|
* shape automatically via TS narrowing.
|
|
107
67
|
*/
|
|
108
|
-
export type SandboxBackendConfig =
|
|
68
|
+
export type SandboxBackendConfig = ContainerBackendConfig | ACIStandbyPoolBackendConfig | MicroVMBackendConfig;
|
|
109
69
|
/**
|
|
110
70
|
* Azure Container Instances Standby Pool backend. Container tier,
|
|
111
71
|
* managed-microvm-ish: every claim is a fresh ACI container group
|
|
112
72
|
* pre-warmed in an Azure-managed standby pool (`Microsoft.StandbyPool`).
|
|
113
73
|
* ~1.5 s claim latency vs ~10-30 s for cold ACI spawn. Trust boundary
|
|
114
|
-
* =
|
|
115
|
-
* SKU
|
|
74
|
+
* = the provider's isolation host, whose strength varies by SKU; the
|
|
75
|
+
* Confidential SKU adds an AMD SEV-SNP trusted execution environment.
|
|
116
76
|
*
|
|
117
77
|
* No host filesystem — workspace mounts ride `azureFileShare` sources
|
|
118
78
|
* (the host provisions a per-task Azure Files share upstream and
|
|
@@ -154,33 +114,17 @@ export interface ACIStandbyPoolBackendConfig {
|
|
|
154
114
|
*/
|
|
155
115
|
readonly containerNamePrefix?: string;
|
|
156
116
|
}
|
|
157
|
-
/**
|
|
158
|
-
* `process` tier. Auto-detects the platform's native primitive
|
|
159
|
-
* unless overridden:
|
|
160
|
-
*
|
|
161
|
-
* - `bubblewrap` on Linux / WSL2 (`bwrap`)
|
|
162
|
-
* - `seatbelt` on macOS (`sandbox-exec`)
|
|
163
|
-
*
|
|
164
|
-
* Both are what `@anthropic-ai/sandbox-runtime` ships. Cold-start
|
|
165
|
-
* is process spawn (~ms). Use this when the agent runs on the
|
|
166
|
-
* end-user's developer machine — Claude Code's deployment model.
|
|
167
|
-
*/
|
|
168
|
-
export interface ProcessBackendConfig {
|
|
169
|
-
readonly tier: 'process';
|
|
170
|
-
readonly engine?: 'auto' | 'bubblewrap' | 'seatbelt';
|
|
171
|
-
}
|
|
172
117
|
/**
|
|
173
118
|
* `container` tier. Two runtime options:
|
|
174
119
|
*
|
|
175
120
|
* - `docker` (default) — plain OCI container on the host's
|
|
176
121
|
* Docker daemon. No special runtime required.
|
|
177
|
-
* - `runsc` —
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* `gvisor.dev/docs/user_guide/quick_start/docker`.
|
|
122
|
+
* - `runsc` — a userspace-kernel runtime: the guest's syscalls
|
|
123
|
+
* are served by a user-space implementation rather than the
|
|
124
|
+
* host kernel, which is a stronger boundary than namespaces and
|
|
125
|
+
* runs on commodity Linux without nested virtualization.
|
|
126
|
+
* Requires the runtime installed on the container daemon (Linux
|
|
127
|
+
* only).
|
|
184
128
|
*
|
|
185
129
|
* `image` is the container image to spawn per task. The package
|
|
186
130
|
* ships a reference Dockerfile (compass-platform pattern) with
|
|
@@ -227,63 +171,38 @@ export interface ContainerBackendConfig {
|
|
|
227
171
|
readonly labels?: Readonly<Record<string, string>>;
|
|
228
172
|
}
|
|
229
173
|
/**
|
|
230
|
-
* `microvm` tier
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
* calls" rather than "Python REPL".
|
|
242
|
-
* - `self-hosted` — direct `firecracker-containerd` against a
|
|
243
|
-
* KVM-enabled host. For deployments where E2B and Fly are
|
|
244
|
-
* both off the table for policy reasons. Operationally the
|
|
245
|
-
* heaviest path; everything below ships first.
|
|
246
|
-
*
|
|
247
|
-
* Local dev: `e2b` and `fly-machines` work from any laptop with
|
|
248
|
-
* an API key (no infra setup). `self-hosted` requires Linux + KVM
|
|
249
|
-
* (Lima/Colima on macOS).
|
|
174
|
+
* `microvm` tier, against namzu's own guest orchestrator.
|
|
175
|
+
*
|
|
176
|
+
* Two adapters to third-party managed schedulers were declared here
|
|
177
|
+
* and never written: both threw on construction, and each demanded
|
|
178
|
+
* required credentials for a call that was never made. A config
|
|
179
|
+
* shape whose only reachable outcome is an exception is worse than
|
|
180
|
+
* no shape, because it type-checks.
|
|
181
|
+
*
|
|
182
|
+
* What remains is the orchestrator namzu runs: the control plane
|
|
183
|
+
* mints a guest per task and resumes it copy-on-write from a golden
|
|
184
|
+
* snapshot, so a cold start is a resume rather than a boot.
|
|
250
185
|
*/
|
|
251
186
|
export type MicroVMBackendConfig = {
|
|
252
|
-
readonly tier: 'microvm';
|
|
253
|
-
readonly service: 'e2b';
|
|
254
|
-
readonly apiKey: string;
|
|
255
|
-
readonly template?: string;
|
|
256
|
-
} | {
|
|
257
|
-
readonly tier: 'microvm';
|
|
258
|
-
readonly service: 'fly-machines';
|
|
259
|
-
readonly apiToken: string;
|
|
260
|
-
readonly app: string;
|
|
261
|
-
readonly image: string;
|
|
262
|
-
readonly region?: string;
|
|
263
|
-
} | {
|
|
264
187
|
readonly tier: 'microvm';
|
|
265
188
|
readonly service: 'self-hosted';
|
|
266
|
-
readonly firecrackerBinary: string;
|
|
267
|
-
readonly kernelImage: string;
|
|
268
|
-
readonly rootfsImage: string;
|
|
269
189
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
190
|
+
* Control-plane base URL, and the bearer minted for it.
|
|
191
|
+
*
|
|
192
|
+
* Both are REQUIRED, which is a correction: they were optional
|
|
193
|
+
* beside three required fields (`firecrackerBinary`,
|
|
194
|
+
* `kernelImage`, `rootfsImage`) belonging to a local-daemon shape
|
|
195
|
+
* that was never implemented. So the only working configuration
|
|
196
|
+
* had to supply three values nothing reads, and omitting these
|
|
197
|
+
* two type-checked its way to a runtime throw.
|
|
278
198
|
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* {@link SandboxBackendNotImplementedError}; supplying
|
|
283
|
-
* `orchestratorEndpoint` is what routes to the owned backend.
|
|
199
|
+
* `getToken` is a closure rather than a credential, so this
|
|
200
|
+
* package carries no cloud SDK: the host runtime owns how the
|
|
201
|
+
* bearer is obtained.
|
|
284
202
|
*/
|
|
285
|
-
readonly orchestratorEndpoint
|
|
286
|
-
readonly getToken
|
|
203
|
+
readonly orchestratorEndpoint: string;
|
|
204
|
+
readonly getToken: () => Promise<string>;
|
|
205
|
+
/** Golden snapshot revision to resume copy-on-write. */
|
|
287
206
|
readonly template?: string;
|
|
288
207
|
/**
|
|
289
208
|
* Resume this per-agent captured snapshot (layered on its base
|
|
@@ -357,13 +276,6 @@ export interface AgentSnapshotRef {
|
|
|
357
276
|
readonly agentId: string;
|
|
358
277
|
readonly version: string;
|
|
359
278
|
}
|
|
360
|
-
/**
|
|
361
|
-
* `passthrough` tier. No isolation — runs commands directly in
|
|
362
|
-
* the host process. Tests and trusted environments only.
|
|
363
|
-
*/
|
|
364
|
-
export interface PassthroughBackendConfig {
|
|
365
|
-
readonly tier: 'passthrough';
|
|
366
|
-
}
|
|
367
279
|
/**
|
|
368
280
|
* Egress allowlist resolution. Host-supplied policy decides whether
|
|
369
281
|
* an outbound request is allowed before the proxy opens a socket.
|
|
@@ -384,6 +296,8 @@ export interface PassthroughBackendConfig {
|
|
|
384
296
|
* problem — the host owns the closure, the SDK runtime
|
|
385
297
|
* doesn't have to forward identity through `provider.create`.
|
|
386
298
|
*/
|
|
299
|
+
export { EgressProxy, isHostAllowed, splitAuthority, } from './egress/index.js';
|
|
300
|
+
export type { BrokeredCredential, EgressProxyOptions, RunningEgressProxy, } from './egress/index.js';
|
|
387
301
|
export type EgressPolicy = {
|
|
388
302
|
readonly kind: 'deny-all';
|
|
389
303
|
} | {
|
|
@@ -478,7 +392,7 @@ export type SandboxProviderConfig = (SandboxProviderConfigBase & {
|
|
|
478
392
|
readonly backend: ContainerBackendConfig;
|
|
479
393
|
readonly layout: ContainerSandboxLayout;
|
|
480
394
|
}) | (SandboxProviderConfigBase & {
|
|
481
|
-
readonly backend:
|
|
395
|
+
readonly backend: MicroVMBackendConfig;
|
|
482
396
|
});
|
|
483
397
|
interface SandboxProviderConfigBase {
|
|
484
398
|
readonly defaultEgress?: EgressPolicy;
|
|
@@ -493,25 +407,22 @@ interface SandboxProviderConfigBase {
|
|
|
493
407
|
* the chosen backend.
|
|
494
408
|
*
|
|
495
409
|
* Backends are loaded lazily — the package only imports the
|
|
496
|
-
* platform-specific modules (
|
|
497
|
-
* Docker SDK, the
|
|
410
|
+
* platform-specific modules (the host sandbox runtime, the
|
|
411
|
+
* Docker SDK, the microVM SDK, …) when the corresponding backend is
|
|
498
412
|
* requested. That keeps `@namzu/sandbox` reasonable to install in
|
|
499
413
|
* environments where one backend is genuinely impossible.
|
|
500
414
|
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
* Calling this function now throws
|
|
513
|
-
* {@link SandboxBackendNotImplementedError} so consumers get a
|
|
514
|
-
* clear signal during the staged rollout.
|
|
415
|
+
* Every shape in {@link SandboxBackendConfig} has a backend behind
|
|
416
|
+
* it. That is a recent property: this file used to declare a staged
|
|
417
|
+
* roadmap of tiers and adapters, most of which threw, so the surface
|
|
418
|
+
* described a plan and the runtime described the truth. The shapes
|
|
419
|
+
* that were never built are gone rather than pending — a config that
|
|
420
|
+
* type-checks and can only throw teaches a caller the wrong thing
|
|
421
|
+
* about what this package does.
|
|
422
|
+
*
|
|
423
|
+
* {@link SandboxBackendNotImplementedError} survives for the untyped
|
|
424
|
+
* caller: a JS host that invents a tier gets a named refusal instead
|
|
425
|
+
* of a provider that confines nothing.
|
|
515
426
|
*/
|
|
516
427
|
export declare function createSandboxProvider(config: SandboxProviderConfig): SandboxProvider;
|
|
517
428
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,69 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @namzu/sandbox — pluggable
|
|
2
|
+
* @namzu/sandbox — pluggable containment for @namzu/sdk.
|
|
3
3
|
*
|
|
4
|
-
* The SDK
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* The SDK declares the `SandboxProvider` shape
|
|
5
|
+
* (`packages/sdk/src/types/sandbox/index.ts`); this package implements
|
|
6
|
+
* it with concrete BACKENDS chosen at construction time. A backend is
|
|
7
|
+
* named for the mechanism it drives, because that is what it has to
|
|
8
|
+
* speak on the wire — never for a system whose ideas it borrowed.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* profile, tmpfs workdir, no-network-by-default. The universal
|
|
12
|
-
* fallback every namzu host gets locally with `docker compose`
|
|
13
|
-
* and on every Linux replica in any cloud. What Northflank /
|
|
14
|
-
* Railway / Render / Compass-platform / GitHub Actions runners
|
|
15
|
-
* actually ship for code execution. Trust boundary: namespaces.
|
|
10
|
+
* Two tiers, each a trust boundary:
|
|
16
11
|
*
|
|
17
|
-
* • `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
12
|
+
* • `container` — one OCI container per task, seccomp on, tmpfs
|
|
13
|
+
* workdir, no network unless asked. The same path on a laptop and
|
|
14
|
+
* on a Linux replica anywhere. The tier for trusted prompts and
|
|
15
|
+
* contained workloads. Boundary: kernel namespaces, or a
|
|
16
|
+
* userspace-kernel runtime where one is installed.
|
|
21
17
|
*
|
|
22
|
-
* • `
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* than "Python REPL".
|
|
18
|
+
* • `microvm` — one hardware-virtualized guest per task. The boundary
|
|
19
|
+
* to reach for when the prompt itself is adversarial, at the cost
|
|
20
|
+
* of running or renting the machinery that starts them.
|
|
26
21
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
22
|
+
* Every shape in {@link SandboxBackendConfig} has a backend behind it,
|
|
23
|
+
* which used not to be true: a `process` tier, a `passthrough` tier and
|
|
24
|
+
* two adapters to third-party schedulers were declared here and never
|
|
25
|
+
* written, so four of the shapes this package offered could only ever
|
|
26
|
+
* type-check and then throw. They are gone rather than pending.
|
|
27
|
+
* Confining an agent to the operator's own host is the SDK's local
|
|
28
|
+
* sandbox provider, which is implemented; a host that wants no
|
|
29
|
+
* confinement configures no sandbox.
|
|
31
30
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* runtime; not available on macOS Docker Desktop.
|
|
37
|
-
*
|
|
38
|
-
* • `passthrough` — no isolation, runs commands directly. For
|
|
39
|
-
* tests and trusted environments only. Off by default; opt-in.
|
|
40
|
-
*
|
|
41
|
-
* **What we deliberately do NOT build** is yet-another Firecracker
|
|
42
|
-
* scheduler — that is E2B's and Fly's entire product, and writing
|
|
43
|
-
* our own is a years-long detour. We adapt to theirs.
|
|
44
|
-
*
|
|
45
|
-
* **Cloud portability:** the backend interface is cloud-agnostic.
|
|
46
|
-
* `docker` works on every cloud; `e2b` and `fly-machines` are
|
|
47
|
-
* managed services not tied to any cloud; `firecracker` and
|
|
48
|
-
* `gvisor` need infrastructure the host chooses (GKE Sandbox, AWS
|
|
49
|
-
* Fargate, self-hosted KVM, etc.). Picking a stronger backend may
|
|
50
|
-
* imply moving cloud — that's the host's call, not the SDK's.
|
|
51
|
-
*
|
|
52
|
-
* **Local dev story:** Phase 1 (`docker`) runs everywhere. Phase 2
|
|
53
|
-
* (`e2b` / `fly-machines`) hits the managed service from a dev
|
|
54
|
-
* laptop with no infra setup. Phase 3 (`firecracker` / `gvisor`)
|
|
55
|
-
* needs Lima/Colima on macOS or native KVM on Linux — only the
|
|
56
|
-
* adversarial-multi-tenant prod path needs that and it's clearly
|
|
57
|
-
* documented as such.
|
|
58
|
-
*
|
|
59
|
-
* This file is the public surface. Concrete backend implementations
|
|
60
|
-
* land under `./backends/<kind>/` in subsequent commits — the
|
|
61
|
-
* `SandboxBackend` interface here is the contract they implement.
|
|
62
|
-
*
|
|
63
|
-
* Refs: `e2b.dev/docs/sandbox`, `fly.io/docs/machines`,
|
|
64
|
-
* `firecracker-microvm.github.io`, `gvisor.dev/docs`,
|
|
65
|
-
* `cloud.google.com/kubernetes-engine/docs/concepts/sandbox-pods`,
|
|
66
|
-
* `aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing`.
|
|
31
|
+
* namzu does not build its own microVM scheduler. That is a years-long
|
|
32
|
+
* detour from an agent kernel, and the boundary a guest gives is the
|
|
33
|
+
* same whoever started it — so the microvm tier is an interface to a
|
|
34
|
+
* scheduler, not a scheduler.
|
|
67
35
|
*/
|
|
68
36
|
import { buildAciStandbyPoolBackend } from './backends/aci-standby-pool/index.js';
|
|
69
37
|
import { buildDockerBackend, resolveLayout } from './backends/docker/index.js';
|
|
@@ -75,6 +43,27 @@ import { buildFirecrackerBackend } from './backends/firecracker/index.js';
|
|
|
75
43
|
// `SANDBOX_DEFAULT_OUTPUTS_PATH` instead of hard-coding the string.
|
|
76
44
|
export { SANDBOX_DEFAULT_OUTPUTS_PATH, SANDBOX_DEFAULT_SKILLS_PARENT, SANDBOX_DEFAULT_TOOL_RESULTS_PATH, SANDBOX_DEFAULT_TRANSCRIPTS_PATH, SANDBOX_DEFAULT_UPLOADS_PATH, } from '@namzu/sdk';
|
|
77
45
|
export { VsockAgentTransport, } from './backends/firecracker/transport.js';
|
|
46
|
+
/**
|
|
47
|
+
* Egress allowlist resolution. Host-supplied policy decides whether
|
|
48
|
+
* an outbound request is allowed before the proxy opens a socket.
|
|
49
|
+
*
|
|
50
|
+
* Four shapes:
|
|
51
|
+
*
|
|
52
|
+
* - `deny-all` — default. Reject every outbound request.
|
|
53
|
+
* - `allow-all` — accept every outbound request. Tests only.
|
|
54
|
+
* - `static` — fixed allowlist of hostnames at construction.
|
|
55
|
+
* - `resolver` — async closure returning the allowlist.
|
|
56
|
+
* Parameterless **on purpose**: the resolver is a closure that
|
|
57
|
+
* captures whatever context the host has (tenantId, runId,
|
|
58
|
+
* auth token, etc.) at provider-construction time. Compass-
|
|
59
|
+
* platform's JWT-minting flow already works this way: the
|
|
60
|
+
* server knows the tenant when it issues the JWT, and the
|
|
61
|
+
* allowlist claim is baked in there. This avoids the
|
|
62
|
+
* "where does the resolver get its context from" plumbing
|
|
63
|
+
* problem — the host owns the closure, the SDK runtime
|
|
64
|
+
* doesn't have to forward identity through `provider.create`.
|
|
65
|
+
*/
|
|
66
|
+
export { EgressProxy, isHostAllowed, splitAuthority, } from './egress/index.js';
|
|
78
67
|
/**
|
|
79
68
|
* Build a {@link SandboxProvider} the SDK can wire into
|
|
80
69
|
* `drainQuery`'s `sandboxProvider` field. Selects the backend at
|
|
@@ -82,25 +71,22 @@ export { VsockAgentTransport, } from './backends/firecracker/transport.js';
|
|
|
82
71
|
* the chosen backend.
|
|
83
72
|
*
|
|
84
73
|
* Backends are loaded lazily — the package only imports the
|
|
85
|
-
* platform-specific modules (
|
|
86
|
-
* Docker SDK, the
|
|
74
|
+
* platform-specific modules (the host sandbox runtime, the
|
|
75
|
+
* Docker SDK, the microVM SDK, …) when the corresponding backend is
|
|
87
76
|
* requested. That keeps `@namzu/sandbox` reasonable to install in
|
|
88
77
|
* environments where one backend is genuinely impossible.
|
|
89
78
|
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* - **P3.4** — `process` (Anthropic sandbox-runtime adapter).
|
|
98
|
-
* - **P3.5** — `microvm` (self-hosted firecracker-containerd) +
|
|
99
|
-
* `container` (gVisor runtime). Phase 3 adversarial-multi-tenant.
|
|
79
|
+
* Every shape in {@link SandboxBackendConfig} has a backend behind
|
|
80
|
+
* it. That is a recent property: this file used to declare a staged
|
|
81
|
+
* roadmap of tiers and adapters, most of which threw, so the surface
|
|
82
|
+
* described a plan and the runtime described the truth. The shapes
|
|
83
|
+
* that were never built are gone rather than pending — a config that
|
|
84
|
+
* type-checks and can only throw teaches a caller the wrong thing
|
|
85
|
+
* about what this package does.
|
|
100
86
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
87
|
+
* {@link SandboxBackendNotImplementedError} survives for the untyped
|
|
88
|
+
* caller: a JS host that invents a tier gets a named refusal instead
|
|
89
|
+
* of a provider that confines nothing.
|
|
104
90
|
*/
|
|
105
91
|
export function createSandboxProvider(config) {
|
|
106
92
|
const backend = pickBackend(config);
|
|
@@ -235,16 +221,12 @@ function pickBackend(config) {
|
|
|
235
221
|
/**
|
|
236
222
|
* Human-readable backend label for error messages. Returns the
|
|
237
223
|
* tier plus the concrete service / runtime when present, e.g.
|
|
238
|
-
* `'microvm:
|
|
224
|
+
* `'microvm:self-hosted'` or `'container:runsc'`.
|
|
239
225
|
*/
|
|
240
226
|
function describeBackend(config) {
|
|
241
227
|
if (config.tier === 'microvm')
|
|
242
228
|
return `microvm:${config.service}`;
|
|
243
|
-
|
|
244
|
-
return `container:${config.runtime ?? 'docker'}`;
|
|
245
|
-
if (config.tier === 'process')
|
|
246
|
-
return `process:${config.engine ?? 'auto'}`;
|
|
247
|
-
return config.tier;
|
|
229
|
+
return `container:${config.runtime ?? 'docker'}`;
|
|
248
230
|
}
|
|
249
231
|
// ---------------------------------------------------------------------------
|
|
250
232
|
// Errors
|