Self-sovereign infrastructure platform with secure, encrypted NixOS deployments
Run AI coding agents (Claude Code, Gemini CLI, Codex) in isolated, secure MicroVM sandboxes.
The Agent Sandbox provides isolated environments where AI agents can operate autonomously without requiring permission prompts for file changes, command execution, or network access. Your host system remains protected while agents work freely.
Key Benefits:
/dev/kvm must exist)~/.ssh/ for passwordless authenticationCheck KVM availability:
ls -la /dev/kvm
# Should show the device exists
# 1. Navigate to your project
cd ~/projects/my-app
# 2. Start a sandbox (builds on first run, ~2 min)
keystone agent start
# 3. You're now SSH'd into the sandbox at /workspace
# Run your agent, make changes, etc.
# 4. Detach with Ctrl-D or 'exit'
# 5. Sync committed changes back to host
keystone agent sync
# 6. Stop the sandbox when done
keystone agent stop
cd ~/projects/my-web-app
keystone agent start
What happens:
First run takes ~2 minutes to build. Subsequent starts are faster (~30 seconds).
Inside the sandbox:
/workspace/sandbox user has sudo accessThe sandbox is isolated - it cannot push directly to your host. Instead, use keystone agent sync to pull changes:
# Inside sandbox: make changes and commit
cd /workspace
git add .
git commit -m "Agent's improvements"
# Exit sandbox (Ctrl-D or 'exit')
# On host: sync the changes
keystone agent sync
Sync behavior:
git fetch + git merge --ff-only for safetyPreview before syncing:
keystone agent sync --dry-run
Sync build artifacts too:
keystone agent sync --artifacts
# Syncs: dist/, build/, target/, .next/, out/
By default, sandbox names are derived from the project directory. You can run multiple:
# Terminal 1: Web frontend
cd ~/projects/frontend
keystone agent start --no-attach
# Terminal 2: API backend
cd ~/projects/backend
keystone agent start --no-attach
# See all running sandboxes
keystone agent list
# Attach to a specific one
keystone agent attach backend
Custom names:
keystone agent start --name my-custom-sandbox
Sandboxes persist between sessions. To reconnect:
# Check status
keystone agent status my-app
# Reattach
keystone agent attach my-app
# or
keystone agent ssh my-app
Starting fresh:
keystone agent start --fresh
# Discards previous state and starts clean
# Run a single command
keystone agent exec my-app -- npm test
# Check git status in sandbox
keystone agent exec my-app -- git -C /workspace status
# Multiple commands
keystone agent exec -- bash -c "cd /workspace && npm install && npm test"
Launch a sandbox for a project.
keystone agent start [path] [options]
Arguments:
path - Project directory (default: current directory)Options:
| Option | Description |
|——–|————-|
| --name <name> | Custom sandbox name (default: directory name) |
| --memory <MB> | RAM allocation (default: 8192) |
| --vcpus <N> | Virtual CPUs (default: 4) |
| --no-nested | Disable nested virtualization |
| --fresh | Discard previous state |
| --no-attach | Don’t auto-attach after starting |
| --network <mode> | Network mode: user, tap, macvtap, bridge (default: user) |
| --sync-mode <mode> | Sync mode: manual, auto-commit, auto-idle (default: manual) |
Exit codes:
0 - Success1 - Not a git repository2 - Sandbox already running (use --fresh or attach)3 - Build failed4 - KVM not availableStop a running sandbox.
keystone agent stop [name] [options]
Options:
| Option | Description |
|——–|————-|
| --sync | Sync changes before stopping |
SSH into a running sandbox.
keystone agent attach [name]
keystone agent ssh [name]
These commands are equivalent. Detach with Ctrl-D or exit.
Run a command in the sandbox.
keystone agent exec [name] -- <command>
Example:
keystone agent exec -- ls -la /workspace
keystone agent exec my-app -- npm run build
Sync committed changes from sandbox to host.
keystone agent sync [name] [options]
Options:
| Option | Description |
|——–|————-|
| --dry-run | Preview what would be synced |
| --artifacts | Also sync build directories |
Exit codes:
0 - Sync completed1 - Sandbox not found or not running2 - No changes to sync3 - Merge conflict (manual resolution needed)Show sandbox status.
keystone agent status [name] [options]
Options:
| Option | Description |
|——–|————-|
| --json | Output as JSON |
List all sandboxes.
keystone agent list [options]
Options:
| Option | Description |
|——–|————-|
| --json | Output as JSON |
Remove a sandbox completely.
keystone agent destroy <name> [options]
Options:
| Option | Description |
|——–|————-|
| --force | Skip confirmation, force destroy if running |
All sandbox state is stored in ~/.config/keystone/agent/:
~/.config/keystone/agent/
├── sandboxes.json # Registry of all sandboxes
└── sandboxes/
└── <sandbox-name>/
├── workspace/ # Git clone of your project
└── state/
├── flake.nix # Generated NixOS configuration
├── runner/ # MicroVM runner scripts
└── microvm.pid # Process ID when running
| Resource | Default | Minimum |
|---|---|---|
| Memory | 8192 MB | 2048 MB |
| vCPUs | 4 | 1 |
| Network | user mode | - |
The agent automatically detects SSH keys in this order:
~/.ssh/id_ed25519.pub~/.ssh/id_rsa.pub~/.ssh/id_ecdsa.pubIf no key is found, password authentication is enabled with password sandbox.
Generate an SSH key:
ssh-keygen -t ed25519
Error: KVM is not available on this system
Solutions:
lsmod | grep kvmsudo modprobe kvm_intel or sudo modprobe kvm_amdError: Failed to build MicroVM
Solutions:
keystone agent start --freshError: Permission denied or Connection refused
Solutions:
keystone agent status)ss -tlnp | grep 2223ssh -p 2223 sandbox@localhost (password: sandbox)Solution: Use force destroy:
keystone agent destroy <name> --force
Or manually kill the process:
kill $(cat ~/.config/keystone/agent/sandboxes/<name>/state/microvm.pid)
/workspace//workspace/ (via 9p)keystone agent sync