isol8 0.8.1 → 0.8.2
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/README.md +1 -0
- package/dist/cli.js +66 -22
- package/dist/index.js +52 -19
- package/dist/src/engine/docker.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Secure code execution engine for AI agents. Run untrusted Python, Node.js, Bun,
|
|
|
15
15
|
- **Fast** — warm container pool for sub-100ms execution latency
|
|
16
16
|
- **Security first** — read-only rootfs, `no-new-privileges`, PID/memory/CPU limits
|
|
17
17
|
- **Network control** — `none` (default), `host`, or `filtered` (HTTP/HTTPS proxy with regex whitelist/blacklist)
|
|
18
|
+
- **Secure File I/O** — streaming file content avoids process argument leaks
|
|
18
19
|
- **File I/O** — upload files into and download files from sandboxes
|
|
19
20
|
- **Runtime packages** — install pip/npm/bun packages on-the-fly (`--install`)
|
|
20
21
|
- **Modern Node.js** — defaults to ESM (`.mjs`), supports CommonJS (`.cjs`)
|
package/dist/cli.js
CHANGED
|
@@ -6316,12 +6316,23 @@ var require_bcrypt_pbkdf = __commonJS((exports, module) => {
|
|
|
6316
6316
|
};
|
|
6317
6317
|
});
|
|
6318
6318
|
|
|
6319
|
+
// node_modules/cpu-features/build/Release/cpufeatures.node
|
|
6320
|
+
var require_cpufeatures = __commonJS((exports, module) => {
|
|
6321
|
+
module.exports = __require("./cpufeatures-tjjrgpt7.node");
|
|
6322
|
+
});
|
|
6323
|
+
|
|
6324
|
+
// node_modules/cpu-features/lib/index.js
|
|
6325
|
+
var require_lib2 = __commonJS((exports, module) => {
|
|
6326
|
+
var binding = require_cpufeatures();
|
|
6327
|
+
module.exports = binding.getCPUInfo;
|
|
6328
|
+
});
|
|
6329
|
+
|
|
6319
6330
|
// node_modules/ssh2/lib/protocol/constants.js
|
|
6320
6331
|
var require_constants = __commonJS((exports, module) => {
|
|
6321
6332
|
var crypto = __require("crypto");
|
|
6322
6333
|
var cpuInfo;
|
|
6323
6334
|
try {
|
|
6324
|
-
cpuInfo = (
|
|
6335
|
+
cpuInfo = require_lib2()();
|
|
6325
6336
|
} catch {}
|
|
6326
6337
|
var { bindingAvailable, CIPHER_INFO, MAC_INFO } = require_crypto();
|
|
6327
6338
|
var eddsaSupported = (() => {
|
|
@@ -20964,7 +20975,7 @@ var require_keygen = __commonJS((exports, module) => {
|
|
|
20964
20975
|
});
|
|
20965
20976
|
|
|
20966
20977
|
// node_modules/ssh2/lib/index.js
|
|
20967
|
-
var
|
|
20978
|
+
var require_lib3 = __commonJS((exports, module) => {
|
|
20968
20979
|
var {
|
|
20969
20980
|
AgentProtocol,
|
|
20970
20981
|
BaseAgent,
|
|
@@ -21010,7 +21021,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
21010
21021
|
|
|
21011
21022
|
// node_modules/docker-modem/lib/ssh.js
|
|
21012
21023
|
var require_ssh = __commonJS((exports, module) => {
|
|
21013
|
-
var Client =
|
|
21024
|
+
var Client = require_lib3().Client;
|
|
21014
21025
|
var http = __require("http");
|
|
21015
21026
|
module.exports = function(opt) {
|
|
21016
21027
|
var conn = new Client;
|
|
@@ -55272,25 +55283,31 @@ var exports_docker = {};
|
|
|
55272
55283
|
__export(exports_docker, {
|
|
55273
55284
|
DockerIsol8: () => DockerIsol8
|
|
55274
55285
|
});
|
|
55286
|
+
import { spawn } from "node:child_process";
|
|
55275
55287
|
import { randomUUID } from "node:crypto";
|
|
55276
55288
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
55277
55289
|
import { PassThrough } from "node:stream";
|
|
55278
55290
|
async function writeFileViaExec(container, filePath, content) {
|
|
55279
55291
|
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
55280
|
-
|
|
55281
|
-
|
|
55282
|
-
|
|
55283
|
-
|
|
55292
|
+
return new Promise((resolve2, reject) => {
|
|
55293
|
+
const child = spawn("docker", ["exec", "-i", "-u", "sandbox", container.id, "sh", "-c", `cat > ${filePath}`], {
|
|
55294
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
55295
|
+
});
|
|
55296
|
+
child.on("error", (err) => {
|
|
55297
|
+
reject(new Error(`Failed to spawn docker exec: ${err.message}`));
|
|
55298
|
+
});
|
|
55299
|
+
let stderr = "";
|
|
55300
|
+
child.stderr.on("data", (chunk) => stderr += chunk.toString());
|
|
55301
|
+
child.stdin.write(data);
|
|
55302
|
+
child.stdin.end();
|
|
55303
|
+
child.on("close", (code) => {
|
|
55304
|
+
if (code !== 0) {
|
|
55305
|
+
reject(new Error(`Failed to write file ${filePath}: ${stderr} (exit code ${code})`));
|
|
55306
|
+
} else {
|
|
55307
|
+
resolve2();
|
|
55308
|
+
}
|
|
55309
|
+
});
|
|
55284
55310
|
});
|
|
55285
|
-
await exec.start({ Detach: true });
|
|
55286
|
-
let info2 = await exec.inspect();
|
|
55287
|
-
while (info2.Running) {
|
|
55288
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
55289
|
-
info2 = await exec.inspect();
|
|
55290
|
-
}
|
|
55291
|
-
if (info2.ExitCode !== 0) {
|
|
55292
|
-
throw new Error(`Failed to write file ${filePath} in container (exit code ${info2.ExitCode})`);
|
|
55293
|
-
}
|
|
55294
55311
|
}
|
|
55295
55312
|
async function readFileViaExec(container, filePath) {
|
|
55296
55313
|
const exec = await container.exec({
|
|
@@ -55958,11 +55975,16 @@ class DockerIsol8 {
|
|
|
55958
55975
|
let stderr = "";
|
|
55959
55976
|
let truncated = false;
|
|
55960
55977
|
let settled = false;
|
|
55978
|
+
let stdoutEnded = false;
|
|
55979
|
+
let stderrEnded = false;
|
|
55961
55980
|
const timer = setTimeout(() => {
|
|
55962
55981
|
if (settled) {
|
|
55963
55982
|
return;
|
|
55964
55983
|
}
|
|
55965
55984
|
settled = true;
|
|
55985
|
+
if (stream.destroy) {
|
|
55986
|
+
stream.destroy();
|
|
55987
|
+
}
|
|
55966
55988
|
resolve2({ stdout, stderr: `${stderr}
|
|
55967
55989
|
--- EXECUTION TIMED OUT ---`, truncated });
|
|
55968
55990
|
}, timeoutMs);
|
|
@@ -55985,13 +56007,23 @@ class DockerIsol8 {
|
|
|
55985
56007
|
truncated = true;
|
|
55986
56008
|
}
|
|
55987
56009
|
});
|
|
55988
|
-
|
|
56010
|
+
const checkDone = () => {
|
|
55989
56011
|
if (settled) {
|
|
55990
56012
|
return;
|
|
55991
56013
|
}
|
|
55992
|
-
|
|
55993
|
-
|
|
55994
|
-
|
|
56014
|
+
if (stdoutEnded && stderrEnded) {
|
|
56015
|
+
settled = true;
|
|
56016
|
+
clearTimeout(timer);
|
|
56017
|
+
resolve2({ stdout, stderr, truncated });
|
|
56018
|
+
}
|
|
56019
|
+
};
|
|
56020
|
+
stdoutStream.on("end", () => {
|
|
56021
|
+
stdoutEnded = true;
|
|
56022
|
+
checkDone();
|
|
56023
|
+
});
|
|
56024
|
+
stderrStream.on("end", () => {
|
|
56025
|
+
stderrEnded = true;
|
|
56026
|
+
checkDone();
|
|
55995
56027
|
});
|
|
55996
56028
|
stream.on("error", (err) => {
|
|
55997
56029
|
if (settled) {
|
|
@@ -56001,6 +56033,18 @@ class DockerIsol8 {
|
|
|
56001
56033
|
clearTimeout(timer);
|
|
56002
56034
|
reject(err);
|
|
56003
56035
|
});
|
|
56036
|
+
stream.on("end", () => {
|
|
56037
|
+
if (settled) {
|
|
56038
|
+
return;
|
|
56039
|
+
}
|
|
56040
|
+
setTimeout(() => {
|
|
56041
|
+
if (!settled) {
|
|
56042
|
+
stdoutEnded = true;
|
|
56043
|
+
stderrEnded = true;
|
|
56044
|
+
checkDone();
|
|
56045
|
+
}
|
|
56046
|
+
}, 100);
|
|
56047
|
+
});
|
|
56004
56048
|
});
|
|
56005
56049
|
}
|
|
56006
56050
|
postProcessOutput(output, _truncated) {
|
|
@@ -56045,7 +56089,7 @@ var package_default;
|
|
|
56045
56089
|
var init_package = __esm(() => {
|
|
56046
56090
|
package_default = {
|
|
56047
56091
|
name: "isol8",
|
|
56048
|
-
version: "0.8.
|
|
56092
|
+
version: "0.8.1",
|
|
56049
56093
|
description: "Secure code execution engine for AI agents",
|
|
56050
56094
|
author: "Illusion47586",
|
|
56051
56095
|
license: "MIT",
|
|
@@ -62052,4 +62096,4 @@ if (!process.argv.slice(2).length) {
|
|
|
62052
62096
|
}
|
|
62053
62097
|
program2.parse();
|
|
62054
62098
|
|
|
62055
|
-
//# debugId=
|
|
62099
|
+
//# debugId=2B71A68DA2ABDB9664756E2164756E21
|
package/dist/index.js
CHANGED
|
@@ -451,26 +451,32 @@ var exports_docker = {};
|
|
|
451
451
|
__export(exports_docker, {
|
|
452
452
|
DockerIsol8: () => DockerIsol8
|
|
453
453
|
});
|
|
454
|
+
import { spawn } from "node:child_process";
|
|
454
455
|
import { randomUUID } from "node:crypto";
|
|
455
456
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
456
457
|
import { PassThrough } from "node:stream";
|
|
457
458
|
import Docker from "dockerode";
|
|
458
459
|
async function writeFileViaExec(container, filePath, content) {
|
|
459
460
|
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
461
|
+
return new Promise((resolve2, reject) => {
|
|
462
|
+
const child = spawn("docker", ["exec", "-i", "-u", "sandbox", container.id, "sh", "-c", `cat > ${filePath}`], {
|
|
463
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
464
|
+
});
|
|
465
|
+
child.on("error", (err) => {
|
|
466
|
+
reject(new Error(`Failed to spawn docker exec: ${err.message}`));
|
|
467
|
+
});
|
|
468
|
+
let stderr = "";
|
|
469
|
+
child.stderr.on("data", (chunk) => stderr += chunk.toString());
|
|
470
|
+
child.stdin.write(data);
|
|
471
|
+
child.stdin.end();
|
|
472
|
+
child.on("close", (code) => {
|
|
473
|
+
if (code !== 0) {
|
|
474
|
+
reject(new Error(`Failed to write file ${filePath}: ${stderr} (exit code ${code})`));
|
|
475
|
+
} else {
|
|
476
|
+
resolve2();
|
|
477
|
+
}
|
|
478
|
+
});
|
|
464
479
|
});
|
|
465
|
-
await exec.start({ Detach: true });
|
|
466
|
-
let info = await exec.inspect();
|
|
467
|
-
while (info.Running) {
|
|
468
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
469
|
-
info = await exec.inspect();
|
|
470
|
-
}
|
|
471
|
-
if (info.ExitCode !== 0) {
|
|
472
|
-
throw new Error(`Failed to write file ${filePath} in container (exit code ${info.ExitCode})`);
|
|
473
|
-
}
|
|
474
480
|
}
|
|
475
481
|
async function readFileViaExec(container, filePath) {
|
|
476
482
|
const exec = await container.exec({
|
|
@@ -1138,11 +1144,16 @@ class DockerIsol8 {
|
|
|
1138
1144
|
let stderr = "";
|
|
1139
1145
|
let truncated = false;
|
|
1140
1146
|
let settled = false;
|
|
1147
|
+
let stdoutEnded = false;
|
|
1148
|
+
let stderrEnded = false;
|
|
1141
1149
|
const timer = setTimeout(() => {
|
|
1142
1150
|
if (settled) {
|
|
1143
1151
|
return;
|
|
1144
1152
|
}
|
|
1145
1153
|
settled = true;
|
|
1154
|
+
if (stream.destroy) {
|
|
1155
|
+
stream.destroy();
|
|
1156
|
+
}
|
|
1146
1157
|
resolve2({ stdout, stderr: `${stderr}
|
|
1147
1158
|
--- EXECUTION TIMED OUT ---`, truncated });
|
|
1148
1159
|
}, timeoutMs);
|
|
@@ -1165,13 +1176,23 @@ class DockerIsol8 {
|
|
|
1165
1176
|
truncated = true;
|
|
1166
1177
|
}
|
|
1167
1178
|
});
|
|
1168
|
-
|
|
1179
|
+
const checkDone = () => {
|
|
1169
1180
|
if (settled) {
|
|
1170
1181
|
return;
|
|
1171
1182
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1183
|
+
if (stdoutEnded && stderrEnded) {
|
|
1184
|
+
settled = true;
|
|
1185
|
+
clearTimeout(timer);
|
|
1186
|
+
resolve2({ stdout, stderr, truncated });
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
stdoutStream.on("end", () => {
|
|
1190
|
+
stdoutEnded = true;
|
|
1191
|
+
checkDone();
|
|
1192
|
+
});
|
|
1193
|
+
stderrStream.on("end", () => {
|
|
1194
|
+
stderrEnded = true;
|
|
1195
|
+
checkDone();
|
|
1175
1196
|
});
|
|
1176
1197
|
stream.on("error", (err) => {
|
|
1177
1198
|
if (settled) {
|
|
@@ -1181,6 +1202,18 @@ class DockerIsol8 {
|
|
|
1181
1202
|
clearTimeout(timer);
|
|
1182
1203
|
reject(err);
|
|
1183
1204
|
});
|
|
1205
|
+
stream.on("end", () => {
|
|
1206
|
+
if (settled) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
setTimeout(() => {
|
|
1210
|
+
if (!settled) {
|
|
1211
|
+
stdoutEnded = true;
|
|
1212
|
+
stderrEnded = true;
|
|
1213
|
+
checkDone();
|
|
1214
|
+
}
|
|
1215
|
+
}, 100);
|
|
1216
|
+
});
|
|
1184
1217
|
});
|
|
1185
1218
|
}
|
|
1186
1219
|
postProcessOutput(output, _truncated) {
|
|
@@ -1424,7 +1457,7 @@ init_logger();
|
|
|
1424
1457
|
// package.json
|
|
1425
1458
|
var package_default = {
|
|
1426
1459
|
name: "isol8",
|
|
1427
|
-
version: "0.8.
|
|
1460
|
+
version: "0.8.1",
|
|
1428
1461
|
description: "Secure code execution engine for AI agents",
|
|
1429
1462
|
author: "Illusion47586",
|
|
1430
1463
|
license: "MIT",
|
|
@@ -1759,4 +1792,4 @@ export {
|
|
|
1759
1792
|
BunAdapter
|
|
1760
1793
|
};
|
|
1761
1794
|
|
|
1762
|
-
//# debugId=
|
|
1795
|
+
//# debugId=3E8DBF80E2D1D77264756E2164756E21
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EAEX,YAAY,EAIZ,WAAW,EACZ,MAAM,UAAU,CAAC;AAiTlB,2HAA2H;AAC3H,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,IAAI,CAA8B;IAE1C;;;OAGG;gBACS,OAAO,GAAE,kBAAuB,EAAE,aAAa,SAAK;IAwBhE;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,kFAAkF;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAW9D;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB5C,6GAA6G;IAC7G,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED;;;OAGG;IACI,aAAa,CAAC,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC;YAsFzD,YAAY;YAcZ,gBAAgB;YA0GhB,iBAAiB;YA8FjB,aAAa;YAkBb,oBAAoB;YASpB,wBAAwB;IA4BtC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,QAAQ;YAwCD,gBAAgB;YA8EjB,iBAAiB;IAiG/B,OAAO,CAAC,iBAAiB;IAYzB;;;;;;;;;;;;;;;;;;;;OAoBG;WACU,OAAO,CAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CA2BlE"}
|