isol8 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +379 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +61288 -0
  6. package/dist/cli.js.map +304 -0
  7. package/dist/client/remote.d.ts +64 -0
  8. package/dist/client/remote.d.ts.map +1 -0
  9. package/dist/config.d.ts +36 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/cpufeatures-8g73ch7n.node +0 -0
  12. package/dist/docker/Dockerfile +39 -0
  13. package/dist/docker/proxy.mjs +127 -0
  14. package/dist/engine/concurrency.d.ts +46 -0
  15. package/dist/engine/concurrency.d.ts.map +1 -0
  16. package/dist/engine/docker.d.ts +103 -0
  17. package/dist/engine/docker.d.ts.map +1 -0
  18. package/dist/engine/image-builder.d.ts +46 -0
  19. package/dist/engine/image-builder.d.ts.map +1 -0
  20. package/dist/engine/pool.d.ts +57 -0
  21. package/dist/engine/pool.d.ts.map +1 -0
  22. package/dist/engine/utils.d.ts +62 -0
  23. package/dist/engine/utils.d.ts.map +1 -0
  24. package/dist/index.d.ts +16 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +1357 -0
  27. package/dist/index.js.map +24 -0
  28. package/dist/runtime/adapter.d.ts +60 -0
  29. package/dist/runtime/adapter.d.ts.map +1 -0
  30. package/dist/runtime/adapters/bash.d.ts +3 -0
  31. package/dist/runtime/adapters/bash.d.ts.map +1 -0
  32. package/dist/runtime/adapters/bun.d.ts +4 -0
  33. package/dist/runtime/adapters/bun.d.ts.map +1 -0
  34. package/dist/runtime/adapters/deno.d.ts +10 -0
  35. package/dist/runtime/adapters/deno.d.ts.map +1 -0
  36. package/dist/runtime/adapters/node.d.ts +4 -0
  37. package/dist/runtime/adapters/node.d.ts.map +1 -0
  38. package/dist/runtime/adapters/python.d.ts +4 -0
  39. package/dist/runtime/adapters/python.d.ts.map +1 -0
  40. package/dist/runtime/index.d.ts +15 -0
  41. package/dist/runtime/index.d.ts.map +1 -0
  42. package/dist/server/auth.d.ts +20 -0
  43. package/dist/server/auth.d.ts.map +1 -0
  44. package/dist/server/index.d.ts +34 -0
  45. package/dist/server/index.d.ts.map +1 -0
  46. package/dist/sshcrypto-f6atjna1.node +0 -0
  47. package/dist/types.d.ts +274 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/docker/Dockerfile +39 -0
  50. package/docker/proxy.mjs +127 -0
  51. package/package.json +96 -0
  52. package/schema/isol8.config.schema.json +138 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Illusion47586
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,379 @@
1
+ # isol8
2
+
3
+ Secure code execution engine for AI agents. Run untrusted Python, Node.js, Bun, Deno, and Bash code inside locked-down Docker containers with network filtering, resource limits, and output controls.
4
+
5
+ ## Features
6
+
7
+ - **5 runtimes** — Python, Node.js, Bun, Deno, Bash
8
+ - **Ephemeral & persistent** — one-shot execution or stateful REPL-like sessions
9
+ - **Streaming** — real-time output via `executeStream()` / SSE
10
+ - **Fast** — warm container pool for sub-100ms execution latency
11
+ - **Security first** — read-only rootfs, `no-new-privileges`, PID/memory/CPU limits
12
+ - **Network control** — `none` (default), `host`, or `filtered` (HTTP/HTTPS proxy with regex whitelist/blacklist)
13
+ - **File I/O** — upload files into and download files from sandboxes
14
+ - **Runtime packages** — install pip/npm/bun packages on-the-fly via `installPackages`
15
+ - **Secret masking** — environment variables are scrubbed from output
16
+ - **Output truncation** — prevents runaway stdout (default 1MB cap)
17
+ - **Remote mode** — run an HTTP server and execute from anywhere
18
+ - **Embeddable** — use as a TypeScript library in your own project
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Install
24
+ bun add isol8
25
+
26
+ # Build sandbox images (requires Docker)
27
+ bunx isol8 setup
28
+
29
+ # Run code
30
+ bunx isol8 run -e "print('hello isol8')" --runtime python
31
+ bunx isol8 run script.py
32
+ echo "console.log(42)" | bunx isol8 run --runtime node
33
+ ```
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ bun add isol8
39
+ # or
40
+ npm install isol8
41
+ ```
42
+
43
+ **Prerequisites:**
44
+ - [Docker](https://docs.docker.com/get-docker/) running locally
45
+ - [Bun](https://bun.sh) (recommended) or Node.js 20+
46
+
47
+ ## CLI
48
+
49
+ ### `isol8 setup`
50
+
51
+ Checks Docker connectivity and builds base isol8 images.
52
+
53
+ ```bash
54
+ isol8 setup
55
+ isol8 setup --python numpy,pandas,scipy
56
+ isol8 setup --node lodash,axios
57
+ ```
58
+
59
+ | Flag | Description |
60
+ |------|-------------|
61
+ | `--python <pkgs>` | Comma-separated pip packages to bake in |
62
+ | `--node <pkgs>` | Comma-separated npm packages to install globally |
63
+ | `--bun <pkgs>` | Comma-separated bun packages |
64
+ | `--deno <pkgs>` | Comma-separated Deno module URLs to cache |
65
+ | `--bash <pkgs>` | Comma-separated Alpine apk packages |
66
+
67
+ ### `isol8 run`
68
+
69
+ Execute code in isol8. Accepts a file, `--eval`, or stdin.
70
+
71
+ ```bash
72
+ # File
73
+ isol8 run script.py
74
+
75
+ # Inline
76
+ isol8 run -e "print(1+1)" --runtime python
77
+
78
+ # Stdin
79
+ echo "Bun.version" | isol8 run --runtime bun
80
+
81
+ # With packages
82
+ isol8 run -e "import numpy; print(numpy.__version__)" --install numpy --runtime python
83
+
84
+ # Remote execution
85
+ isol8 run script.py --host http://server:3000 --key my-api-key
86
+ ```
87
+
88
+ | Flag | Description | Default |
89
+ |------|-------------|---------|
90
+ | `-e, --eval <code>` | Execute inline code | — |
91
+ | `-r, --runtime <rt>` | Force runtime: `python`, `node`, `bun`, `deno`, `bash` | auto-detect |
92
+ | `--net <mode>` | Network mode: `none`, `host`, `filtered` | `none` |
93
+ | `--allow <regex>` | Whitelist regex (repeatable, for `filtered`) | — |
94
+ | `--deny <regex>` | Blacklist regex (repeatable, for `filtered`) | — |
95
+ | `--out <file>` | Write stdout to file | — |
96
+ | `--persistent` | Keep container alive between runs | `false` |
97
+ | `--timeout <ms>` | Execution timeout in milliseconds | `30000` |
98
+ | `--memory <limit>` | Memory limit (e.g. `512m`, `1g`) | `512m` |
99
+ | `--cpu <limit>` | CPU limit as fraction (e.g. `0.5`, `2.0`) | `1.0` |
100
+ | `--image <name>` | Override Docker image | — |
101
+ | `--pids-limit <n>` | Maximum number of processes | `64` |
102
+ | `--writable` | Disable read-only root filesystem | `false` |
103
+ | `--max-output <bytes>` | Maximum output size in bytes | `1048576` |
104
+ | `--secret <KEY=VALUE>` | Secret env var (repeatable, values masked) | — |
105
+ | `--sandbox-size <size>` | Sandbox tmpfs size (e.g. `128m`) | `64m` |
106
+ | `--stdin <data>` | Data to pipe to stdin | — |
107
+ | `--install <pkg>` | Install package for runtime (repeatable) | — |
108
+ | `--host <url>` | Remote server URL | — |
109
+ | `--key <key>` | API key for remote server | `$ISOL8_API_KEY` |
110
+
111
+ ### `isol8 serve`
112
+
113
+ Start the isol8 remote HTTP server. **Requires Bun runtime.**
114
+
115
+ ```bash
116
+ isol8 serve --port 3000 --key my-secret-key
117
+ ```
118
+
119
+ ### `isol8 config`
120
+
121
+ Display the resolved configuration (merged defaults + config file). Shows the source file, defaults, network rules, cleanup policy, and dependencies.
122
+
123
+ ```bash
124
+ # Formatted output
125
+ isol8 config
126
+
127
+ # Raw JSON (useful for piping)
128
+ isol8 config --json
129
+ ```
130
+
131
+ ## Library Usage
132
+
133
+ ```typescript
134
+ import { DockerIsol8, loadConfig } from "isol8";
135
+
136
+ const isol8 = new DockerIsol8({ network: "none" });
137
+ await isol8.start();
138
+
139
+ const result = await isol8.execute({
140
+ code: 'print("Hello from isol8!")',
141
+ runtime: "python",
142
+ timeoutMs: 10000,
143
+ });
144
+
145
+ console.log(result.stdout); // "Hello from isol8!"
146
+ console.log(result.exitCode); // 0
147
+ console.log(result.durationMs); // ~55-95ms (warm pool)
148
+
149
+ await isol8.stop();
150
+ ```
151
+
152
+ ### Persistent Sessions
153
+
154
+ ```typescript
155
+ const isol8 = new DockerIsol8({ mode: "persistent" });
156
+ await isol8.start();
157
+
158
+ await isol8.execute({ code: "x = 42", runtime: "python" });
159
+ const result = await isol8.execute({ code: "print(x)", runtime: "python" });
160
+ console.log(result.stdout); // "42"
161
+
162
+ await isol8.stop();
163
+ ```
164
+
165
+ ### File I/O
166
+
167
+ ```typescript
168
+ await isol8.putFile("/sandbox/data.csv", "name,age\nAlice,30\nBob,25\n");
169
+
170
+ const result = await isol8.execute({
171
+ code: `
172
+ import csv
173
+ with open('/sandbox/data.csv') as f:
174
+ for row in csv.reader(f):
175
+ print(row)
176
+ `,
177
+ runtime: "python",
178
+ });
179
+
180
+ const output = await isol8.getFile("/sandbox/output.txt");
181
+ ```
182
+
183
+ ### Remote Client
184
+
185
+ ```typescript
186
+ import { RemoteIsol8 } from "isol8";
187
+
188
+ const isol8 = new RemoteIsol8(
189
+ { host: "http://localhost:3000", apiKey: "my-key" },
190
+ { network: "none" }
191
+ );
192
+
193
+ await isol8.start();
194
+ const result = await isol8.execute({ code: "print('remote!')", runtime: "python" });
195
+ await isol8.stop();
196
+ ```
197
+
198
+ ### Streaming Output
199
+
200
+ ```typescript
201
+ import { DockerIsol8 } from "isol8";
202
+
203
+ const isol8 = new DockerIsol8({ network: "none" });
204
+ await isol8.start();
205
+
206
+ for await (const event of isol8.executeStream({
207
+ code: 'for i in range(5): print(i)',
208
+ runtime: "python",
209
+ })) {
210
+ if (event.type === "stdout") process.stdout.write(event.data);
211
+ if (event.type === "stderr") process.stderr.write(event.data);
212
+ if (event.type === "exit") console.log(`\nExit: ${event.data}`);
213
+ }
214
+
215
+ await isol8.stop();
216
+ ```
217
+
218
+ ### Runtime Package Installation
219
+
220
+ ```typescript
221
+ const result = await isol8.execute({
222
+ code: 'import numpy; print(numpy.__version__)',
223
+ runtime: "python",
224
+ installPackages: ["numpy"],
225
+ });
226
+ ```
227
+
228
+ ### Network Filtering
229
+
230
+ ```typescript
231
+ const isol8 = new DockerIsol8({
232
+ network: "filtered",
233
+ networkFilter: {
234
+ whitelist: ["^api\\.openai\\.com$", "pypi\\.org"],
235
+ blacklist: [".*\\.ru$"],
236
+ },
237
+ });
238
+ ```
239
+
240
+ ## Configuration
241
+
242
+ Create `isol8.config.json` in your project root or `~/.isol8/config.json`.
243
+
244
+ ### Editor Setup
245
+
246
+ Add the `$schema` property to get autocompletion, validation, and inline documentation in VS Code, JetBrains, and any JSON Schema-aware editor:
247
+
248
+ ```json
249
+ {
250
+ "$schema": "node_modules/isol8/schema/isol8.config.schema.json"
251
+ }
252
+ ```
253
+
254
+ ### Full Example
255
+
256
+ ```json
257
+ {
258
+ "$schema": "node_modules/isol8/schema/isol8.config.schema.json",
259
+ "maxConcurrent": 10,
260
+ "defaults": {
261
+ "timeoutMs": 30000,
262
+ "memoryLimit": "512m",
263
+ "cpuLimit": 1.0,
264
+ "network": "none"
265
+ },
266
+ "network": {
267
+ "whitelist": ["^api\\.openai\\.com$"],
268
+ "blacklist": []
269
+ },
270
+ "cleanup": {
271
+ "autoPrune": true,
272
+ "maxContainerAgeMs": 3600000
273
+ },
274
+ "dependencies": {
275
+ "python": ["numpy", "pandas"],
276
+ "node": ["lodash"]
277
+ }
278
+ }
279
+ ```
280
+
281
+ Full schema: [`schema/isol8.config.schema.json`](./schema/isol8.config.schema.json)
282
+
283
+ ## Benchmarks
284
+
285
+ Execution latency for a "hello world" script per runtime. Measured on Apple Silicon (Docker Desktop), averaged across multiple runs. Results will vary by machine.
286
+
287
+ ### Cold Start (fresh engine per run)
288
+
289
+ Each run creates a new `DockerIsol8` instance, executes, and tears down.
290
+
291
+ | Runtime | Min | Median | Max | Avg |
292
+ |---------|-----|--------|-----|-----|
293
+ | Python | 148ms | 155ms | 414ms | 239ms |
294
+ | Node.js | 152ms | 155ms | 186ms | 165ms |
295
+ | Bun | 124ms | 145ms | 260ms | 176ms |
296
+ | Deno | 339ms | 372ms | 626ms | 446ms |
297
+ | Bash | 115ms | 123ms | 148ms | 128ms |
298
+
299
+ ### Warm Pool (reused engine)
300
+
301
+ A single `DockerIsol8` instance reused across 5 runs. The first run is cold (pool empty); subsequent runs hit the warm container pool.
302
+
303
+ | Runtime | Cold | Warm Avg | Warm Min | Speedup |
304
+ |---------|------|----------|----------|---------|
305
+ | Python | 285ms | 95ms | 89ms | 3.2x |
306
+ | Node.js | 177ms | 91ms | 76ms | 2.3x |
307
+ | Bun | 157ms | 72ms | 66ms | 2.4x |
308
+ | Deno | 330ms | 264ms | 231ms | 1.4x |
309
+ | Bash | 222ms | 68ms | 55ms | 4.0x |
310
+
311
+ ### Execution Phase Breakdown
312
+
313
+ Where time is spent in the container lifecycle (raw Docker API, no pool):
314
+
315
+ | Runtime | Create | Start | Write | Exec Setup | Run | Cleanup | Total |
316
+ |---------|--------|-------|-------|------------|-----|---------|-------|
317
+ | Python | 41ms | 49ms | 17ms | 1ms | 40ms | 43ms | 190ms |
318
+ | Node.js | 32ms | 63ms | 34ms | 1ms | 39ms | 43ms | 212ms |
319
+ | Bun | 32ms | 56ms | 26ms | 1ms | 27ms | 44ms | 186ms |
320
+ | Bash | 35ms | 69ms | 23ms | 1ms | 20ms | 48ms | 196ms |
321
+
322
+ Run benchmarks yourself:
323
+
324
+ ```bash
325
+ bun run bench # Cold start benchmark
326
+ bun run bench:pool # Warm pool benchmark
327
+ bun run bench:detailed # Phase breakdown
328
+ ```
329
+
330
+ ## Security Model
331
+
332
+ | Layer | Protection |
333
+ |-------|-----------|
334
+ | **Filesystem** | Read-only root, writable `/sandbox` (tmpfs, 64MB), writable `/tmp` (tmpfs, noexec, 64MB) |
335
+ | **Processes** | PID limit (default 64), `no-new-privileges` |
336
+ | **Resources** | CPU (1 core), memory (512MB), execution timeout (30s) |
337
+ | **Network** | Disabled by default; optional proxy-based filtering |
338
+ | **Output** | Truncated at 1MB; secrets masked from stdout/stderr |
339
+ | **Isolation** | Each execution in its own container (ephemeral) or exec (persistent) |
340
+
341
+ ## REST API
342
+
343
+ When running `isol8 serve`, these endpoints are available:
344
+
345
+ | Method | Path | Description |
346
+ |--------|------|-------------|
347
+ | `GET` | `/health` | Health check (no auth) |
348
+ | `POST` | `/execute` | Execute code |
349
+ | `POST` | `/execute/stream` | Execute code with SSE streaming |
350
+ | `POST` | `/file` | Upload file (base64) |
351
+ | `GET` | `/file?sessionId=&path=` | Download file (base64) |
352
+ | `DELETE` | `/session/:id` | Destroy persistent session |
353
+
354
+ All endpoints (except `/health`) require `Authorization: Bearer <key>`.
355
+
356
+ ## Development
357
+
358
+ ```bash
359
+ # Run CLI in dev mode
360
+ bun run dev <command>
361
+
362
+ # Run tests
363
+ bun test
364
+
365
+ # Type check
366
+ bunx tsc --noEmit
367
+
368
+ # Lint
369
+ bun run lint
370
+
371
+ # Benchmarks
372
+ bun run bench # Cold start
373
+ bun run bench:pool # Warm pool
374
+ bun run bench:detailed # Phase breakdown
375
+ ```
376
+
377
+ ## License
378
+
379
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}