---
title: "Sandboxes for the OpenAI Agents SDK"
description: "Give each OpenAI Agents SDK sandbox session its own exe.dev VM: a sandbox client for SandboxAgent, and an agent that runs on the LLM integration."
url: https://exe-staging.dev/deploy/openai-agents-sdk
category: "AI agents"
updated: 2026-10-29
---

# Sandboxes for the OpenAI Agents SDK

The SDK runs the agent loop. Each session's commands run on a VM of its own.

- **Software:** OpenAI Agents SDK (https://openai.github.io/openai-agents-python/sandbox_agents/)
- **Source:** https://github.com/openai/openai-agents-python
- **License:** MIT
- **Time:** 5 minutes
- **Example VM name:** `my-openai-agents` (yours will differ; on the VM, `hostname` prints it)
- **Machine-readable:** https://exe-staging.dev/deploy/openai-agents-sdk/manifest.json
- **File:** https://exe-staging.dev/deploy/openai-agents-sdk/agent.py
- **File:** https://exe-staging.dev/deploy/openai-agents-sdk/agents_api.py
- **File:** https://exe-staging.dev/deploy/openai-agents-sdk/exe_sandbox.py

## What you get

- agent.py and exe_sandbox.py in ~/openai-agents
- exe.dev's API through the openai-agents integration, scoped to session VMs, with no exe.dev key on any VM
- A first session that ran its commands on a new VM of its own, then was deleted with `./agent.py --rm`
- GPT models through exe.dev's LLM integration, with no OpenAI API key on any VM

Running on the VM:

- **Your agent**: agent.py, OpenAI Agents SDK 0.24 run by uv, data in `~/openai-agents/sessions`
- **Sandbox client**: exe_sandbox.py, which makes a VM per session with exe.dev's Python SDK
- **exe.dev API**: The openai-agents integration, which holds the API key off the VM
- **Session VMs**: One exe.dev VM per session, the agent working in /workspace, data in `/workspace`
- **GPT models**: OpenAI, through exe.dev's LLM integration

## Deploy with Shelley

Open https://exe-staging.dev/new?prompt=Set%20up%20OpenAI%20Agents%20SDK%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fopenai-agents-sdk.md%20from%20top%20to%20bottom.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-openai-agents.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-openai-agents.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20agent.py%20and%20exe_sandbox.py%20in%20~%2Fopenai-agents%0A-%20exe.dev%27s%20API%20through%20the%20openai-agents%20integration%2C%20scoped%20to%20session%20VMs%2C%20with%20no%20exe.dev%20key%20on%20any%20VM%0A-%20A%20first%20session%20that%20ran%20its%20commands%20on%20a%20new%20VM%20of%20its%20own%2C%20then%20was%20deleted%20with%20%60.%2Fagent.py%20--rm%60%0A-%20GPT%20models%20through%20exe.dev%27s%20LLM%20integration%2C%20with%20no%20OpenAI%20API%20key%20on%20any%20VM%0A%0ARun%20%22Set%20up%20the%20agent%20VM%20by%20hand%22%20from%20%22On%20the%20VM%22%2C%20skipping%20VM%20creation%0Aand%20SSH.%20Only%20the%20owner%20can%20create%20the%20integration%2C%20from%20their%20own%0Acomputer%3A%20give%20them%20the%20command%20in%20%22Let%20it%20make%20VMs%22%2C%20with%20this%20VM%27s%0Aname%20in%20it%2C%20and%20wait%20until%20they%20say%20they%27ve%20run%20it.%20Never%20ask%20for%20an%0Aexe.dev%20API%20key%20instead.%20Then%20run%20the%20check%20and%20the%20first%20task%20in%20that%0Asection%2C%20and%20delete%20the%20session%20with%20.%2Fagent.py%20--rm%20%3Cname%3E%2C%20so%20it%0Aleaves%20no%20VM%20behind.%20Skip%20%22Or%20let%20OpenAI%20run%20the%20agent%22%3A%20it%20needs%20the%0Aowner%27s%20OpenAI%20keys.%20Finish%20by%20pointing%20the%20owner%20to%20%22Give%20it%20a%20task%22.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A to create a VM whose agent, Shelley, follows this recipe. From a terminal:

```sh
curl -fsSL https://exe-staging.dev/deploy/openai-agents-sdk/prompt.txt | ssh exe.dev new --prompt=/dev/stdin
```

Or follow the steps below by hand.

The [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/)
runs sandbox agents: a `SandboxAgent` whose shell and file tools work in a
sandbox, while the agent loop stays in your Python process. A sandbox
client makes the sandbox. The SDK has clients for Docker and the local
machine, and for hosted providers such as E2B, Daytona, Modal, Vercel, and
Cloudflare.

This page adds one for exe.dev.
[exe_sandbox.py](https://exe-staging.dev/deploy/openai-agents-sdk/exe_sandbox.py)
makes each sandbox session an exe.dev VM of its own: a whole Ubuntu
machine with sudo and Docker, ready in a few seconds and private by
default, made with exe.dev's
[Python SDK](https://github.com/boldsoftware/exe-sdk-python).
[agent.py](https://exe-staging.dev/deploy/openai-agents-sdk/agent.py) is a
command-line agent built on it. It runs on a small VM of its own, with GPT
models from exe.dev's [LLM integration](/docs/integrations-llm), so no
OpenAI API key is needed anywhere.

## Set up the agent VM

Deploy sets it up on a new VM. To do it yourself:

<details id="create-the-vm" data-manual-setup class="dp-details">
<summary>Set up the agent VM by hand</summary>

On your computer:

```bash
ssh exe.dev new --name=my-openai-agents
ssh my-openai-agents.exe.xyz
```

On the VM, download the two files:

```bash
mkdir -p ~/openai-agents && cd ~/openai-agents
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/agent.py
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/exe_sandbox.py
chmod +x agent.py
```

To update later, run the two `curl` lines again.

</details>

## Let it make VMs

The agent VM makes session VMs through exe.dev's API, by way of an
integration that holds the API key: no key is ever on a VM. On your
computer:

```bash
ssh exe.dev integrations add exe-dev --name openai-agents \
  --tag openai-sandbox --cmds new,ls,ssh,rm --attach vm:my-openai-agents
```

The integration can make, reach, and delete VMs tagged `openai-sandbox`,
and nothing else; the VMs it makes get that tag. Only the agent VM can use
it. `ssh exe.dev integrations remove openai-agents` revokes it.

On the agent VM, check it:

```bash
curl -s -X POST https://openai-agents.int.exe.xyz/exec -d ls
```

Expect `{"vms":[]}`. Then give it a first task, in `~/openai-agents`. uv
installs the SDK the first time:

```bash
./agent.py "Write the output of hostname to hello.txt, and show it to me."
```

Expect `session <name>, on VM <name>`, a line for each command or edit
the agent makes, and a reply with the session VM's name, which is not this
VM's.

## Give it a task

On the agent VM, in `~/openai-agents`:

```bash
./agent.py "Make a small Flask to-do app, serve it on port 8080, and give me the link."
```

The agent gets a new VM, and each command it runs shows up as it runs.
The link it gives, `https://<session-vm>.exe.xyz:8080/`, opens for you
after exe.dev login, like any port from 3000 to 9999 through the
[HTTPS proxy](/docs/proxy).

Each session keeps its VM, its conversation, and its files. Continue it
with the name it printed:

```bash
./agent.py -s <name> "Add a due date to each to-do."
```

`./agent.py --ls` lists sessions, and `./agent.py --rm <name>` deletes
one and its VM. You can also open a session's VM yourself, on your
computer: `ssh <name>.exe.xyz`, then `cd /workspace`.

> [!WARNING]
> The agent runs commands with sudo, without asking. That's what the
> session VMs are for: they hold nothing else. Keep the agent VM, which
> can make VMs on your account, to yourself, and never attach the
> integration to the `openai-sandbox` tag, which would let sessions do the
> same.

## Use it in your own code

`exe_sandbox.py` works with any `SandboxAgent`. Put it beside your code on
the agent VM, and pass the client in `SandboxRunConfig`. This agent starts
with a repository checked out on its VM:

```python
import asyncio

from agents import Runner, set_default_openai_client, set_tracing_disabled
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.sandbox.entries import GitRepo
from openai import AsyncOpenAI

from exe_sandbox import ExeSandboxClient, ExeSandboxClientOptions

# On an exe.dev VM, models come from the LLM integration; the key is a placeholder.
set_default_openai_client(AsyncOpenAI(base_url="https://llm.int.exe.xyz/v1", api_key="exe.dev"), use_for_tracing=False)
set_tracing_disabled(True)

agent = SandboxAgent(
    name="Reviewer",
    model="gpt-6.1-sol",
    instructions="Answer questions about the repository in repo/. Run commands to check.",
    default_manifest=Manifest(entries={"repo": GitRepo(repo="openai/openai-agents-python", ref="main")}),
)

async def main():
    result = await Runner.run(
        agent,
        "Which sandbox providers are under repo/src/agents/extensions?",
        run_config=RunConfig(sandbox=SandboxRunConfig(
            client=ExeSandboxClient(api="https://openai-agents.int.exe.xyz"),
            options=ExeSandboxClientOptions(cpu=2))),
    )
    print(result.final_output)

asyncio.run(main())
```

Run it with `uv run --with 'openai-agents>=0.24,<0.25' --with 'exedev>=0.4,<0.5' review.py`.
When the run ends, the SDK closes the session and its VM is deleted.
`ExeSandboxClientOptions` also takes `memory`, `disk`, `image`, `egress`,
`integrations`, `tags`, `comment`, `exposed_ports`, and `on_exit`:

- `on_exit="keep"` keeps the VM. Save the session's state with
  `client.serialize_session_state(session.state)`, and
  `client.resume(...)` reconnects to the same VM later, with its files,
  packages, and running services. That's how `agent.py` keeps sessions.
- If a kept VM is gone, resuming makes a new, empty one. To bring the
  files back too, create the session with a snapshot, such as
  `snapshot=LocalSnapshotSpec(base_path=Path("snapshots"))`: the SDK
  saves `/workspace` when the session closes and restores it onto the new
  VM.
- For work the SDK has no method for, `session.vm` is the exe.dev VM
  object (`await session.vm.run("...")`).

Off exe.dev, integrations aren't reachable. Use
`ExeSandboxClient(token=...)` with an exe.dev API key from
`ssh exe.dev ssh-key generate-api-key --label=openai-agents --tag=openai-sandbox --cmds=new,ls,ssh,rm --exp=30d`,
leave out the two `set_` lines, and set `OPENAI_API_KEY`.

## Or let OpenAI run the agent

OpenAI's [Agents API](https://developers.openai.com/api/docs/guides/agents-api/overview)
(in beta) turns this around: OpenAI runs the agent loop, the Codex
harness, and a
[self-hosted environment](https://developers.openai.com/api/docs/guides/agents-api/environments/self-hosted)
runs its tools wherever you start `codex exec-server`. Codex is already on
every exe.dev VM, so a VM per session takes one more short program:
[agents_api.py](https://exe-staging.dev/deploy/openai-agents-sdk/agents_api.py)
creates a session, makes its VM through the same integration, and starts
`codex exec-server` there under systemd.

It needs two OpenAI keys, which the LLM integration doesn't replace:

- An OpenAI API key with `api.agents.read`, `api.agents.write`, and
  `api.responses.write`. Keep it off the VM in an
  [HTTP proxy integration](/docs/integrations-http-proxy). On your
  computer:

  ```bash
  printf %s "$OPENAI_API_KEY" | ssh exe.dev integrations add http-proxy --name openai \
    --target https://api.openai.com --bearer=- --attach vm:my-openai-agents
  ```

- An environment key, from the
  [Agents tab](https://platform.openai.com/agents?tab=environments&environment_view=keys)
  of the OpenAI platform, with every other permission set to **None**. It
  can only connect environments, and each session VM gets a copy, as
  OpenAI's design has it.

On the agent VM, fill in the environment key:

```bash
cd ~/openai-agents
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/agents_api.py
chmod +x agents_api.py
(umask 077; echo 'OPENAI_EXECUTOR_API_KEY=...' >> .env)
./agents_api.py "Write the output of hostname to hello.txt, and show it to me."
```

Expect `session sess_..., on VM <name>`, then the agent's reply with that
VM's name. `./agents_api.py -s sess_... "..."` continues a session on its
VM, restarting the executor if the VM was rebooted, and
`./agents_api.py --rm sess_...` deletes the session and its VM. OpenAI
bills the model at its API rates; `MODEL` in `.env` picks it (default
`gpt-6-astra`).

## Clean up

`./agent.py --rm <name>` deletes a session. On your computer,
`ssh exe.dev ls` lists session VMs with their task as the comment. To
delete every VM tagged `openai-sandbox`, including any the agent VM's
sessions still use (its first two lines alone list them):

```bash
ssh exe.dev ls --json |
  jq -r '.vms[] | select(.tags // [] | index("openai-sandbox")) | .vm_name' |
  xargs -r ssh exe.dev rm
```

Session history is in `~/openai-agents/sessions` on the agent VM. When
you're done with it all, `ssh exe.dev integrations remove openai-agents`.

## Troubleshooting

- `exe.dev API error (403) during new: integration not found or not
  attached to this VM`: run the command in [Let it make VMs](#let-it-make-vms)
  with this VM's name, or `ssh exe.dev integrations attach openai-agents vm:<this-vm>`.
- `agents_api.py` stops with `403` and `integration not found`: attach the
  `openai` integration to this VM, as in
  [Or let OpenAI run the agent](#or-let-openai-run-the-agent).
- `during new: ...` otherwise: exe.dev refused a VM, often because the
  plan's VM limit is reached. Delete old sessions.
- `Connection error` from the model: the LLM integration is reachable only
  from exe.dev VMs. Elsewhere, set `OPENAI_API_KEY`.
- A command that starts a server with `&` and leaves it writing to the
  terminal holds the command open until it times out. Run servers under
  `sudo systemd-run`, as `agent.py` tells the model to.

## Frequently asked questions

### What runs where?

The agent loop runs in your Python process: on the agent VM, or wherever you run your code. It calls the model, then runs the tools the model picks (shell commands, file edits, `apply_patch`) on the session's VM, over exe.dev's [HTTPS API](/docs/https-api), through an integration that keeps the API key off every VM. The session VMs can't use that integration, and hold no model key either.

### Do I need an OpenAI API key?

No. On an exe.dev VM, `agent.py` sends model requests to exe.dev's [LLM integration](/docs/integrations-llm), which bills them to your exe.dev account. To use your own key, or run the agent off exe.dev, add `OPENAI_API_KEY=sk-...` to `~/openai-agents/.env` (mode 600); traces then appear in OpenAI's dashboard, too.

### How is this different from the E2B, Daytona, or Modal clients?

It plugs into the same place: `SandboxRunConfig(client=...)`. Each sandbox is a whole VM with sudo, Docker, and systemd, so a session can install packages, run databases, and serve web apps at a private HTTPS address, and a kept session is still there days later. It doesn't do PTY sessions (no `write_stdin`), mounts, or manifest users and groups.

### What does it cost?

Session VMs share your exe.dev plan's CPU, memory, and disk rather than being billed one by one, but each counts toward the plan's VM limit (50 on [Personal](/docs/billing/personal)), so delete sessions you're done with. Model usage through the LLM integration is billed to your exe.dev account.

### Can the agent show me a web app it built?

Yes. Anything it serves on `0.0.0.0`, on a port from 3000 to 9999, is at `https://<vm>.exe.xyz:<port>/`, behind exe.dev login. `agent.py` tells the model so, and to run servers under systemd so they keep running between turns.

### Can the agent work on my GitHub repositories?

Yes, with no GitHub token on any VM. Attach exe.dev's [GitHub integration](/docs/integrations-github) to every session VM by their tag, on your computer: `ssh exe.dev integrations add github --name myapp --repository you/myapp --attach tag:openai-sandbox`. The agent then clones `https://github.int.exe.xyz/you/myapp.git`.

### Can sessions get bigger VMs, or no internet?

Yes, through `ExeSandboxClientOptions`: `cpu=4`, `memory="16GB"`, `disk="50GB"`, or `egress="integrations"`, which leaves a VM only its integrations. See [Internet access](/docs/internet-access).


## Related

- [Self-hosted sandbox for Claude Managed Agents](https://exe-staging.dev/deploy/claude-managed-agents.md): Anthropic runs the agent. Each session's tools run on a VM of its own.
- [Create sandboxes from Python](https://exe-staging.dev/deploy/python-sandboxes.md): Full VMs as sandboxes. A with block creates one, runs your code, and deletes it.
- [Run Codex on a remote server](https://exe-staging.dev/deploy/codex.md): A computer for Codex. An early night for your laptop.
- [Running Agents](https://exe-staging.dev/deploy/agents.md): Use exe.dev VMs as a sandbox
- [Run Claude Code on a remote server](https://exe-staging.dev/deploy/claude-code.md): A computer for Claude. A breather for your laptop.
- [Host OpenClaw](https://exe-staging.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
