Skip to main content
The Gemini sparkle and wordmark inside the boxd card. Gemini Managed Agents, such as the Antigravity agent, run through the Gemini Interactions API. Google hosts the model and the agent loop. A self-hosted environment moves tool execution to you, so every execute_bash, file read, file write and search runs on infrastructure you own. The worker is the environment runtime in Google’s gemini-api CLI. Run it on boxd and the agent’s commands run on a full Linux machine with its own kernel. The machine hibernates with its files and processes in place, a fresh one starts from a snapshot for every interaction if you want that, and each has an egress allowlist you set from outside it.

How it fits together

The worker talks to Google over outbound HTTPS only. Nothing dials into the machine, so it needs no open ports. The runtime has two modes. Use one per environment: if both run against the same environment, they compete for its interactions.

Set up the Gemini side

Create a self-hosted environment with your Gemini API key. The response holds the environment’s id and an environment_key, which the API returns only once:
The environment key is scoped to this environment: it is what a worker uses to lease and run its interactions. Keep your Gemini API key with your app. The examples below use the boxd Python SDK (pip install boxd, with BOXD_API_KEY set). Both setups install the same pinned gemini-api release and check it against the release’s checksums. Save this next to the scripts as install-gemini-api.sh:
install-gemini-api.sh

One worker machine

The worker starts in its own session, so it keeps running after the exec returns:
worker.py
Send the agent a task from anywhere, with your Gemini API key:
The host name is the machine’s name: the command ran on boxd. The worker’s log is in ~/worker.log on the machine.

Sleep between uses

The worker polls Google every few seconds, and that outbound traffic keeps the machine awake. When you don’t need it, hibernate it. Interactions you send meanwhile wait at Google, and the worker picks them up when the machine wakes, with its files and its worker process as they were:
Nothing wakes a hibernated machine on its own when an interaction arrives, so wake it before you send work, or use a machine per interaction.

A machine per interaction

Here the poller runs on a host you control and holds the environment key. For each interaction it leases, it runs a provisioning command with a JSON payload on stdin. The command below starts a fresh isolated machine from a snapshot and runs gemini-api environments serve on it with only that interaction’s lease token.

Build the snapshot once

snapshot.py
Add whatever every interaction should start with: a toolchain, private packages, a repository.

The provisioning command

provision.py
cleanup.py
Run the poller with it, on a host with the gemini-api CLI, BOXD_API_KEY and the environment key:
Every interaction now gets its own machine. Send several at once and they run in parallel:
That is hostname; ls -A /workspace | wc -l from one interaction: its own machine, and an empty workspace. The poller kills a provisioning command that runs longer than --provision-timeout (2 minutes by default). If that happens after the machine exists, or the cleanup loop dies, delete_after removes the machine after 2 hours.

What the agent can reach

  • Its own VM. Every machine here is created isolated: its own kernel, no private network with your other machines, and no boxd credentials inside it. See machine specs.
  • Only the Gemini API. The egress allowlist is set through the boxd API, so nothing inside the machine can change it. Add the hosts the agent needs, such as pypi.org and files.pythonhosted.org for pip install.
  • A lease token, not a key, per interaction. The per-interaction machine never holds your Gemini API key or the environment key. The agent’s commands can read the lease token, but it works only for the interaction they are already part of and expires with it.
  • The environment key, on the one worker machine. It sits in the worker process’s environment, not on disk. The agent’s commands run as the same user, so treat it as readable, and use a machine per interaction for untrusted input.

Read more