# How to run OpenAI Codex CLI in a cloud sandbox Install `@openai/codex` with npm in a Linux microVM, store the API key as a secret, run `codex exec` on a cloned repo and copy the diff. **On Runtime, Codex gets a whole machine to itself and never holds your key.** Every sandbox is a Firecracker microVM with its own Linux kernel, Ubuntu 24.04 and Node.js 24, so the npm package installs unchanged. The OpenAI key is stored as a Runtime secret: the sandbox sees a placeholder, and the host's proxy adds the real key only on requests to `api.openai.com`. A 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while the agent waits on the model. Codex 0.156.1 was the current npm release on 25 September 2026. | You want | Do this | | --------------------------------------------- | ----------------------------------------------------------- | | Codex to work on a repo away from your laptop | Run Codex inside a sandbox (below) | | Codex on your machine to run code safely | Add Runtime's MCP server, and it creates sandboxes as tools | ## Store the key once `codex exec` reads its key from `CODEX_API_KEY`. Store yours as a secret bound to OpenAI's API host: ```bash no-run printf %s "$OPENAI_API_KEY" | npx withruntime secrets set CODEX_API_KEY --host api.openai.com ``` Every sandbox of your account then has `CODEX_API_KEY` set to a placeholder such as `rtsec_3f9c…`. Only an HTTPS request to `api.openai.com` carries the real value. The value is sealed when you store it, and no API, tool or command returns it ([secrets sandboxes never see](/docs/security#secrets-sandboxes-never-see)). OpenAI's guide says to set `CODEX_API_KEY` inline, not job-wide, when running code a repository controls. A secret goes further: the code in the sandbox, Codex included, can read only the placeholder. ## Run Codex on a repo ```ts check import { writeFile } from "node:fs/promises"; import { Sandbox } from "withruntime"; const repo = "https://github.com/your-org/your-repo"; const task = "Find and fix the failing test in the parser, then run the tests."; await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600 }); const slow = { check: true, timeoutMs: 600_000 } as const; await sbx.exec("npm install -g --prefix /workspace/.local @openai/codex", slow); await sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], slow); // From here on the agent reaches only the model and the npm registry. await sbx.network.set({ internet: true, allow: ["api.openai.com", "registry.npmjs.org"] }); const run = await sbx.exec( ["codex", "exec", "--sandbox", "danger-full-access", "--ephemeral", task], { cwd: "/workspace/app", timeoutMs: 1_800_000, onStderr: (text) => process.stderr.write(text), }, ); console.log(run.exitCode, run.stdout); // stdout holds Codex's final message await sbx.exec("git add -A && git diff --cached > /workspace/change.patch", { cwd: "/workspace/app", check: true, }); await writeFile("change.patch", await sbx.files.readText("/workspace/change.patch")); ``` ```python check import sys from withruntime import Sandbox repo = "https://github.com/your-org/your-repo" task = "Find and fix the failing test in the parser, then run the tests." with Sandbox.create(disk_mib=8192, timeout_seconds=3600) as sbx: sbx.exec("npm install -g --prefix /workspace/.local @openai/codex", check=True, timeout_ms=600_000) sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], check=True, timeout_ms=600_000) sbx.network.set(internet=True, allow=["api.openai.com", "registry.npmjs.org"]) run = sbx.exec( ["codex", "exec", "--sandbox", "danger-full-access", "--ephemeral", task], cwd="/workspace/app", timeout_ms=1_800_000, on_stderr=sys.stderr.write, ) print(run.exit_code, run.stdout) # stdout holds Codex's final message sbx.exec("git add -A && git diff --cached > /workspace/change.patch", cwd="/workspace/app", check=True) with open("change.patch", "w") as file: file.write(sbx.files.read_text("/workspace/change.patch")) ``` What each part does: - **`--prefix /workspace/.local`** puts the `codex` command in `/workspace/.local/bin`, first on the sandbox's `PATH`, with no `sudo`. - **`--sandbox danger-full-access`** turns off Codex's own command sandbox. OpenAI's guide says to use it "only in a controlled environment (for example, an isolated CI runner or container)". A microVM that holds no key and reaches two hosts is that environment. For Codex's own read-only default, leave the flag out; `--sandbox workspace-write` lets it edit files in the checkout. - **`--ephemeral`** keeps session files off the disk. - **The clone** matters: `codex exec` refuses to run outside a Git repository unless you pass `--skip-git-repo-check`. - **Output:** Codex streams progress to stderr and prints its final message to stdout. The diff comes back as a file, so a large change is never cut at the 64 KiB result limit. - **The task is an array element,** so no shell reads its quotes or symbols. The sandbox trusts the certificate its proxy uses for a secret's host through `SSL_CERT_FILE`, which Codex reads for its HTTPS and WebSocket clients. ## Headless flags that matter Checked in OpenAI's documentation on 25 September 2026: | Flag | What it does | | ------------------------------------ | ----------------------------------------------- | | `codex exec ""` | Runs one task non-interactively | | `--sandbox workspace-write` | Lets Codex edit files; the default is read-only | | `--sandbox danger-full-access` | No Codex sandbox, for an isolated runner | | `--json` | A JSON Lines event stream | | `-o`, `--output-last-message ` | Writes the final message to a file | | `--output-schema ` | Holds the final answer to a JSON Schema | | `--skip-git-repo-check` | Runs outside a Git repository | | `--ephemeral` | Keeps no session files | | `codex exec resume --last ""` | Carries on the previous run | `--full-auto` still works but prints a warning; OpenAI's guide names `--sandbox workspace-write` in its place. To keep a checkout between tasks, [pause the sandbox](/how-to/pause-and-resume-a-sandbox) instead of stopping it. Its files, memory and processes are kept, and compute billing stops. ## Give Codex Runtime as a tool Codex on your own machine can create sandboxes, run commands in them and read files back through Runtime's MCP server: ```bash no-run codex mcp add runtime -- npx -y withruntime mcp ``` Or, in `~/.codex/config.toml`: ```toml [mcp_servers.runtime] command = "npx" args = ["-y", "withruntime", "mcp"] ``` The first call shows a link and a code. Approve **Connect agent** in your browser and every Runtime tool appears, with no key to copy ([MCP](/docs/mcp#add-it-to-your-agent)). A machine already connected by `npx withruntime login` skips that step, and in CI `RUNTIME_API_KEY` from a secret manager takes its place. | Tool | What it does | | ----------------------------------------------------------- | --------------------------------------------------- | | `runtime_sandbox_create` | A new sandbox, ready when the call returns | | `runtime_sandbox_exec` | Runs a command and returns its exit code and output | | `runtime_sandbox_files_read`, `runtime_sandbox_files_write` | Reads and writes files in the sandbox | | `runtime_sandbox_network_set` | Narrows or turns off the sandbox's internet | | `runtime_sandbox_fork` | Running copies of a sandbox, memory included | | `runtime_sandbox_manage` | Pause, wake, extend or stop | Every tool is in [MCP tools](/docs/mcp#tools); [coding agents](/docs/frameworks#coding-agents) has the same setup for Claude Code, Cursor, Gemini CLI and VS Code. ## What it costs Runtime bills the CPU the agent uses at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU, and memory at $0.0075 per GiB-hour. A 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while Codex waits on the model and $0.08 an hour with both CPUs busy ([pricing](/docs/pricing)). Model tokens are billed by OpenAI on your key. New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- node --version ``` The first run prints a link to approve in your browser. The same setup for Anthropic's agent is in [Claude Code in a sandbox](/integrations/claude-code), and [a sandbox for coding agents](/use-cases/coding-agent-sandbox) covers running many at once. ## Sources Checked 25 September 2026. - [Codex on GitHub](https://github.com/openai/codex): `npm install -g @openai/codex` - [Non-interactive mode](https://learn.chatgpt.com/docs/non-interactive-mode): `codex exec`, `--sandbox`, `--json`, `-o`, `--skip-git-repo-check`, `--ephemeral`, `CODEX_API_KEY`, and the guidance on `danger-full-access` - [Environment variables](https://learn.chatgpt.com/docs/config-file/environment-variables): `CODEX_API_KEY`, `CODEX_CA_CERTIFICATE` and `SSL_CERT_FILE` - [Authentication](https://learn.chatgpt.com/docs/auth): API keys for CI - [@openai/codex on npm](https://www.npmjs.com/package/@openai/codex): version 0.156.1 Facts on this page were checked on 25 September 2026.