Bashlet
Sandboxed bash execution for AI agents.
Bashlet provides a secure sandbox for AI agents to execute shell commands, with support for multiple isolation backends:
- Wasmer (WASM) - Cross-platform, lightweight sandbox
- Firecracker (microVM) - Full Linux VM isolation on Linux with KVM
Installation
Quick Install (macOS/Linux)
|
This installs bashlet along with:
- Wasmer - For WASM sandbox (all platforms)
- Firecracker - For microVM sandbox (Linux only)
All dependencies are automatically downloaded if not present at runtime.
From Source
The binary will be at ./target/release/bashlet.
Usage
One-Shot Command Execution
Run a single command in an isolated sandbox:
With a mounted directory:
With environment variables:
Selecting a Backend
By default, bashlet automatically selects the best available backend (auto). You can explicitly choose a backend:
# Use Wasmer (WASM sandbox)
# Use Firecracker (microVM, Linux only)
# Auto-select (default)
Session Management
Sessions allow you to create persistent sandbox environments that maintain their configuration across multiple commands.
Create a Session
With TTL (time-to-live):
Run Commands in a Session
Run and Create in One Step
Use -C / --create to automatically create the session if it doesn't exist:
# Creates 'dev' session if missing, then runs the command
# Subsequent runs reuse the existing session
This is useful for scripts where you want idempotent behavior.
List Active Sessions
Output:
ID NAME CREATED TTL MOUNTS
----------------------------------------------------------------------
abc123 my-session 2024-01-10 15:20 - ./src:/workspace
def456 temp-session 2024-01-10 15:25 1h ./data:/data
Terminate a Session
Presets
Presets allow you to define reusable environment configurations with mounts, environment variables, and setup commands. This is ideal for creating consistent development environments.
Defining Presets
Add presets to your configuration file (~/.config/bashlet/config.toml):
[]
= [
["/usr/local/bin/kubectl", "/usr/local/bin/kubectl", true],
["~/.kube", "/home/.kube", true]
]
= [["KUBECONFIG", "/home/.kube/config"]]
= ["kubectl version --client"]
[]
= [["~/.npm", "/home/.npm", false]]
= [["NODE_ENV", "development"]]
= "/app"
Using Presets
Apply a preset when creating sessions or running commands:
# Create a session with a preset
# One-shot command with a preset
# Run with auto-create and preset
Preset Configuration Options
| Field | Description |
|---|---|
backend |
Backend override: wasmer, firecracker, or auto |
mounts |
Mount specifications: [[host, guest, readonly], ...] |
env_vars |
Environment variables: [[KEY, VALUE], ...] |
workdir |
Working directory inside sandbox |
setup_commands |
Commands to run when session is created |
rootfs_image |
Custom rootfs image path (Firecracker only) |
Persistent Storage with Presets
Mount a host directory for data that persists across sessions:
[]
= [
["~/.bashlet/data/myenv", "/data", false] # writable persistent storage
]
= ["test -d /data/cache || mkdir -p /data/cache"]
Firecracker with Persistent Rootfs
For full Linux environment persistence, use Firecracker with a custom rootfs image:
[]
= "firecracker"
= "~/.bashlet/images/dev.ext4"
= ["echo 'VM ready'"]
Changes to the rootfs (installed packages, modified files) persist across sessions.
Command Reference
| Command | Description |
|---|---|
bashlet exec "command" |
One-shot command execution in sandbox |
bashlet exec --preset NAME "command" |
One-shot with preset configuration |
bashlet create |
Create a new persistent session |
bashlet create --preset NAME |
Create session with preset |
bashlet run SESSION "command" |
Run command in an existing session |
bashlet run SESSION -C "command" |
Run command, creating session if missing |
bashlet run SESSION -C --preset NAME "command" |
Run with auto-create and preset |
bashlet list |
List all active sessions |
bashlet terminate SESSION |
Terminate a session |
Exec Options
bashlet exec [OPTIONS] <COMMAND>
Arguments:
<COMMAND> The shell command to execute
Options:
-p, --preset <PRESET> Apply a preset configuration
-m, --mount <MOUNT> Mount host directories (host_path:guest_path[:ro])
-e, --env <ENV> Environment variables (KEY=VALUE)
-w, --workdir <DIR> Working directory in sandbox [default: /workspace]
-b, --backend <BACKEND> Sandbox backend: auto, wasmer, firecracker [default: auto]
-v, --verbose Enable verbose output
-h, --help Print help
Create Options
bashlet create [OPTIONS]
Options:
-n, --name <NAME> Session name (auto-generated if not provided)
-p, --preset <PRESET> Apply a preset configuration
-m, --mount <MOUNT> Mount host directories (host_path:guest_path[:ro])
-e, --env <ENV> Environment variables (KEY=VALUE)
-w, --workdir <DIR> Working directory in sandbox [default: /workspace]
--ttl <TTL> Time-to-live (e.g., 30m, 1h, 2d)
-h, --help Print help
Run Options
bashlet run [OPTIONS] <SESSION> <COMMAND>
Arguments:
<SESSION> Session ID or name
<COMMAND> The shell command to execute
Options:
-C, --create Create the session if it doesn't exist
-p, --preset <PRESET> Apply a preset configuration (requires --create)
-m, --mount <MOUNT> Mount host directories (requires --create)
-e, --env <ENV> Environment variables (requires --create)
--workdir <DIR> Working directory in sandbox (requires --create)
--ttl <TTL> Time-to-live (requires --create)
-h, --help Print help
Mount Syntax
Mounts follow Docker-style syntax:
| Format | Description |
|---|---|
./src:/workspace |
Mount ./src to /workspace (read-write) |
./src:/workspace:ro |
Mount ./src to /workspace (read-only) |
TTL Syntax
| Format | Description |
|---|---|
30m |
30 minutes |
1h |
1 hour |
2d |
2 days |
Backends
Auto (Default)
Automatically selects the best available backend:
- Uses Firecracker on Linux with KVM support
- Falls back to Wasmer on other platforms
Wasmer
WASM-based sandbox using Wasmer runtime.
| Feature | Support |
|---|---|
| Platforms | macOS, Linux, Windows |
| Startup time | ~50ms |
| Isolation | WASM sandbox |
| Native Linux commands | Limited (WASI/WASIX) |
| Networking | No |
Firecracker
MicroVM-based sandbox using Firecracker.
| Feature | Support |
|---|---|
| Platforms | Linux with KVM |
| Startup time | ~125ms (VM boot) |
| Isolation | Hardware-level VM |
| Native Linux commands | Full support |
| Networking | Optional |
Requirements for Firecracker:
- Linux kernel with KVM support
- Access to
/dev/kvm(add user tokvmgroup)
# Check KVM support
# Add user to kvm group if needed
How It Works
Wasmer Backend
- Auto-download: Downloads Wasmer binary and bash WEBC package on first run
- Execution: Commands run via
wasmer runwith directory mounts and env vars - Isolation: WASM sandbox provides memory and filesystem isolation
Firecracker Backend
- Auto-download: Downloads Firecracker binary, Linux kernel, and rootfs on first run
- VM Boot: Starts a lightweight microVM (~5MB memory overhead)
- Guest Agent: Communicates with VM via vsock for command execution
- Isolation: Hardware-level isolation via KVM
Session Persistence
Sessions are stored as JSON files and can be resumed across CLI invocations.
Cache Locations
| Platform | Cache Directory |
|---|---|
| macOS | ~/Library/Caches/com.bashlet.bashlet/ |
| Linux | ~/.cache/bashlet/ |
| Windows | %LOCALAPPDATA%\bashlet\cache\ |
Session Storage
| Platform | Sessions Directory |
|---|---|
| macOS | ~/Library/Application Support/com.bashlet.bashlet/sessions/ |
| Linux | ~/.local/share/bashlet/sessions/ |
| Windows | %APPDATA%\bashlet\sessions\ |
Configuration
Configuration is stored in ~/.config/bashlet/config.toml (or platform equivalent).
Example configuration:
[]
= "auto" # auto, wasmer, or firecracker
= "/workspace"
= 256
= 300
[]
= 1
= false
# Presets for reusable environment configurations
[]
= [
["/usr/local/bin/kubectl", "/usr/local/bin/kubectl", true],
["~/.kube", "/home/.kube", true]
]
= [["KUBECONFIG", "/home/.kube/config"]]
= ["kubectl version --client"]
[]
= [["~/.bashlet/data/python", "/data", false]]
= [["PYTHONUNBUFFERED", "1"]]
= "/app"
[]
= "firecracker"
= "~/.bashlet/images/dev.ext4"
= [["EDITOR", "vim"]]
License
MIT