# Run Codex in a sandbox
URL: https://docs.munito.ai/harnesses/codex

The Codex CLI (`codex`) is installed in the `ubuntu` template. Choose how it signs in, then run a task with `codex exec`.

## Sign in [#sign-in]

### With an OpenAI API key [#with-an-openai-api-key]

Put the key in the `env` of the sandbox:

```json
{ "CODEX_API_KEY": "sk-..." }
```

`codex exec` reads `CODEX_API_KEY` for each run. For the terminal UI, sign in once with the key: `printenv CODEX_API_KEY | codex login --with-api-key`. OpenAI recommends an API key for automation, see [authentication](https://learn.chatgpt.com/docs/auth) in the Codex docs.

### With a ChatGPT plan [#with-a-chatgpt-plan]

Sign in inside the sandbox, over [SSH](https://docs.munito.ai/sandboxes#ssh), in one of two ways:

- **With a device code:** turn on device code sign-in in the security settings of ChatGPT, or of your workspace. Then run `codex login --device-auth`, open the link on any device, and enter the code.
- **With your browser:** connect with `ssh -L 1455:localhost:1455`, then run `codex login`, and open the link in the browser of your computer. The forward brings the sign-in back to the sandbox.

Codex keeps the sign-in in `~/.codex/auth.json`, and each later `codex exec` in the same sandbox uses it. A [persistent sandbox](https://docs.munito.ai/sandboxes#persistent-sandboxes) keeps it across pauses. Codex then uses the usage limits of your plan.

### With the open models of Munito AI [#with-the-open-models-of-munito-ai]

Put your Munito AI key in the `env` of the sandbox as `MUNITO_API_KEY`, and write this configuration to `~/.codex/config.toml` in the sandbox, with the files API or a command:

```toml
model = "zai-org/glm-5.3-flash"
model_provider = "munito"

[model_providers.munito]
name = "Munito"
base_url = "https://api.munito.ai/inference/v1"
env_key = "MUNITO_API_KEY"
wire_api = "responses"
```

[Codex with open models](https://docs.munito.ai/codex) explains the provider, the model metadata and the regional hosts.

## Run a task [#run-a-task]

```bash
curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/exec" \
  -H "Authorization: Bearer $MUNITO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command": "cd /workspace && codex exec --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox \"Write a Python script that prints the first 10 primes, and run it\"", "timeout": 1800}'
```

- `codex exec` runs one task and exits. It writes its progress to standard error and its last message to standard output.
- `--dangerously-bypass-approvals-and-sandbox` lets Codex run commands and change files without asking, and without its own sandbox: the sandbox of Munito AI isolates it. Without it, `codex exec` can only read files.
- `--skip-git-repo-check` lets Codex work in a folder that is not a Git repository. In a cloned repository, leave it out.
- `--json` prints each event of Codex as one line of JSON. With `"stream": true` in the command, the events come as they happen.
- A command runs for at most 30 minutes. For a longer task, run `codex exec` in the background with `nohup` and read its log with later commands.

## Use the terminal UI over SSH [#use-the-terminal-ui-over-ssh]

Add your public key with [SSH](https://docs.munito.ai/sandboxes#ssh), connect with the command that `GET /sandboxes/{sandbox_id}/ssh` answers, and run `codex` in `/workspace`. For a session that outlives your connection, install `tmux` (`apt-get install -y tmux`) and start Codex inside it.
