@bunny-agent/sandbox-srt 0.9.52-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=srt-sandbox.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"srt-sandbox.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/srt-sandbox.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,264 @@
1
+ import { execFileSync, execSync } from "node:child_process";
2
+ import * as fs from "node:fs/promises";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
+ import { buildInstallHint, SrtSandbox } from "../srt-sandbox.js";
7
+ /**
8
+ * These are real isolation tests: they execute commands through the actual
9
+ * srt wrapper (bubblewrap on Linux, Seatbelt on macOS). They are skipped on
10
+ * hosts where the platform sandboxing primitive is unavailable (e.g. Linux
11
+ * without bubblewrap installed, CI containers without user namespaces).
12
+ */
13
+ const sandboxingAvailable = (() => {
14
+ if (process.platform === "darwin") {
15
+ return true; // sandbox-exec ships with macOS
16
+ }
17
+ if (process.platform === "linux") {
18
+ try {
19
+ // srt needs bwrap (with permission to create user namespaces — on
20
+ // Ubuntu 24.04+ that requires an AppArmor profile or
21
+ // kernel.apparmor_restrict_unprivileged_userns=0), socat for its
22
+ // network proxy bridge, and ripgrep.
23
+ execFileSync("bwrap", ["--ro-bind", "/", "/", "true"], {
24
+ stdio: "ignore",
25
+ timeout: 10000,
26
+ });
27
+ execFileSync("socat", ["-V"], { stdio: "ignore", timeout: 10000 });
28
+ execFileSync("rg", ["--version"], { stdio: "ignore", timeout: 10000 });
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ return false;
36
+ })();
37
+ /** Run a shell script through the sandbox's primary exec() path. exec()
38
+ * throws on non-zero exit, which is exactly the signal these tests assert. */
39
+ async function run(handle, script) {
40
+ const chunks = [];
41
+ try {
42
+ for await (const chunk of handle.exec(["sh", "-c", script])) {
43
+ chunks.push(new TextDecoder().decode(chunk));
44
+ }
45
+ return { ok: true, output: chunks.join("") };
46
+ }
47
+ catch {
48
+ return { ok: false, output: chunks.join("") };
49
+ }
50
+ }
51
+ describe.skipIf(!sandboxingAvailable)("SrtSandbox (real isolation)", () => {
52
+ let workdir;
53
+ let outsideDir;
54
+ beforeEach(async () => {
55
+ workdir = await fs.mkdtemp(path.join(os.tmpdir(), "srt-sandbox-wd-"));
56
+ // A directory the policy does NOT allow writes to. It must live outside
57
+ // the OS temp dir (which SrtSandbox always allows) — and the repo itself
58
+ // can sit under the temp dir (e.g. a /tmp git worktree), so anchor to
59
+ // the user's home rather than process.cwd(). Removed in afterEach.
60
+ outsideDir = await fs.mkdtemp(path.join(os.homedir(), ".srt-test-outside-"));
61
+ });
62
+ afterEach(async () => {
63
+ await fs.rm(workdir, { recursive: true, force: true }).catch(() => { });
64
+ await fs.rm(outsideDir, { recursive: true, force: true }).catch(() => { });
65
+ });
66
+ it("runs commands and allows writes inside the workdir", async () => {
67
+ const sandbox = new SrtSandbox({ workdir });
68
+ const handle = await sandbox.attach();
69
+ const result = await run(handle, "echo sandboxed-ok > inside.txt && cat inside.txt");
70
+ expect(result.ok).toBe(true);
71
+ expect(result.output).toContain("sandboxed-ok");
72
+ // The write really landed on the host filesystem.
73
+ const content = await fs.readFile(path.join(workdir, "inside.txt"), "utf8");
74
+ expect(content).toContain("sandboxed-ok");
75
+ }, 120000);
76
+ it("denies writes outside the allowed paths", async () => {
77
+ const sandbox = new SrtSandbox({ workdir });
78
+ const handle = await sandbox.attach();
79
+ const target = path.join(outsideDir, "escape.txt");
80
+ const result = await run(handle, `touch ${target}`);
81
+ expect(result.ok).toBe(false);
82
+ await expect(fs.access(target)).rejects.toThrow();
83
+ }, 120000);
84
+ it("denies reads of paths listed in denyRead", async () => {
85
+ const secretDir = path.join(outsideDir, "secrets");
86
+ await fs.mkdir(secretDir, { recursive: true });
87
+ await fs.writeFile(path.join(secretDir, "key.txt"), "top-secret");
88
+ const sandbox = new SrtSandbox({
89
+ workdir,
90
+ isolation: { denyRead: [secretDir] },
91
+ });
92
+ const handle = await sandbox.attach();
93
+ const result = await run(handle, `cat ${secretDir}/key.txt`);
94
+ expect(result.ok).toBe(false);
95
+ expect(result.output).not.toContain("top-secret");
96
+ }, 120000);
97
+ it("blocks network access by default", async () => {
98
+ const sandbox = new SrtSandbox({ workdir });
99
+ const handle = await sandbox.attach();
100
+ // 5s timeout so a (wrongly) reachable network still fails fast.
101
+ const result = await run(handle, "curl -sS --max-time 5 https://example.com");
102
+ expect(result.ok).toBe(false);
103
+ }, 120000);
104
+ it("sandboxed process cannot rewrite its own policy file", async () => {
105
+ const sandbox = new SrtSandbox({ workdir });
106
+ const handle = await sandbox.attach();
107
+ // Locate the generated settings file via the wrapper command itself:
108
+ // it is passed as `--settings <path>` and lives under an srt-sandbox-*
109
+ // temp dir that the policy denies writes to.
110
+ const probe = await run(handle, "echo policy-probe");
111
+ expect(probe.ok).toBe(true);
112
+ const dirs = await fs.readdir(os.tmpdir());
113
+ const policyDirs = dirs.filter((d) => d.startsWith("srt-sandbox-"));
114
+ expect(policyDirs.length).toBeGreaterThan(0);
115
+ let deniedSomewhere = false;
116
+ for (const dir of policyDirs) {
117
+ const settingsPath = path.join(os.tmpdir(), dir, "srt-settings.json");
118
+ const result = await run(handle, `echo '{}' > ${settingsPath}`);
119
+ if (!result.ok) {
120
+ deniedSomewhere = true;
121
+ }
122
+ }
123
+ expect(deniedSomewhere).toBe(true);
124
+ }, 120000);
125
+ it("abort/timeout leaves no orphaned grandchild process (PID namespace)", async () => {
126
+ // LocalMachine (no isolation) needs its own process-group kill logic to
127
+ // catch backgrounded grandchildren on abort/timeout (see
128
+ // sandbox-local's local-machine.test.ts). SrtSandbox doesn't need that
129
+ // extra mechanism: srt passes bwrap `--unshare-pid`, so the kernel tears
130
+ // down every process in that PID namespace the moment its init process
131
+ // dies — this test locks that guarantee in so a future srt/bwrap flag
132
+ // change can't silently regress it.
133
+ const sandbox = new SrtSandbox({ workdir });
134
+ const handle = await sandbox.attach();
135
+ const marker = `srt-orphan-test-${process.pid}-${Date.now()}`;
136
+ const controller = new AbortController();
137
+ const consume = (async () => {
138
+ try {
139
+ for await (const chunk of handle.exec([
140
+ "bash",
141
+ "-c",
142
+ `(exec -a ${marker} sleep 60) & echo started; sleep 60`,
143
+ ], { signal: controller.signal })) {
144
+ void chunk;
145
+ }
146
+ }
147
+ catch {
148
+ // Expected: exec() rejects once aborted.
149
+ }
150
+ })();
151
+ await new Promise((r) => setTimeout(r, 3000));
152
+ controller.abort();
153
+ await consume;
154
+ await new Promise((r) => setTimeout(r, 3000));
155
+ let survived = false;
156
+ try {
157
+ execSync(`pgrep -f -x "${marker} 60"`, { stdio: "ignore" });
158
+ survived = true;
159
+ }
160
+ catch {
161
+ survived = false; // pgrep exits non-zero when nothing matches
162
+ }
163
+ expect(survived).toBe(false);
164
+ }, 120000);
165
+ it("destroy() removes the generated srt-settings temp directory", async () => {
166
+ // Regression: ensureSettingsFile() mkdtemp's a `srt-sandbox-*` dir under
167
+ // the OS temp dir for the generated policy file, but nothing removed it
168
+ // — every SrtSandbox instance that ran a command leaked one directory
169
+ // for the life of the host. Confirmed for real: a debugging session
170
+ // running this suite repeatedly had accumulated 80+ leaked directories
171
+ // in /tmp before this fix.
172
+ const before = new Set((await fs.readdir(os.tmpdir())).filter((d) => d.startsWith("srt-sandbox-")));
173
+ const sandbox = new SrtSandbox({ workdir });
174
+ const handle = await sandbox.attach();
175
+ const result = await run(handle, "echo hi");
176
+ expect(result.ok).toBe(true);
177
+ const afterRun = new Set((await fs.readdir(os.tmpdir())).filter((d) => d.startsWith("srt-sandbox-")));
178
+ const created = [...afterRun].filter((d) => !before.has(d));
179
+ expect(created.length).toBeGreaterThan(0);
180
+ await handle.destroy();
181
+ const afterDestroy = new Set((await fs.readdir(os.tmpdir())).filter((d) => d.startsWith("srt-sandbox-")));
182
+ for (const dir of created) {
183
+ expect(afterDestroy.has(dir)).toBe(false);
184
+ }
185
+ }, 120000);
186
+ });
187
+ describe("buildInstallHint", () => {
188
+ it("suggests installing all dependencies named in srt's message", () => {
189
+ const hint = buildInstallHint("Sandbox dependencies not available: ripgrep (rg) not found, bubblewrap (bwrap) not installed, socat not installed");
190
+ expect(hint).toContain("apt-get install -y ripgrep bubblewrap socat");
191
+ expect(hint).toContain("brew install ripgrep socat");
192
+ expect(hint).toContain("userns");
193
+ });
194
+ it("only mentions what the message actually names as missing", () => {
195
+ const hint = buildInstallHint("Sandbox dependencies not available: socat not installed");
196
+ expect(hint).toContain("apt-get install -y socat");
197
+ expect(hint).not.toContain("ripgrep");
198
+ expect(hint).not.toContain("bubblewrap");
199
+ });
200
+ it("returns an empty string for a message naming no known dependency", () => {
201
+ expect(buildInstallHint("some unrelated failure")).toBe("");
202
+ });
203
+ });
204
+ /**
205
+ * Preflight-check tests use a fake `srtCommand` (a tiny throwaway script)
206
+ * instead of the real srt/bwrap wrapper, so they exercise attach()'s
207
+ * fail-fast behavior deterministically on any platform/CI environment —
208
+ * unlike the "real isolation" suite above, they don't need bubblewrap,
209
+ * socat, or ripgrep actually installed.
210
+ */
211
+ describe("SrtSandbox preflight check (fake wrapper)", () => {
212
+ let workdir;
213
+ beforeEach(async () => {
214
+ workdir = await fs.mkdtemp(path.join(os.tmpdir(), "srt-preflight-wd-"));
215
+ });
216
+ afterEach(async () => {
217
+ await fs.rm(workdir, { recursive: true, force: true }).catch(() => { });
218
+ });
219
+ async function writeFakeSrt(script) {
220
+ const scriptPath = path.join(workdir, "fake-srt.cjs");
221
+ await fs.writeFile(scriptPath, script);
222
+ return [process.execPath, scriptPath];
223
+ }
224
+ it("attach() rejects immediately with an actionable message on a missing-dependency signature", async () => {
225
+ const srtCommand = await writeFakeSrt('console.error("Error: Sandbox dependencies not available: ripgrep (rg) not found, bubblewrap (bwrap) not installed, socat not installed"); process.exit(1);');
226
+ const sandbox = new SrtSandbox({ workdir, isolation: { srtCommand } });
227
+ await expect(sandbox.attach()).rejects.toThrow(/ripgrep/);
228
+ });
229
+ it("does not mislabel an unrelated startup failure as a missing dependency", async () => {
230
+ const srtCommand = await writeFakeSrt('console.error("Error: something else entirely broke"); process.exit(1);');
231
+ const sandbox = new SrtSandbox({ workdir, isolation: { srtCommand } });
232
+ await expect(sandbox.attach()).rejects.toThrow(/failed its startup preflight check/);
233
+ await expect(new SrtSandbox({ workdir, isolation: { srtCommand } }).attach()).rejects.not.toThrow(/apt-get install/);
234
+ });
235
+ it("attach() succeeds once the preflight probe passes", async () => {
236
+ const srtCommand = await writeFakeSrt("process.exit(0);");
237
+ const sandbox = new SrtSandbox({ workdir, isolation: { srtCommand } });
238
+ const handle = await sandbox.attach();
239
+ expect(handle).toBeDefined();
240
+ });
241
+ it("does not re-run the preflight probe on a second attach() (already attached)", async () => {
242
+ const scriptPath = path.join(workdir, "counting-srt.cjs");
243
+ const counterPath = path.join(workdir, "count.txt");
244
+ await fs.writeFile(counterPath, "0");
245
+ // Every invocation bumps a counter file — including the real payload
246
+ // args exec()/runCommand() would pass — but this test only calls
247
+ // attach() twice, so any increment beyond 1 means the probe re-ran.
248
+ await fs.writeFile(scriptPath, [
249
+ 'const fs = require("fs");',
250
+ `const p = ${JSON.stringify(counterPath)};`,
251
+ "fs.writeFileSync(p, String(Number(fs.readFileSync(p, 'utf8')) + 1));",
252
+ "process.exit(0);",
253
+ ].join("\n"));
254
+ const sandbox = new SrtSandbox({
255
+ workdir,
256
+ isolation: { srtCommand: [process.execPath, scriptPath] },
257
+ });
258
+ await sandbox.attach();
259
+ expect(Number(await fs.readFile(counterPath, "utf8"))).toBe(1);
260
+ await sandbox.attach();
261
+ expect(Number(await fs.readFile(counterPath, "utf8"))).toBe(1);
262
+ });
263
+ });
264
+ //# sourceMappingURL=srt-sandbox.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"srt-sandbox.test.js","sourceRoot":"","sources":["../../src/__tests__/srt-sandbox.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type { SrtIsolationOptions, SrtSandboxOptions, } from "./srt-sandbox.js";
2
+ export { SrtSandbox } from "./srt-sandbox.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { SrtSandbox } from "./srt-sandbox.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,126 @@
1
+ import type { SandboxHandle } from "@bunny-agent/manager";
2
+ import { LocalMachine, type LocalMachineOptions } from "@bunny-agent/sandbox-local";
3
+ /**
4
+ * Builds an actionable "how to fix this" hint appended to srt's own missing-
5
+ * dependency message. Only mentions dependencies srt's message actually
6
+ * named (never asserts what's needed on a platform we haven't confirmed).
7
+ * Exported for direct unit testing — not part of the package's public API.
8
+ */
9
+ export declare function buildInstallHint(srtMessage: string): string;
10
+ /**
11
+ * Isolation policy for {@link SrtSandbox}, mapped onto
12
+ * `@anthropic-ai/sandbox-runtime` (srt) settings.
13
+ *
14
+ * Defaults are deny-by-default where srt is deny-by-default:
15
+ * - Network: fully blocked unless domains are listed in `allowedDomains`.
16
+ * - Filesystem writes: only the sandbox workdir and the OS temp dir are
17
+ * writable unless more paths are listed in `allowWrite`.
18
+ * - Filesystem reads: allowed except paths listed in `denyRead`.
19
+ */
20
+ export interface SrtIsolationOptions {
21
+ /** Domains the sandboxed process may reach (supports `*.example.com`).
22
+ * Default: `[]` — no network access. */
23
+ allowedDomains?: string[];
24
+ /** Domains to always block (takes precedence over `allowedDomains`). */
25
+ deniedDomains?: string[];
26
+ /** Paths the sandboxed process may NOT read (e.g. `~/.ssh`). */
27
+ denyRead?: string[];
28
+ /** Extra writable paths, in addition to the workdir and the OS temp dir.
29
+ * Runners that write to the home directory (npm cache, session stores)
30
+ * need those paths listed here — e.g. `["~/.npm", "~/.bunny-agent"]`. */
31
+ allowWrite?: string[];
32
+ /** Paths to deny writes to even inside allowed paths. */
33
+ denyWrite?: string[];
34
+ /** Allow binding local ports (dev servers inside the sandbox). Default false. */
35
+ allowLocalBinding?: boolean;
36
+ /** Disable Unix-socket blocking (Linux: seccomp; macOS: Seatbelt). Default false. */
37
+ allowAllUnixSockets?: boolean;
38
+ /**
39
+ * Bring-your-own srt settings file. When set, it is passed to srt as-is and
40
+ * every other option in this object is ignored.
41
+ */
42
+ settingsPath?: string;
43
+ /**
44
+ * Override the wrapper invocation (argv prefix). Defaults to running the
45
+ * `srt` CLI bundled with `@anthropic-ai/sandbox-runtime` via the current
46
+ * Node executable.
47
+ */
48
+ srtCommand?: string[];
49
+ }
50
+ export interface SrtSandboxOptions extends LocalMachineOptions {
51
+ isolation?: SrtIsolationOptions;
52
+ }
53
+ /**
54
+ * A locally-isolated sandbox: same lifecycle and API as {@link LocalMachine},
55
+ * but every command is wrapped with Anthropic's sandbox runtime
56
+ * (`@anthropic-ai/sandbox-runtime`, the sandbox used by Claude Code), which
57
+ * enforces OS-level boundaries:
58
+ *
59
+ * - Linux: bubblewrap + network-namespace isolation (traffic must go through
60
+ * srt's host-side proxies)
61
+ * - macOS: `sandbox-exec` with a generated Seatbelt profile
62
+ * - Windows (alpha): a dedicated `srt-sandbox` user account + WFP egress fence
63
+ *
64
+ * The policy is allow-only for network and writes: by default the process
65
+ * can read the filesystem (minus `denyRead`), write only to the workdir and
66
+ * the OS temp dir, and reach no network at all.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { BunnyAgent } from "@bunny-agent/manager";
71
+ * import { SrtSandbox } from "@bunny-agent/sandbox-srt";
72
+ *
73
+ * const sandbox = new SrtSandbox({
74
+ * workdir: "/tmp/my-sandbox",
75
+ * isolation: {
76
+ * allowedDomains: ["api.anthropic.com", "*.npmjs.org"],
77
+ * denyRead: ["~/.ssh", "~/.aws"],
78
+ * allowWrite: ["~/.npm"],
79
+ * },
80
+ * });
81
+ *
82
+ * const handle = await sandbox.attach();
83
+ * // Runs inside the OS sandbox; writing outside the workdir fails.
84
+ * const result = await handle.runCommand("id && touch out.txt");
85
+ * ```
86
+ */
87
+ export declare class SrtSandbox extends LocalMachine {
88
+ protected readonly label: string;
89
+ private readonly isolation;
90
+ /** Generated settings file path; created lazily, stable per instance. */
91
+ private settingsFilePromise;
92
+ /** The mkdtemp'd directory holding the generated settings file — tracked
93
+ * separately so onDestroy() can remove it without re-deriving it from
94
+ * the (possibly not-yet-created) settings path. */
95
+ private generatedSettingsDir;
96
+ constructor(options?: SrtSandboxOptions);
97
+ /**
98
+ * Runs a cheap srt-wrapped no-op before doing any real work, so a missing
99
+ * platform dependency (bubblewrap, socat, ripgrep, ...) or an otherwise
100
+ * unusable sandbox surfaces immediately with an actionable message —
101
+ * instead of being discovered deep inside the first real `exec()` call,
102
+ * where it previously arrived as a generic "Command failed (exit 1)"
103
+ * with srt's raw stderr buried in the trace.
104
+ */
105
+ attach(): Promise<SandboxHandle>;
106
+ private preflightCheck;
107
+ protected transformCommand(command: string[]): Promise<string[]>;
108
+ /**
109
+ * Write the srt settings file derived from {@link SrtIsolationOptions}.
110
+ * The file lives under the OS temp dir, which is inside the sandbox's
111
+ * writable paths — so the policy explicitly denies writes to its own
112
+ * directory (`denyWrite` takes precedence over `allowWrite` in srt): a
113
+ * sandboxed process cannot edit its own policy for the next run.
114
+ */
115
+ private ensureSettingsFile;
116
+ /**
117
+ * Removes the generated `srt-sandbox-*` settings directory, if one was
118
+ * created (bring-your-own `settingsPath` never triggers this). Without
119
+ * this, every SrtSandbox instance that actually ran a command leaked one
120
+ * temp directory under the OS temp dir for the lifetime of the host —
121
+ * across many agent runs (each gets its own SrtSandbox instance) these
122
+ * accumulate indefinitely.
123
+ */
124
+ protected onDestroy(): Promise<void>;
125
+ }
126
+ //# sourceMappingURL=srt-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"srt-sandbox.d.ts","sourceRoot":"","sources":["../src/srt-sandbox.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AA6BpC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAkC3D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAClC;6CACyC;IACzC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;8EAE0E;IAC1E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,mBAA4B,KAAK,EAAE,MAAM,CAAgB;IAEzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,yEAAyE;IACzE,OAAO,CAAC,mBAAmB,CAAgC;IAC3D;;wDAEoD;IACpD,OAAO,CAAC,oBAAoB,CAAuB;gBAEvC,OAAO,GAAE,iBAAsB;IAK3C;;;;;;;OAOG;IACY,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;YAOjC,cAAc;cA6CH,gBAAgB,CACvC,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC;IAUpB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;;;;;;OAOG;cACsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAKpD"}
@@ -0,0 +1,216 @@
1
+ import { execFile } from "node:child_process";
2
+ import * as fs from "node:fs/promises";
3
+ import { createRequire } from "node:module";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import { LocalMachine, } from "@bunny-agent/sandbox-local";
7
+ const require = createRequire(import.meta.url);
8
+ /** The exact prefix srt uses when a required platform binary (bubblewrap,
9
+ * socat, ripgrep, ...) is missing — confirmed against
10
+ * `@anthropic-ai/sandbox-runtime@0.0.65` by a live repro with those
11
+ * binaries hidden from PATH. Matching on this signature (rather than
12
+ * guessing at srt's exact dependency list ourselves, which could drift out
13
+ * of sync with a future srt version) lets SrtSandbox tell "you're missing
14
+ * a dependency" apart from "the sandbox failed to start for some other
15
+ * reason" without duplicating srt's own platform-requirements logic. */
16
+ const MISSING_DEPS_SIGNATURE = "Sandbox dependencies not available";
17
+ /** Package names to suggest installing, keyed by the dependency name
18
+ * substring srt's own error message uses (see MISSING_DEPS_SIGNATURE's
19
+ * doc comment — these are read out of srt's message, not asserted
20
+ * independently, so an unlisted dependency just gets no extra hint
21
+ * rather than a wrong one). `bubblewrap` has no `brew` entry: it's a
22
+ * Linux-only sandboxing primitive, macOS uses Seatbelt instead. */
23
+ const DEPENDENCY_PACKAGE_NAMES = {
24
+ ripgrep: { apt: "ripgrep", brew: "ripgrep" },
25
+ bubblewrap: { apt: "bubblewrap" },
26
+ socat: { apt: "socat", brew: "socat" },
27
+ };
28
+ /**
29
+ * Builds an actionable "how to fix this" hint appended to srt's own missing-
30
+ * dependency message. Only mentions dependencies srt's message actually
31
+ * named (never asserts what's needed on a platform we haven't confirmed).
32
+ * Exported for direct unit testing — not part of the package's public API.
33
+ */
34
+ export function buildInstallHint(srtMessage) {
35
+ const lowerMessage = srtMessage.toLowerCase();
36
+ const missing = Object.keys(DEPENDENCY_PACKAGE_NAMES).filter((name) => lowerMessage.includes(name));
37
+ if (missing.length === 0) {
38
+ return "";
39
+ }
40
+ const aptPackages = missing
41
+ .map((name) => DEPENDENCY_PACKAGE_NAMES[name].apt)
42
+ .filter((pkg) => Boolean(pkg));
43
+ const brewPackages = missing
44
+ .map((name) => DEPENDENCY_PACKAGE_NAMES[name].brew)
45
+ .filter((pkg) => Boolean(pkg));
46
+ const lines = ["", "To fix:"];
47
+ if (aptPackages.length > 0) {
48
+ lines.push(` Debian/Ubuntu: sudo apt-get install -y ${aptPackages.join(" ")}`);
49
+ }
50
+ if (brewPackages.length > 0) {
51
+ lines.push(` macOS: brew install ${brewPackages.join(" ")}`);
52
+ }
53
+ if (missing.includes("bubblewrap")) {
54
+ lines.push(" Ubuntu 24.04+ additionally restricts unprivileged user namespaces by " +
55
+ "default, which bubblewrap needs — either " +
56
+ "`sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0` or grant " +
57
+ "an AppArmor profile permitting bwrap's `userns` (see docs/SANDBOX_ADAPTERS.md).");
58
+ }
59
+ return lines.join("\n");
60
+ }
61
+ /**
62
+ * A locally-isolated sandbox: same lifecycle and API as {@link LocalMachine},
63
+ * but every command is wrapped with Anthropic's sandbox runtime
64
+ * (`@anthropic-ai/sandbox-runtime`, the sandbox used by Claude Code), which
65
+ * enforces OS-level boundaries:
66
+ *
67
+ * - Linux: bubblewrap + network-namespace isolation (traffic must go through
68
+ * srt's host-side proxies)
69
+ * - macOS: `sandbox-exec` with a generated Seatbelt profile
70
+ * - Windows (alpha): a dedicated `srt-sandbox` user account + WFP egress fence
71
+ *
72
+ * The policy is allow-only for network and writes: by default the process
73
+ * can read the filesystem (minus `denyRead`), write only to the workdir and
74
+ * the OS temp dir, and reach no network at all.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * import { BunnyAgent } from "@bunny-agent/manager";
79
+ * import { SrtSandbox } from "@bunny-agent/sandbox-srt";
80
+ *
81
+ * const sandbox = new SrtSandbox({
82
+ * workdir: "/tmp/my-sandbox",
83
+ * isolation: {
84
+ * allowedDomains: ["api.anthropic.com", "*.npmjs.org"],
85
+ * denyRead: ["~/.ssh", "~/.aws"],
86
+ * allowWrite: ["~/.npm"],
87
+ * },
88
+ * });
89
+ *
90
+ * const handle = await sandbox.attach();
91
+ * // Runs inside the OS sandbox; writing outside the workdir fails.
92
+ * const result = await handle.runCommand("id && touch out.txt");
93
+ * ```
94
+ */
95
+ export class SrtSandbox extends LocalMachine {
96
+ label = "SrtSandbox";
97
+ isolation;
98
+ /** Generated settings file path; created lazily, stable per instance. */
99
+ settingsFilePromise = null;
100
+ /** The mkdtemp'd directory holding the generated settings file — tracked
101
+ * separately so onDestroy() can remove it without re-deriving it from
102
+ * the (possibly not-yet-created) settings path. */
103
+ generatedSettingsDir = null;
104
+ constructor(options = {}) {
105
+ super(options);
106
+ this.isolation = options.isolation ?? {};
107
+ }
108
+ /**
109
+ * Runs a cheap srt-wrapped no-op before doing any real work, so a missing
110
+ * platform dependency (bubblewrap, socat, ripgrep, ...) or an otherwise
111
+ * unusable sandbox surfaces immediately with an actionable message —
112
+ * instead of being discovered deep inside the first real `exec()` call,
113
+ * where it previously arrived as a generic "Command failed (exit 1)"
114
+ * with srt's raw stderr buried in the trace.
115
+ */
116
+ async attach() {
117
+ if (!this.getHandle()) {
118
+ await this.preflightCheck();
119
+ }
120
+ return super.attach();
121
+ }
122
+ async preflightCheck() {
123
+ const settingsPath = this.isolation.settingsPath ?? (await this.ensureSettingsFile());
124
+ const srtCommand = this.isolation.srtCommand ?? [
125
+ process.execPath,
126
+ require.resolve("@anthropic-ai/sandbox-runtime/dist/cli.js"),
127
+ ];
128
+ // A harmless payload: node itself is guaranteed present (we're running
129
+ // inside it right now), so the probe doesn't depend on `true`/`echo`
130
+ // existing, and it touches neither the filesystem nor the network.
131
+ const [cmd, ...args] = [
132
+ ...srtCommand,
133
+ "--settings",
134
+ settingsPath,
135
+ process.execPath,
136
+ "-e",
137
+ "process.exit(0)",
138
+ ];
139
+ await new Promise((resolve, reject) => {
140
+ execFile(cmd, args, { timeout: 15000 }, (error, _stdout, stderr) => {
141
+ if (!error) {
142
+ resolve();
143
+ return;
144
+ }
145
+ const message = (stderr || error.message).trim();
146
+ if (message.includes(MISSING_DEPS_SIGNATURE)) {
147
+ reject(new Error(`SrtSandbox cannot start: ${message}${buildInstallHint(message)}`));
148
+ return;
149
+ }
150
+ reject(new Error("SrtSandbox failed its startup preflight check (this usually means " +
151
+ "the sandboxing runtime — bubblewrap on Linux, Seatbelt on macOS — " +
152
+ `can't run in this environment): ${message}`));
153
+ });
154
+ });
155
+ }
156
+ async transformCommand(command) {
157
+ const settingsPath = this.isolation.settingsPath ?? (await this.ensureSettingsFile());
158
+ const srtCommand = this.isolation.srtCommand ?? [
159
+ process.execPath,
160
+ require.resolve("@anthropic-ai/sandbox-runtime/dist/cli.js"),
161
+ ];
162
+ return [...srtCommand, "--settings", settingsPath, ...command];
163
+ }
164
+ /**
165
+ * Write the srt settings file derived from {@link SrtIsolationOptions}.
166
+ * The file lives under the OS temp dir, which is inside the sandbox's
167
+ * writable paths — so the policy explicitly denies writes to its own
168
+ * directory (`denyWrite` takes precedence over `allowWrite` in srt): a
169
+ * sandboxed process cannot edit its own policy for the next run.
170
+ */
171
+ ensureSettingsFile() {
172
+ this.settingsFilePromise ??= (async () => {
173
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "srt-sandbox-"));
174
+ this.generatedSettingsDir = dir;
175
+ const settingsPath = path.join(dir, "srt-settings.json");
176
+ const settings = {
177
+ network: {
178
+ allowedDomains: this.isolation.allowedDomains ?? [],
179
+ deniedDomains: this.isolation.deniedDomains ?? [],
180
+ allowLocalBinding: this.isolation.allowLocalBinding ?? false,
181
+ allowAllUnixSockets: this.isolation.allowAllUnixSockets ?? false,
182
+ },
183
+ filesystem: {
184
+ denyRead: this.isolation.denyRead ?? [],
185
+ allowWrite: [
186
+ this.getWorkdir(),
187
+ os.tmpdir(),
188
+ ...(this.isolation.allowWrite ?? []),
189
+ ],
190
+ // The policy file itself (and its directory) must never be
191
+ // writable from inside the sandbox, even though it lives under
192
+ // the OS temp dir.
193
+ denyWrite: [dir, ...(this.isolation.denyWrite ?? [])],
194
+ },
195
+ };
196
+ await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));
197
+ console.log(`[${this.label}] Wrote srt settings: ${settingsPath}`);
198
+ return settingsPath;
199
+ })();
200
+ return this.settingsFilePromise;
201
+ }
202
+ /**
203
+ * Removes the generated `srt-sandbox-*` settings directory, if one was
204
+ * created (bring-your-own `settingsPath` never triggers this). Without
205
+ * this, every SrtSandbox instance that actually ran a command leaked one
206
+ * temp directory under the OS temp dir for the lifetime of the host —
207
+ * across many agent runs (each gets its own SrtSandbox instance) these
208
+ * accumulate indefinitely.
209
+ */
210
+ async onDestroy() {
211
+ if (this.generatedSettingsDir) {
212
+ await fs.rm(this.generatedSettingsDir, { recursive: true, force: true });
213
+ }
214
+ }
215
+ }
216
+ //# sourceMappingURL=srt-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"srt-sandbox.js","sourceRoot":"","sources":["../src/srt-sandbox.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@bunny-agent/sandbox-srt",
3
+ "version": "0.9.52-beta.1",
4
+ "description": "Locally-isolated sandbox adapter for BunnyAgent — wraps commands with Anthropic's sandbox runtime (srt)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/vikadata/bunny-agent.git",
21
+ "directory": "packages/sandbox-srt"
22
+ },
23
+ "license": "Apache-2.0",
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "engines": {
28
+ "node": ">=20.11.0"
29
+ },
30
+ "keywords": [
31
+ "sandbox",
32
+ "srt",
33
+ "isolation",
34
+ "bubblewrap",
35
+ "seatbelt",
36
+ "bunny-agent",
37
+ "adapter"
38
+ ],
39
+ "dependencies": {
40
+ "@anthropic-ai/sandbox-runtime": "^0.0.65",
41
+ "@bunny-agent/manager": "0.9.52-beta.1",
42
+ "@bunny-agent/sandbox-local": "0.9.52-beta.1"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.10.0",
46
+ "typescript": "^5.3.0",
47
+ "vitest": "^1.6.1"
48
+ },
49
+ "scripts": {
50
+ "build": "tsc",
51
+ "dev": "tsc --watch",
52
+ "clean": "rm -rf dist",
53
+ "typecheck": "tsc --noEmit",
54
+ "lint": "echo 'no lint configured'",
55
+ "test": "vitest run --passWithNoTests"
56
+ }
57
+ }