|
1 | | -# sandbox |
| 1 | +# SandBox |
| 2 | + |
| 3 | +Lightweight, OS-native sandboxing solution on macOS (`sandbox-exec`) and Linux (`bubblewrap`). |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- agentic code execution (AI agents): with minimal risk of data leaks or system compromise |
| 8 | +- secure-by-default dual isolation: Untrusted code runs with strong restrictions - filesystem isolation prevents secret exfiltration (e.g. SSH keys), while network isolation blocks unrestricted outbound access |
| 9 | +- minimal performance overhead: No containers / VMs required |
| 10 | +- blazingly fast startup times: milliseconds |
| 11 | +- cross-platform: macOS and Linux support |
| 12 | +- highly configurable: fine-grained control over network and filesystem access |
| 13 | +- easy to use: CLI and Node.js library |
| 14 | + |
| 15 | +## Usage |
| 16 | + |
| 17 | +### CLI |
| 18 | + |
| 19 | +```bash |
| 20 | +vsbx <command> # Run command sandboxed |
| 21 | +vsbx --debug <command> # Debug logging |
| 22 | +vsbx --settings <file> <command> # Custom config |
| 23 | +``` |
| 24 | + |
| 25 | +### Node.js Library |
| 26 | + |
| 27 | +```javascript |
| 28 | +import { type SandboxRuntimeConfig } from "@/core/sandbox/sandbox-config"; |
| 29 | +import { SandboxManager } from "@/core/manager/sandbox-manager"; |
| 30 | +import { spawn } from "node:child_process"; |
| 31 | + |
| 32 | +const config: SandboxRuntimeConfig = { |
| 33 | + network: { |
| 34 | + allowedDomains: ["example.com", "api.github.com"], |
| 35 | + deniedDomains: [], |
| 36 | + }, |
| 37 | + filesystem: { |
| 38 | + denyRead: ["~/.ssh"], |
| 39 | + allowWrite: [".", "/tmp"], |
| 40 | + denyWrite: [".env"], |
| 41 | + }, |
| 42 | +}; |
| 43 | + |
| 44 | +await SandboxManager.initialize(config); |
| 45 | +const sandboxedCommand = await SandboxManager.wrapWithSandbox( |
| 46 | + "curl https://example.com", |
| 47 | +); |
| 48 | +const child = spawn(sandboxedCommand, { shell: true, stdio: "inherit" }); |
| 49 | + |
| 50 | +child.on("exit", (code) => console.log(`Command exited with code ${code}`)); |
| 51 | +await SandboxManager.reset(); |
| 52 | +``` |
| 53 | + |
| 54 | +## Configuration |
| 55 | + |
| 56 | +```json |
| 57 | +{ |
| 58 | + "network": { |
| 59 | + "allowedDomains": [ |
| 60 | + "api.github.com", |
| 61 | + "registry.npmjs.org", |
| 62 | + "objects.githubusercontent.com" |
| 63 | + ] |
| 64 | + }, |
| 65 | + "filesystem": { |
| 66 | + "denyRead": ["~/.ssh", "~/.aws", "~/.config/gh"], |
| 67 | + "allowWrite": ["."] |
| 68 | + } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +### Configuration Options |
| 73 | + |
| 74 | +```json |
| 75 | +{ |
| 76 | + "network": { |
| 77 | + "allowedDomains": string[], // wildcards *. ok, empty = no network |
| 78 | + "deniedDomains": string[], // checked first, blocks even if in allowed |
| 79 | + "allowUnixSockets": string[], // macOS mostly - dangerous! |
| 80 | + "allowLocalBinding": boolean // default false - very dangerous |
| 81 | + }, |
| 82 | + "filesystem": { |
| 83 | + "denyRead": string[], // empty = read everywhere |
| 84 | + "allowWrite": string[], // empty = write nowhere ← most important! |
| 85 | + "denyWrite": string[] // exceptions inside allowWrite (stronger priority) |
| 86 | + }, |
| 87 | + "ignoreViolations": { // rare - mostly for tooling workarounds |
| 88 | + "<command-pattern>": string[] |
| 89 | + }, |
| 90 | + "enableWeakerNestedSandbox": boolean, // only for running inside Docker (much weaker!) |
| 91 | + "mandatoryDenySearchDepth": number // Linux only - how deep to scan for dangerous files (default: 3) |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +### Default Permissions |
| 96 | + |
| 97 | +| Resource | Default State | Restriction Style | How to open access | |
| 98 | +| -------------------- | -------------------------- | ---------------------- | ------------------------------------- | |
| 99 | +| Network | Completely blocked | Allow-list only | `allowedDomains: ["..."]` | |
| 100 | +| Filesystem - Read | Allowed everywhere | Deny-list only | `denyRead: ["~/.ssh"]` | |
| 101 | +| Filesystem - Write | Completely blocked | Allow-list + deny-list | `allowWrite: ["."]` + `denyWrite: []` | |
| 102 | +| Unix sockets (Linux) | Creation blocked (seccomp) | Explicit allow | `allowUnixSockets: [...]` | |
0 commit comments