> ## Documentation Index
> Fetch the complete documentation index at: https://docs.costgraph.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Run workflows on a managed sandbox provider

> Run a workflow's code changes in sandboxes from your own provider account, such as E2B, Daytona, Modal or Vercel

A workflow's repository agent can run its commands in sandboxes from a managed
sandbox provider you already pay for, instead of a Kubernetes cluster. Each
code change gets a fresh sandbox in your provider account, and the sandbox is
deleted when the change ends.

This uses the same dispatcher as
[running workflows in your environment](/costgraph/workflows/your-environment).
Only where each sandbox runs changes.

| | Your Kubernetes cluster | A managed sandbox provider |
| - | - | - |
| Where commands run | A Job in your cluster | A sandbox in your provider account |
| Sandbox image | Any pod template you write | The provider's default image, or a template you build there |
| Network rules | Kubernetes NetworkPolicy | The provider's own network settings |
| Where the dispatcher runs | In the cluster | Anywhere that runs a container |

## Supported providers

Set `provider` to the value in the following table, and give the dispatcher
that provider's credential variables. CostGraph tests each provider live;
contact your account team before relying on one in production.

| Provider | `provider` value | Credential variables |
| - | - | - |
| Agentuity | `agentuity` | `AGENTUITY_SDK_KEY` |
| Beam | `beam` | `BEAM_TOKEN` and `BEAM_WORKSPACE_ID` |
| Blaxel | `blaxel` | `BL_API_KEY` and `BL_WORKSPACE` |
| Brezel | `brezel` | `BREZEL_API_KEY`, `BREZEL_API_URL` and `BREZEL_PROJECT_ID` |
| Buddy | `buddy` | `BUDDY_TOKEN`, `BUDDY_WORKSPACE` and `BUDDY_PROJECT` |
| Cloudflare | `cloudflare` | `CLOUDFLARE_SANDBOX_URL` and `CLOUDFLARE_SANDBOX_API_KEY` |
| CodeSandbox | `codesandbox` | `CSB_API_KEY` |
| Collimate | `collimate` | `COLLIMATE_API_KEY` |
| CreateOS | `createos-sandbox` | `CREATEOS_SANDBOX_API_KEY` |
| Daytona | `daytona` | `DAYTONA_API_KEY` |
| Declaw | `declaw` | `DECLAW_API_KEY` |
| E2B | `e2b` | `E2B_API_KEY` |
| Freestyle | `freestyle` | `FREESTYLE_API_KEY` |
| givemeanode | `givemeanode` | `GMN_TOKEN` |
| Google Cloud Run | `cloud-run` | `CLOUD_RUN_SANDBOX_URL` and `CLOUD_RUN_SANDBOX_SECRET` |
| GravixLayer | `gravixlayer` | `GRAVIXLAYER_API_KEY` |
| HopX | `hopx` | `HOPX_API_KEY` |
| Isorun | `isorun` | `ISORUN_API_KEY` |
| Leap0 | `leap0` | `LEAP0_API_KEY` |
| Lelantos | `lelantos` | `LELANTOS_API_KEY` or `E2B_API_KEY` |
| Lightning AI | `lightning` | `LIGHTNING_SANDBOX_API_KEY` or `LIGHTNING_API_KEY` |
| MIOSA | `miosa` | `MIOSA_API_KEY` |
| Microsandbox | `microsandbox` | `MSB_API_KEY`, and `MSB_API_URL` for a self-hosted control plane |
| Modal | `modal` | `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET` |
| Mosaic | `mosaic` | `MOSAIC_API_TOKEN` |
| NeevCloud | `neevcloud` | `NEEV_API_KEY`, `NEEV_ORG_ID` and `NEEV_PROJECT_ID` |
| Northflank | `northflank` | `NORTHFLANK_API_TOKEN` and `NORTHFLANK_PROJECT_ID` |
| Novita | `novita` | `NOVITA_API_KEY` |
| OpenComputer | `opencomputer` | `OPENCOMPUTER_API_KEY` |
| Quilt | `quilt` | `QUILT_BASE_URL` and `QUILT_API_KEY` or `QUILT_ACCESS_TOKEN` |
| Railway | `railway` | `RAILWAY_API_TOKEN` |
| Run Cloud | `run-cloud` | `RUN_CLOUD_API_KEY` or `RUN_CLOUD_API_TOKEN` |
| Runloop | `runloop` | `RUNLOOP_API_KEY` |
| Runtime | `runtime` | `RUNTIME_API_KEY` |
| Sandbox0 | `sandbox0` | `SANDBOX0_TOKEN` or `SANDBOX0_API_KEY` |
| Sprites | `sprites` | `SPRITES_TOKEN` |
| Superserve | `superserve` | `SUPERSERVE_API_KEY` |
| Tenki Cloud | `tenki` | `TENKI_API_KEY` or `TENKI_AUTH_TOKEN` |
| Tensorlake | `tensorlake` | `TENSORLAKE_API_KEY` |
| Upstash Box | `upstash` | `UPSTASH_BOX_API_KEY` |
| Vercel | `vercel` | `VERCEL_TOKEN`, `VERCEL_TEAM_ID` and `VERCEL_PROJECT_ID` |

Cloudflare and Google Cloud Run need a sandbox gateway that you deploy in your
account first. Their URL variable points at that gateway.

Microsandbox sandboxes start from the `buildpack-deps:bookworm-scm` image unless
`providerTemplate` names another image. Set `MSB_API_URL` only when your
team runs its own Microsandbox control plane.

Give the dispatcher its own provider key, limited to creating and deleting
sandboxes. Keep it separate from any key you connect to CostGraph for cost data.

## Before you begin

* A CostGraph API key with the `deployment:register` and `sandbox:worker`
  scopes. The first pulls the dispatcher image from `registry.costgraph.ai`,
  the second lets the dispatcher take code changes.
* Credentials for one provider account, listed in the preceding table.
* Somewhere to run one container that can reach `agent-relay.costgraph.ai` and
  your provider's API over port 443.

## Connect

<Tabs>
  <Tab title="Kubernetes">
    Store the provider credentials in a Secret whose keys are the variable
    names, then install the chart with your provider:

    ```bash theme={null}
    kubectl -n costgraph-agents create secret generic sandbox-provider \
      --from-literal=E2B_API_KEY="$E2B_API_KEY"
    ```

    ```yaml theme={null}
    dispatcher:
      workerName: prod-e2b
      existingSecret: costgraph-sandbox-key
      imagePullSecrets:
        - name: costgraph-registry
      sandbox:
        provider: e2b
        providerSecret: sandbox-provider
    ```

    Create `costgraph-sandbox-key` and `costgraph-registry` as described in
    [Install](/costgraph/workflows/your-environment#install). With a managed
    sandbox provider the dispatcher needs no permissions in the cluster.
  </Tab>

  <Tab title="Docker">
    Sign in to the registry with your CostGraph API key. Then run the
    dispatcher with the key in a file and the provider credentials in its
    environment:

    ```bash theme={null}
    docker login registry.costgraph.ai -u x
    printf '%s' "$COSTGRAPH_API_KEY" > ./api-key
    docker run -d --restart unless-stopped \
      -v "$PWD/api-key:/run/costgraph/api-key:ro" \
      -e RELAY_URL=https://agent-relay.costgraph.ai \
      -e RELAY_API_KEY_FILE=/run/costgraph/api-key \
      -e WORKER_NAME=prod-e2b \
      -e SANDBOX_PROVIDER=e2b \
      -e E2B_API_KEY \
      registry.costgraph.ai/costgraph-sandbox:v2.1.0
    ```
  </Tab>
</Tabs>

`WORKER_NAME` names this dispatcher in CostGraph: lowercase letters, digits and
hyphens, up to 63 characters. After it connects, it is available in a
goal's **Sandbox** setting. See
[Choose where a goal runs](/costgraph/workflows/your-environment#choose-where-a-goal-runs).

## Sandbox image

By default each sandbox starts from the provider's default image, and the
dispatcher installs the agent into it before the code change starts. The image
must have `curl`, `sha256sum`, `base64` and `git`, and either run as root or
allow `sudo`. The install adds a few seconds to every code change.

To skip the install and add your own tools, build a template in your provider.
It must already contain the agent and our two scripts. Then name it:

```yaml theme={null}
dispatcher:
  sandbox:
    providerTemplate: costgraph-worker
```

Build the template from our worker image,
`registry.costgraph.ai/costgraph-sandbox-worker`, with your provider's own
template tooling. The requirements are the same as for
[your own sandbox image](/costgraph/workflows/your-environment#build-your-own-image).

## Network

Each provider controls egress in its own settings. The sandbox must reach
`agent-relay.costgraph.ai` and `github.com` on port 443. Everything else is your
choice.

## Lifetime and cost

A code change that runs longer than `dispatcher.sandbox.ttlSeconds` (two hours
by default) is stopped, and the provider removes its sandbox. Sandbox time is
billed by your provider to your account.

If the dispatcher stops while a code change is running, that sandbox keeps
running until the change ends or the timeout removes it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.