A secure, generic sandboxing wrapper for any AI coding assistant or command-line tool. Works with Aider, code-puppy, Cursor, Copilot, or any other tool. Cross-platform support (Linux + macOS), inspired by Claude Code's sandboxing approach.
Tested on: Linux (Ubuntu) β | macOS β | Windows β
- Filesystem Isolation: Uses bubblewrap (Linux) or sandbox-exec (macOS) to restrict file access to working directory only
- Cross-Platform: Works on both Linux and macOS with platform-specific sandboxing
- Network Proxy: Routes all network traffic through a controlled proxy with domain allowlisting
- Permission System: User approval required for sensitive operations
- Sensitive Path Protection: Automatically blocks access to:
- SSH keys (
~/.ssh) - AWS credentials (
~/.aws) - Google Cloud credentials (
~/.config/gcloud) - Kubernetes config (
~/.kube) - GPG keys (
~/.gnupg) - Docker credentials (
~/.docker)
- SSH keys (
- Minimal Overhead: ~5-10ms per command execution
npm install -g bubblewrap
# or
npm install bubblewrapgit clone https://github.com/soodoku/bubblewrap.git
cd bubblewrap
npm install
npm run build
npm link # Optional: for global CLI access# Linux: Install bubblewrap
sudo apt-get install bubblewrap # Debian/Ubuntu
sudo dnf install bubblewrap # Fedora
sudo pacman -S bubblewrap # Arch
# macOS: sandbox-exec is included by default (no installation needed)
which sandbox-exec # Verify it's available
# Install your preferred AI coding assistant (optional)
pip install aider-chat # For Aider
npm install -g code-puppy # For code-puppy
# or use Cursor, Copilot, etc.# Execute any command in the sandbox
sandbox exec ls -la
sandbox exec python script.py
sandbox exec node app.js
# Run Aider with a message (if installed)
sandbox aider run "Add error handling to the login function" -f src/auth.ts
# Run code-puppy (if installed)
sandbox code-puppy run "Implement user authentication" -f src/auth.ts
# Run npm/git commands in sandbox
sandbox npm test
sandbox git status
# Or use the safe-code CLI
safe-code exec your-commandIf you installed globally with npm install -g bubblewrap, use:
sandbox exec <command>
safe-code exec <command>If installed locally, use via npm scripts or npx:
npx sandbox exec <command>
# or add to package.json scriptsimport { CommandWrapper } from 'bubblewrap';
// Create a sandboxed command wrapper
const wrapper = new CommandWrapper({
workingDir: process.cwd(),
autoApproveRead: false,
autoApproveWrite: false,
});
// Set up event handlers for permission requests
wrapper.on('permission-required', (data) => {
console.log(`Permission requested: ${data.type} for ${data.resource}`);
data.approve(); // or data.deny()
});
wrapper.on('network-approval-required', (data) => {
console.log(`Network access requested to: ${data.domain}`);
data.approve(); // or data.deny()
});
// Initialize the sandbox
await wrapper.initialize();
// Execute any command
const result = await wrapper.execute(['python', 'script.py']);
console.log(result.stdout);
// Clean up
await wrapper.shutdown();import { AiderWrapper, CodePuppyWrapper, GenericToolWrapper } from 'bubblewrap';
// For Aider
const aider = new AiderWrapper({
workingDir: process.cwd(),
model: 'gpt-4',
autoCommit: false,
});
await aider.initialize();
await aider.runMessage('Add validation', ['src/validator.ts']);
await aider.shutdown();
// For code-puppy
const codePuppy = new CodePuppyWrapper({
workingDir: process.cwd(),
model: 'claude-3-5-sonnet',
provider: 'anthropic',
});
await codePuppy.initialize();
await codePuppy.runPrompt('Implement auth', ['src/auth.ts']);
await codePuppy.shutdown();
// Generic tool wrapper with convenience methods
const tool = new GenericToolWrapper({ workingDir: process.cwd() });
await tool.initialize();
await tool.runNpm('test');
await tool.runGit(['status']);
await tool.shutdown();βββββββββββββββββββββββββββββββββββββββββββββββ
β Any Tool (Aider, code-puppy, npm, git...) β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββββββ
β CommandWrapper / SandboxManager β
β - Permission system β
β - Domain allowlist/blocklist β
β - Filesystem path restrictions β
βββββββββββ¬ββββββββββββββββββββ¬ββββββββββββββββ
β β
βββββββββββΌβββββββββββ βββββββΌβββββββββββββββ
β Filesystem Sandbox β β Network Proxy β
β (bubblewrap/macOS) β β (Unix socket) β
β β β β
β - Unshare all β β - Domain filter β
β - Bind mounts β β - User approval β
β - Read-only /usr β β - Traffic logging β
ββββββββββββββββββββββ ββββββββββββββββββββββ
Uses Linux namespaces via bubblewrap to:
- Restrict write access to working directory only
- Block access to sensitive files (SSH keys, cloud credentials)
- Mount system directories as read-only
- Isolate process tree
- All network traffic routed through Unix socket proxy
- Domain allowlisting (github.com, npmjs.com, pypi.org by default)
- User approval required for new domains
- Blocked domain list support
- Granular permission types:
fs:read- Read file accessfs:write- Write file accessnet:access- Network accessproc:spawn- Process execution
- Time-limited permissions (1 hour default)
- Auto-approval configuration
- Permission revocation
{
workingDir: process.cwd(),
allowedReadPaths: ['/usr', '/lib', '/lib64', '/bin', '/etc/ssl'],
allowedWritePaths: [process.cwd()],
deniedPaths: [
'~/.ssh',
'~/.aws',
'~/.config/gcloud',
'~/.gnupg',
'~/.kube',
'~/.docker',
'/etc/passwd',
'/etc/shadow',
'/etc/sudoers',
],
enableNetworkProxy: true,
allowedDomains: [
'github.com',
'raw.githubusercontent.com',
'npmjs.com',
'pypi.org',
'registry.npmjs.org',
'api.github.com',
],
requireApprovalForNewDomains: true,
}import { SandboxManager, CommandWrapper, PermissionType } from 'bubblewrap';
// Using SandboxManager directly
const sandbox = new SandboxManager(process.cwd(), {
allowedDomains: ['*.example.com', 'api.myservice.com'],
blockedDomains: ['evil.com'],
requireApprovalForNewDomains: false,
});
// Enable auto-approval for file reads
sandbox.setAutoApprove([PermissionType.FILESYSTEM_READ]);
await sandbox.initialize();
// Or using CommandWrapper with custom config
const wrapper = new CommandWrapper({
workingDir: process.cwd(),
allowedDomains: ['github.com', 'npmjs.com'],
autoApproveRead: true,
autoApproveWrite: false,
});
await wrapper.initialize();# Run tests
npm test
# Run with coverage
npm run test:coverageThe test suite includes security validation:
- β Blocks access to SSH keys
- β Blocks access to AWS credentials
- β Blocks access to GCloud credentials
- β Allows access to working directory
- β Network traffic routes through proxy
- β Permission system enforces approvals
Based on testing:
- Command execution overhead: ~5-10ms
- Memory overhead: ~2-5MB
- Permission check latency: <1ms
- Linux: Full support with bubblewrap β
- macOS: Full support with sandbox-exec β
- Windows: Not supported (would need WSL2 or App Containers)
Interactive Aider sessions bypass some sandbox protections for usability. Use non-interactive mode for maximum security.
- Unix socket proxy currently supports HTTP/HTTPS
- Some protocols may not be fully supported
- DNS resolution happens outside sandbox
This implementation is inspired by Claude Code's sandboxing approach:
| Feature | Claude Code | Bubblewrap |
|---|---|---|
| Filesystem Isolation | β | β |
| Network Proxy | β | β |
| Permission System | β | β |
| Sensitive Path Protection | β | β |
| Platform | Linux/macOS | Linux/macOS |
| Tool Support | Claude only | Any tool (Aider, code-puppy, etc.) |
| Implementation | Proprietary | Open Source |
| Automated Testing | Unknown | GitHub Actions (both platforms) |
| Resource Limiting | Unknown | CPU/RAM limits β |
Full documentation is available at: https://soodoku.github.io/bubblewrap/
See the examples directory for more usage examples:
- Generic Command - Run any command in sandbox
- Tool Wrappers - Use convenience wrappers
- Basic Usage - Aider-specific example
- Custom Configuration - Advanced config
- Permission Handling - Permission system
Contributions welcome! Please read our contributing guidelines.
MIT
- AI Coding Assistants: Run Aider, code-puppy, or similar tools safely
- CI/CD Pipelines: Sandbox untrusted build scripts
- Code Review: Execute untrusted code changes in isolation
- Development: Test tools without risking your system
- Education: Teach coding in a safe environment
- Inspired by Anthropic's Claude Code sandboxing approach
- Works great with Aider, code-puppy, and other AI coding assistants
- Uses bubblewrap for Linux sandboxing
- Uses sandbox-exec for macOS sandboxing
If you discover a security vulnerability, please open a GitHub issue or contact the maintainers directly.