Skip to content

Commit 031d144

Browse files
committed
init
1 parent 1153c69 commit 031d144

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+9476
-1
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
jobs:
10+
integration-tests:
11+
name: Tests (${{ matrix.os }} / ${{ matrix.arch }})
12+
runs-on: ${{ matrix.runner }}
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- arch: x86-64
19+
runner: ubuntu-24.04
20+
os: linux
21+
- arch: arm64
22+
runner: ubuntu-24.04-arm
23+
os: linux
24+
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@v4
28+
29+
- name: Setup Node.js
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version: "24"
33+
34+
- name: Setup Bun
35+
uses: oven-sh/setup-bun@v2
36+
with:
37+
bun-version: 1.3.1
38+
39+
- name: Prepare environment
40+
if: matrix.os == 'linux'
41+
run: |
42+
sudo apt-get update
43+
sudo apt-get install -y bubblewrap libseccomp-dev gcc socat ripgrep apparmor-profiles zsh qemu-user-static binfmt-support
44+
sudo chmod u+s $(which bwrap)
45+
bwrap --ro-bind / / --unshare-net true && echo "bwrap namespace creation works" || echo "bwrap namespace creation still fails"
46+
47+
- name: Install Node dependencies and build
48+
run: bun install --frozen-lockfile && bun run build && bun run postbuild
49+
50+
- name: Lint code
51+
run: bun run lint
52+
53+
- name: Run tests
54+
run: bun run test

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Node.js
2+
node_modules
3+
dist
4+
5+
# Logs
6+
logs
7+
*.log
8+
9+
# OS
10+
Thumbs.db
11+
Desktop.ini
12+
.DS_Store
13+
14+
#IDE
15+
.vscode

README.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,102 @@
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

Comments
 (0)