# Agent sandboxes for Claude Code

import { Aside } from '@astrojs/starlight/components';

Claude Code cloud sessions can run in your own infrastructure through a
[self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments).
With Avrea, each session gets its own
[agent sandbox](/sandboxes/#agent-sandboxes): a fresh Linux machine that runs
the session's tools and is deleted when the session ends.

You run Anthropic's orchestrator on a host of your own. When a session needs a
machine, the orchestrator runs a spawn script, and the script asks Avrea for a
sandbox. Avrea starts the Claude Code runner in it with the session's one-time
work order. Your environment secret stays on the orchestrator host and never
enters a sandbox.

## Before you start

You need:

- a Claude Team or Enterprise plan with a
  [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments-quickstart)
  and its environment secret;
- your Avrea organization ID (`org-...`). The spawn script does not accept an
  organization slug. Run `avr org list --json name,organization_id` to list
  the IDs of the organizations you belong to;
- an always-on host with Claude Code and the [Avrea CLI](/cli/) installed.

## Give the host an Avrea credential

The spawn script authenticates with `AVR_TOKEN` from the orchestrator's
environment. Use a personal API key and keep it in your secret store, not in
the hooks directory.

To get a personal API key, [sign in with the CLI](/cli/#authenticate) as the
account the orchestrator uses, then print the stored key:

```bash
avr auth login
avr auth status --show-token
```

`avr auth logout` revokes this key, so do not log out of the machine you took
it from while the orchestrator still uses it.

<Aside type="caution" title="The key acts as its user">
A personal API key has its user's full access. Create it for a dedicated
account that is a member of only this organization, with the least access
that can create sandboxes. Anyone who can read the key or run commands on the
orchestrator host can create sandboxes billed to your organization.
</Aside>

An account that is not an organization admin has two limits:

- it can have 2 sandboxes at a time, so a third concurrent session fails with
  a quota error until one ends. Contact Avrea to raise the limit for your
  organization;
- it cannot set `--egress-rules`. Only organization admins can.

## Write the spawn script

Create an executable `spawn-runner` file in the orchestrator's hooks
directory:

```bash
#!/bin/sh
exec avr vm create --from-spawn-script claude-code --org org-abc123
```

The script reads the work order Claude Code passes it, creates one agent
sandbox for it, prints the sandbox ID and exits without waiting for the
sandbox to boot. It never prints or logs the work order. If the orchestrator
offers the same request again, the script returns the sandbox it already
created.

Each agent sandbox is a VM of the organization that `--org` names. That
organization's quotas, billing and egress deny rules apply to it, and its
admins see it in the organization's sandbox list. Its other egress rules do
not: a sandbox reaches only the hosts Claude Code needs (Anthropic and GitHub)
and what `--egress-rules` allows. To run sessions in another
organization, use a separate orchestrator with its own spawn script.

You can add `--size`, `--ttl`, `--disable-cache`, `--egress-rules` and
`--https-port`. The script refuses `--name`, `--repo`, `--ref`, `--os` other
than `linux`, `--remote-desktop`, `--wait` and `--json`: the runner clones
each session's repository itself.

The exit code tells Claude Code what to do next:

| Exit code | Meaning |
| --- | --- |
| 0 | The sandbox was created, or already existed for this request. |
| 1 | A temporary failure, such as a quota limit, rate limit, timeout or network error. Claude Code retries the session later. After 10 failures in a row, the session is blocked as for exit code 2. |
| 2 | Avrea refused the request. The session is blocked until a user sends a new message or an Owner retries it. |

See Anthropic's
[spawn hook contract](https://code.claude.com/docs/en/self-hosted-environments-configuration)
for details.

## Run the orchestrator

```bash
export AVR_TOKEN=avk_...
claude self-hosted-runner orchestrator \
  --environment-secret-file /etc/claude/environment-secret \
  --hooks-dir /etc/claude/hooks
```

Sandboxes are created within seconds, so you can lower
`--expected-spawn-seconds` from its default of 120 to have a failed spawn
offered again sooner. The orchestrator refuses to start unless
`--hook-timeout`, 60 seconds by default, plus 5 seconds is below it, so keep
it above 65 or lower `--hook-timeout` too. It is also how long the work order
stays valid, so leave time for the sandbox to boot. See Anthropic's
[configuration reference](https://code.claude.com/docs/en/self-hosted-environments-reference)
for all orchestrator options.

## What happens in a session

- Each session runs in its own sandbox, which serves only that session.
- The runner clones and pushes github.com repositories through Anthropic's
  git proxy. Repositories on other hosts, including GitHub Enterprise Server,
  are not supported.
- The sandbox is deleted when the runner exits after its session, or when
  its time limit ends. Avrea stops the runner shortly before
  the time limit so the session is released cleanly.
- After 30 idle minutes the runner exits and the sandbox is deleted. The
  session continues in a new sandbox at your next message, so commit and push
  work you want to keep.
- Find running sandboxes with `avr vm list --sandbox`, or under **Agent
  sandboxes** in the console.

## Keep it secure

- Any member of your Anthropic organization can send a session to any of its
  self-hosted environments. Decide who belongs in that organization
  accordingly.
- If an Owner routes Claude Tag channels to the environment, anyone the
  Claude Tag access setting admits can start sessions there. By default that
  is anyone in the connected Slack workspace, with or without a Claude
  account. See Anthropic's
  [deployment guide](https://code.claude.com/docs/en/self-hosted-environments-deploy).
- The environment secret expires 365 days after it is created. Rotate it from
  the environment's **Configuration** tab before then.
- Restrict access to the orchestrator host. It holds the environment secret
  and the Avrea credential.