# Sandbox recipe

URL: https://briq.cloud/cookbook/sandbox

> A machine for the agent's own code: scripts, tests, builds, anything that should not run on your computer. Ubuntu with Python, Node, git and a C toolchain, plus the psql, redis-cli and sqlite3 clients. Commands run with briq_exec. The :full tag adds pandoc, ffmpeg, the Python data libraries and Playwright with Chromium.

Tags: sandbox, testing

Guide:

- [Run code in a sandbox](https://briq.cloud/docs/guides/run-code-in-a-sandbox.md): Give the agent a microVM of its own for scripts, tests and builds, so nothing it runs touches your machine.

## Run it

briq.yaml:

```yaml
stack: app
services:
  sandbox:
    recipe: sandbox
    # its defaults, each a field you can set:
    # image: ghcr.io/briq-cloud/sandbox:latest
    # size: small
    # volume: { gb: 2 }
```

MCP:

```ts
briq_run({ recipe: "sandbox", wait: true })
```

REST:

```bash
curl -X POST https://api.briq.cloud/v1/briqs \
  -H "Authorization: Bearer $BRIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipe": "sandbox",
    "wait": true
  }'
# → { "briqs": [{ "id": "bq_…", … }], "outputs": { "SANDBOX_HOST": "…" }, … }

# ... when done, for each briq id
curl -X DELETE https://api.briq.cloud/v1/briqs/<id> \
  -H "Authorization: Bearer $BRIQ_API_KEY"
```

## Fields

Set them beside `recipe`, in briq_run or a briq.yaml service, as a GitHub Actions service.

| Name | Type | Options | Default | What it does |
| --- | --- | --- | --- | --- |
| `image` | string | — | "ghcr.io/briq-cloud/sandbox:latest" | The image: another tag, or a compatible image (as for a GitHub Actions service) |
| `env` | unknown | — | {} | Added to the recipe's env, or replacing one of its values. A credential as { secret: NAME, value } |
| `cmd` | string \| string[] | — | — | The command: a string run with sh -c, or the argv. Default: the recipe's |
| `size` | enum | nano, small, medium, large | "small" | small for scripts and tests; medium or large for a build or a long test suite, which a shared CPU slows down once it used its burst |
| `volume` | object | { gb? } | {"gb":2} | The volume: { gb } |
| `files` | unknown | — | — | Boot files, added to the recipe's |

## Outputs

Returned by `briq_run` once the stack is healthy. Hosts resolve inside your team network; secrets are generated per run.

| Output | Value |
| --- | --- |
| `SANDBOX_HOST` | `sandbox.<stack>.internal` |
| `WORKDIR` | `/work` |
| `PORT` | `8080` |

## What it runs

| Briq | Image | Ports | Size | Volume |
| --- | --- | --- | --- | --- |
| sandbox | `ghcr.io/briq-cloud/sandbox:latest` | 8080 | small | 2 GB at /work |

## When to use it

* Code the agent wrote, or code it does not trust, that should not run on your computer: a
  script, a test suite, a build, a tool to try.
* Code that needs a real service: a Postgres or a Redis in the same stack.
* Work that should stop on its own: the sandbox sleeps after its `sleep` window, and costs nothing
  asleep.

Step by step: [Run code in a sandbox](https://briq.cloud/docs/guides/run-code-in-a-sandbox).

## Tips

* **Files in, commands, files out**: `briq_files_put` to `/work/…`, `briq_exec` with
  `["sh", "-c", "cd /work && …"]`, `briq_files_get` for what it wrote. Over a minute:
  `async: true` ([Run a long command](https://briq.cloud/docs/guides/run-a-long-command)).
* **A repo**: `git clone` it from inside with `briq_exec`. Uploads are capped at 1 MB a file.
* **What the image has**: every tool and its version on the
  [sandbox reference](https://briq.cloud/docs/sandbox). `image: "ghcr.io/briq-cloud/sandbox:full"` adds document
  and media tools, the Python data libraries and a browser. Another image: `"golang:1.25"`,
  `"ubuntu:24.04"`, anything with `sh`.
* **Credentials as secrets**: `env: { GITHUB_TOKEN: { secret: "GITHUB_TOKEN", value: "…" } }`.
  The commands read `$GITHUB_TOKEN`; status and audit show its name only. Make the token for the
  task (read-only, expiring), never a key to your cloud: the code runs with an open internet.
* **A server it starts gets a URL**: `expose: "private"` at run; whatever listens on `$PORT`
  (8080) serves at `URL`.
* **Prepare once, run many**: install the dependencies, then `briq_fork` for each attempt. The
  forks start with `/work` as it was.
* **`small` for scripts and tests**; `medium` or `large` for a build.
* **It can reach the internet and the team's other briqs**: see [Security](https://briq.cloud/docs/security).
