a virtual machine for your AI agents

Your agent works in a VM. Not on your machine.

An agent is a shell with your permissions, and it does whatever the prompt asks. AIBox runs it inside a virtual machine with its own kernel, its own filesystem and no way back: the only thing it shares with the host is the folder you choose.

KVM / QEMU + libvirt its own kernel outbound traffic only nothing collected, nothing in the cloud
aibox web — 127.0.0.1:8787
The AIBox web console, overview tab
the model

One shared folder, and the agent stays inside

The day to day workflow is deliberately narrow. AIBox sets up a virtual machine, shares one directory with it, and gives the agent the harnesses it needs. Everything else stays where it belongs.

1A folder, shared both ways

The host share is mounted in the guest with virtiofs. The agent works there, exactly as it would work in a directory on your machine.

  • →The agent reads and writes the shared folder, and nothing else
  • →Your keys, your SSH agent, your cloud credentials stay on the host
  • →The folder is yours to choose: a worktree, a scratch space, a repo

2Local commits, and you push

Without credentials in the guest, the agent can commit but it cannot push. You keep the last word on what leaves your machine.

  • →The agent commits locally in the shared folder
  • →It has no git credentials, so it cannot push to your remotes
  • →You read the diff and push, from the host, with your own keys
→ AIBox is not a sandbox that certifies anything. It is a boundary that is easy to set up and hard to cross by accident: the guest has its own kernel, the host filesystem is not in its namespace, and the network is outbound only unless you open it yourself.
isolation

What actually separates the agent from your machine

The same agent, in three places. The difference is not a policy file, it is what the kernel and the hypervisor enforce.

what
on your machine
in a container
in a virtual machine
Kernel
The host kernel, with your uid
The host kernel, shared with the host
Its own kernel, in the guest
Files
Everything your user can read
The host filesystem, unless you mount it carefully
Only the guest filesystem
Credentials
SSH keys, cloud credentials, browser sessions
Same, as soon as you mount the home or pass a socket
None, unless you put them there
Devices
The real ones, with your permissions
The host devices, when the runtime is not careful
Emulated, through the hypervisor
Network
Your network, your host name, your ports
Your network, with a bridge or host mode
NAT, outbound only, inbound closed
Escape
No escape needed, it is already there
A kernel or runtime flaw is a host compromise
The guest kernel is the wall, root included
Blast radius
Your workstation
Your workstation
One disk image you can throw away

Scroll the table to see the three columns.

→ A container is the right tool to isolate a build. It is a configuration, not a guarantee: the usual development setups bind the home directory, mount the Docker socket, or run with extra capabilities, and each of those puts the host back in reach. A virtual machine moves the boundary into the kernel, where the agent has no say.
good practices

How to use the box without shooting yourself in the foot

The box protects the host from the agent. It does not protect the agent from the internet, and it does not protect you from your own habits. A few rules keep the value high.

1

Never put your keys in the guest

No SSH key, no git credential, no ~/.aws, no token file. The guest is the one place you cannot watch. An agent that finds a key will use it.

2

Share only what the task needs

The share is the one door between the host and the agent. A worktree for the current task is enough; sharing your whole home is not.

3

Keep the box closed to the network

The guest is behind NAT: it can reach the internet, the internet cannot reach it. Leave it that way unless you need a service to be reachable, and open it per service.

4

Snapshot before a risky run

A snapshot takes seconds and gives you a way back. A broken agent becomes an interesting state to look at instead of a lost afternoon.

5

Read the diff before you push

The agent commits locally because it has no credentials. That is the point: you are the one deciding what goes out.

6

Know what the agent can still reach

The agent has outbound internet access, like any program you run. AIBox collects nothing and sends nothing, but what the agent does with the network is between you and your provider.

playground

A box you can break, reset and throw away

Setting up a sandboxed agent environment is not hard, but it is tedious, and it is easy to get wrong. AIBox does the boring part so that managing the box is not a second project.

1

One-command setup

A guided setup builds the guest, the SSH access, the services and the tunnel, step by step. Every answer is saved.

2

Snapshots and resets

Snapshot before a risky run, revert in a click, and keep the broken state around to study it.

3

A local web console

Services, updates, setup steps, snapshots and the VM lifecycle, in a tab that stays on your machine.

4

VS Code, two ways

The Remote-SSH extension on your VS Code, or the VS Code Server running inside the guest. Both are installed for you.

5

One tunnel per service

Each service gets its own port forward and its own bind address. Localhost by default, the network only when you ask.

6

LAN exposure on demand

Expose a single service to the network, per service, without opening the whole VM to the world.

7

The harnesses, wired

Everything needed to install, update and expose opencode, Claude Code and the DeepSeek Harness is already handled.

8

Easy updates

Check the host and the VM, then update a service, the scripts, the OS or all of them, one target at a time.

network

Outbound by default, one door in

The VM sits behind NAT. It can reach the internet, the internet cannot reach it, and the only path from your machine to the guest is the SSH tunnel.

Your machine aibox CLI · web console ssh Tunnel ssh -N, one -L per service ssh kernel boundary AIBox VM KVM guest · virtiofs share per service Service opencode · dsh · claude localhost:4096 on demand LAN only if you allow it
how it works

Three commands and you have a box

Clone the repository, run the setup, then pick how you want to work: the shell, the console or VS Code.

step 1

Set the box up

The setup creates the guest image, generates a key pair for it, installs the packages, the services and the tunnel, and shares the folder. Every answer is saved, so a second run only asks what changed.

clone & setup
git clone git@github.com:malko/aibox.git
cd aibox && ./setup.sh
step 2

Open a shell in the guest

One command opens an SSH session in the virtual machine, with every service already forwarded to the right local port. This is where your agent works.

connect
./aibox
step 3

Or drive the box from the browser

The local console shows the services with a live availability dot, and gives you the VM controls, the snapshots and the updates. It stops when you close the tab.

web console
./aibox web
→ The tunnel is a systemd user service, so it comes back with your session even without a terminal. The virtual machine itself is not started automatically: the host does not restart it after a reboot, and you start it with aibox start.
the console

A convenience, not a service

The console exists for the people who would rather click than type, and for the moments when a browser is nicer than a terminal. It is not something you are meant to leave running.

↓

It stops with the tab

Closing the browser tab asks the console to stop, a few seconds later. There is no daemon left behind, and no port left open.

↓

It listens on 127.0.0.1 only

The console is never reachable from the network. When the configured port is busy, it takes the next free one instead of failing.

↓

A token per session

A random token is generated at every start and passed in the URL fragment. The API also rejects foreign Host and Origin headers, so another site cannot drive your console.

↓

The root password is asked, never kept

A step that needs sudo asks for the password at that moment. It stays in one shell variable for that step, is never written to a file, never appears in a command line, and is gone when the step ends.

aibox web — overview
Overview tab of the AIBox web console
01Overview — VM and tunnel state.
aibox web — services
Services tab of the AIBox web console
02Services — Every service with its port.
aibox web — snapshots
Snapshots tab of the AIBox web console
03Snapshots — Create a snapshot before a risky change.
vs code

Two ways to open the guest

Both are supported, and both are installed for you. Pick the one that fits how you work.

remote-sshYour VS Code, over SSH

The Remote-SSH extension connects to the guest through the same tunnel as everything else. The host path is mapped to the guest path, so you open a local folder and edit it remotely.

  • →Your own VS Code, your own settings, your own extensions
  • →aibox vscode opens it on the right folder

vs code serverThe server, inside the guest

The setup installs the VS Code Server in the guest, so a browser based VS Code can run entirely inside the virtual machine.

  • →The editor itself runs in the guest, not on your host
  • →Kept up to date with aibox update vscode-server
commands

The CLI stays out of your way

A dozen commands cover the whole life of the box. Everything is scriptable, nothing is interactive-only.

aibox startStart the VM and the tunnel
aibox statusState, service URLs, tunnel state
aibox webOpen the local web console
aibox exec <cmd>Run a command in the VM
aibox tunnel <cmd>Tunnel and LAN exposure
aibox vscode [dir]Open the VM in VS Code
aibox service-add <n> <p>Add a service
aibox service-listList the services
aibox snapshot <cmd>Create, list or delete snapshots
aibox update <target>Update a target
aibox check-updatesCheck for updates
aibox setup [step]Run the setup steps
aibox shutdownStop the tunnel and the VM
requirements

Almost nothing

A Linux host with KVM, and a guest image. That is the whole list.

host

  • KVM/QEMU with libvirt
  • virsh and libvirt-client
  • BusyBox httpd for the web console
  • A Linux distribution, on bare metal or on a workstation

guest

  • Ubuntu or Debian, with SSH access
  • 4 GB of RAM, 4 cores recommended
  • A dedicated user with sudo rights
  • The share is mounted with virtiofs
→ macOS is not supported yet: the Lima based support is being finished, and it will land here. Windows is not planned, the host scripts assume a Linux system with libvirt.
faq

The questions people actually ask

Short answers, including the limits.

Can the agent reach my files?
Only the ones in the shared folder, and the ones inside the guest. Your SSH keys, your browser sessions and the rest of the workstation are not in the guest's filesystem.
Why a virtual machine and not Docker?
A container shares the host kernel and, in most development setups, the host home directory or the Docker socket. A virtual machine has its own kernel, and the host filesystem is simply not in its namespace. For a build, a container is enough. For an agent that writes and runs its own code, the boundary has to be below the process.
Is the box really isolated?
It is a boundary, not a proof. The share is a real door, the agent has outbound internet access, and a bridged network or a forwarded port would open the guest. What AIBox does is make the safe configuration the default one, and the unsafe one something you have to ask for explicitly.
Does the agent have internet access?
Yes, like any program you run: the guest is behind NAT, so it can reach the internet and the internet cannot reach it. AIBox itself collects nothing and sends nothing, but what your agent does with the network depends on your provider and on you.
What if the agent breaks everything?
You take a snapshot before it starts, and you revert it afterwards. The broken state stays available to look at, and the host never saw any of it.
Is the web console a service I should leave running?
No. It is a foreground command: it listens on 127.0.0.1 only, and it stops shortly after you close the tab. The token it needs is generated at every start, and the API rejects foreign Host and Origin headers.
Does the box start with my computer?
The tunnel is a systemd user service, so it starts with your session. The virtual machine is not started for you: a host reboot leaves it off, and you bring it up with aibox start.
Does any of my data leave the machine?
AIBox does not collect, store or send anything: the VM runs on your hardware, the console is served by BusyBox on your machine and the tunnels are plain SSH. The agent, on the other hand, has the same internet access as any program you run.
Is macOS supported? Is Windows?
macOS is on the way: the Lima based support is being finished. Windows is not planned, the host scripts assume a Linux system with libvirt.
Can I run my own services?
Yes. aibox service-add mytool 8080 registers a port, and the tunnel, the console and the status output pick it up right away.
How do I reach a service from another device?
Expose it on the LAN with aibox tunnel lan on opencode. The exposure is temporary by default: it reverts on its own after a couple of hours, and it is always lost on reboot. If a service really has to stay reachable, ask for it explicitly: AIBox then keeps the setting in the configuration and applies it again on the next start. The tunnel binds the port on your network interface instead of localhost, for that service only.
Do I need root on the host?
Only for a few setup steps, and the password is asked at that moment. It is never written to a file, never passed on a command line and never kept after the step ends.

Give your agent a box to work in

One repository, a handful of shell scripts, and a virtual machine that behaves like a machine you own. Clone it, run the setup, and let the agent work.