# Codex — full documentation > Single-file Markdown export of ChatGPT docs for Codex across the CLI, IDE, cloud, and SDK. Curated index: https://learn.chatgpt.com/docs/llms.txt # Administration --- # Agent approvals & security Codex helps protect your code and data and reduces the risk of misuse. This page covers how to operate Codex safely, including sandboxing, approvals, and network access. If you are looking for Codex Security, the product for scanning connected GitHub repositories, see [Codex Security](https://learn.chatgpt.com/docs/security). By default, the agent runs with network access turned off. Locally, Codex uses an OS-enforced sandbox that limits what it can touch (typically to the current workspace), plus an approval policy that controls when it must stop and ask you before acting. For a high-level explanation of how sandboxing works across the ChatGPT desktop app, Codex CLI, and IDE extension, see [sandboxing](https://learn.chatgpt.com/docs/sandboxing). For a broader enterprise security overview, see the [Codex security white paper](https://trust.openai.com/?itemUid=382f924d-54f3-43a8-a9df-c39e6c959958&source=click). ## Migrate from the retired `untrusted` approval policy Codex and ChatGPT Work no longer support `approval_policy = "untrusted"`. The retired setting can prevent either client from starting. Remove it from user or project configuration, profile files, startup scripts, and managed defaults. For interactive, read-only use: ```toml sandbox_mode = "read-only" approval_policy = "on-request" ``` Or run `codex --sandbox read-only --ask-for-approval on-request`. With `on-request`, commands allowed by the sandbox can run without approval, read accessible files, and use network access if enabled. To preserve the stricter command-approval rule, omit an explicit `approval_policy` and add a project entry to your user-level `~/.codex/config.toml`: ```toml [projects."/path/to/project"] trust_level = "untrusted" ``` Commands then require approval unless an execution-policy rule allows them. This also disables project-local configuration. Explicitly setting `on-request` overrides the project-derived policy; managed `allowed_approval_policies` must include `untrusted` to permit it. ## Sandbox and approvals Local computer access with Work Cloud has separate local and cloud execution policies: - **Cloud execution:** Work cloud containers use existing Work Cloud policies. - **Local execution:** Local execution requirements govern the connected computer. MDM and legacy managed-device requirements take precedence over Agent Security, which takes precedence over the device's system requirements file. For Work with local access and dots, supported Global policy applies to the shared cloud orchestrator when managed policy is enabled. Work cloud containers and dots cloud computers use their own execution configuration and requirements. Test local and cloud controls separately. Keep orchestrator controls, including approvals and web search, in Global. Use the dedicated Allowed approval policies and Allowed web search modes controls where available, and TOML for other supported fields. Check the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for the field list and execution scope before applying a Codex example to Local computer access with Work Cloud. Moving between desktop, web, and mobile does not grant access to another computer. Before enabling sync or expanding access, review the Agent Security baseline and test an allowed and a blocked action in each execution environment. See [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration). Codex security controls come from two layers that work together: - **Sandbox mode**: What Codex can do technically (for example, where it can write and whether it can reach the network) when it executes model-generated commands. - **Approval policy**: When Codex must ask you before it executes an action (for example, leaving the sandbox, using the network, or running commands outside a trusted set). Codex uses different sandbox modes depending on where you run it: - **[Codex Cloud (Legacy)](https://learn.chatgpt.com/docs/environments/cloud-environment)**: Runs in isolated OpenAI-managed containers, preventing access to your host system or unrelated data. Uses a two-phase runtime model: setup runs before the agent phase and can access the network to install specified dependencies, then the agent phase runs offline by default unless you enable internet access for that environment. Secrets configured for cloud environments are available only during setup and are removed before the agent phase starts. - **Current Codex Cloud**: See [environment variables and network secrets](https://learn.chatgpt.com/docs/environments/cloud-environments#environment-variables-and-secrets) for how credentials are handled during setup and tasks. - **Codex CLI / IDE extension**: OS-level mechanisms enforce sandbox policies. Defaults include no network access and write permissions limited to the active workspace. You can configure the sandbox, approval policy, and network settings based on your risk tolerance. In the `Auto` preset (for example, `--sandbox workspace-write --ask-for-approval on-request`), Codex can read files, make edits, and run commands in the working directory automatically. Codex asks for approval to edit files outside the workspace or to run commands that require network access. If you want to chat or plan without making changes, switch to `read-only` mode with the `/permissions` command. Codex can also elicit approval for app (connector) tool calls that advertise side effects, even when the action isn't a shell command or file change. Destructive app/MCP tool calls always require approval when the tool advertises a destructive annotation (unless the tool advertises a read annotation, which takes priority). ## Safety monitoring and paused tasks GPT-6 Astra includes safety monitoring in Codex and ChatGPT Work. Monitoring runs asynchronously and can pause a task if it detects potentially unsafe model behavior. A pause can arrive after the activity that triggered it; monitoring doesn't replace sandboxing, permissions, or review of the result. If a task pauses, read the notice and review the findings when available. Resume only after checking that the task can safely continue. If the notice says the task has ended or doesn't offer an option to resume, you can't resume from that surface. | Surface and data controls | Findings and resume | | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | | Codex and ChatGPT Work clients with the findings and resume flow, without the data controls listed here | Review the findings before resuming. | | Codex CLI and mobile | Full findings and resume aren't available. The task ends. | | Zero data retention, Modified Abuse Monitoring, or non-US data storage residency | Full findings and resume aren't available. The task ends. | Safety monitoring evaluates model behavior during a task. [Automatic approval review](https://learn.chatgpt.com/docs/sandboxing/auto-review) evaluates individual actions that already require approval before those actions run. An action approved by automatic approval review can still be part of a task that monitoring later pauses. ## Network access For current Codex Cloud network settings, see [Connect to services](https://learn.chatgpt.com/docs/environments/cloud-environments#connect-to-services). For Codex Cloud (Legacy), see [agent internet access](https://learn.chatgpt.com/docs/cloud/internet-access) to enable full internet access or a domain allow list. For the ChatGPT desktop app, Codex CLI, or IDE extension, the default `workspace-write` sandbox mode keeps network access turned off unless you enable it in your configuration: ```toml [sandbox_workspace_write] network_access = true ``` ### Network isolation On supported managed Codex Cloud execution paths, Agent Security requirements constrain command networking. Codex Cloud environment internet settings apply separately. An allowed domain in Agent Security does not override a restriction in the Cloud environment's internet settings. These command-network controls do not, by themselves, disable hosted web search, apps, or MCP. ChatGPT Work Cloud has separate capability permissions and does not inherit these Agent Security requirements. A managed command allowlist applies to commands using the managed proxy. Where policy permits full sandbox escalation and it is approved, that execution can bypass the command proxy. A narrow network grant is different from full sandbox escalation. Configure enforced approval and sandbox requirements for the intended boundary, and test both ordinary and escalated commands. See [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration#configure-network-access-requirements). Network access is controlled through destination rules that apply to scripts, programs, and subprocesses spawned by commands. When command network access is already enabled, turn on the `network_proxy` feature to constrain that traffic to the network policy you configure. Adding domain rules does not enable the proxy by itself. ```toml [features.network_proxy] enabled = true domains = { "api.openai.com" = "allow", "example.com" = "deny" } ``` For a one-off CLI session, use the boolean shorthand when you only need the toggle, and the table form when you also set policy options: ```bash codex \ -c 'features.network_proxy=true' \ -c 'sandbox_workspace_write.network_access=true' codex \ -c 'features.network_proxy.enabled=true' \ -c 'features.network_proxy.domains={ "api.openai.com" = "allow", "example.com" = "deny" }' \ -c 'sandbox_workspace_write.network_access=true' ``` The feature changes how enabled network access is enforced; it does not grant network access by itself. Use `sandbox_workspace_write.network_access` with `workspace-write` config to decide whether commands have network access at all: - Network off + `network_proxy` on: network stays off, and the feature does nothing. - Network on + `network_proxy` off: network stays on with unrestricted direct outbound access. - Network on + `network_proxy` on: network stays on, and outbound traffic is constrained by the configured network policy. The proxy feature also applies to [permission profiles](https://learn.chatgpt.com/docs/permissions#network-permissions). A profile's `network.enabled = true` grants command network access, while `features.network_proxy = true` activates enforcement of that profile's domain rules: ```toml default_permissions = "project-edit" [features] network_proxy = true [permissions.project-edit] extends = ":workspace" [permissions.project-edit.network] enabled = true [permissions.project-edit.network.domains] "api.openai.com" = "allow" ``` If you omit the proxy feature in this example, commands have direct network access and the `api.openai.com` allow rule does not restrict their destinations. Admin-managed `experimental_network` requirements are separate from the user feature toggle. They can configure and start sandboxed networking without `features.network_proxy`, but they do not turn on network access when the active sandbox keeps it off. See [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration#configure-network-access-requirements) for the administrator-side `requirements.toml` shape. #### Network policy Domain rules are allowlist-first: - Exact hosts match only themselves. - `*.example.com` matches subdomains such as `api.example.com`, but not `example.com`. - `**.example.com` matches both the apex and subdomains. - A global `*` allow rule matches any public host that is not denied. Treat `*` as broad network access and prefer scoped rules when you can. - `deny` always wins over `allow`, and global `*` is only valid for allow rules. #### Local and private destinations By default, `allow_local_binding = false` blocks loopback, link-local, and private destinations: - Specific exceptions: add an exact local IP literal or `localhost` allow rule when a command needs one local target. - Broader access: set `allow_local_binding = true` only when you intentionally want wider local/private reach. - Wildcards: wildcard rules do not count as explicit local exceptions. - Resolved addresses: hostnames that resolve to local/private IPs stay blocked even if they match the allowlist. #### DNS rebinding protections Before allowing a hostname, Codex performs a best-effort DNS and IP classification check: - Lookups that fail or time out are blocked. - Hostnames that resolve to non-public addresses are blocked. - The check reduces DNS rebinding risk, but it does not eliminate it. Preventing rebinding completely would require pinning resolved IPs through the transport layer. If hostile DNS is in scope, enforce egress controls at a lower layer too. #### Dangerous settings Two settings deliberately widen the trust boundary: - `dangerously_allow_non_loopback_proxy = true` can expose proxy listeners beyond loopback. - `dangerously_allow_all_unix_sockets = true` bypasses the Unix socket allowlist. Use them only in tightly controlled environments. When Unix socket proxying is enabled, listeners stay loopback-only even if non-loopback binding was requested, so sandboxed networking does not become a remote bridge into local daemons. `network_proxy` is off by default. When you enable it: | Setting | Default | Behavior | | -------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enabled` | `false` | Starts sandboxed networking only when command network access is already on. | | `domains` | unset | Uses allowlist behavior, so no external destinations are allowed until you add `allow` rules. Supports exact hosts, scoped wildcards, and global `*` allow rules; `deny` always wins. | | `unix_sockets` | unset | No Unix socket destinations are allowed until you add explicit `allow` rules. | | `allow_local_binding` | `false` | Blocks local and private-network destinations unless you add an exact local IP literal or `localhost` allow rule, or explicitly opt into broader local/private access. | | `enable_socks5` | `true` | Exposes SOCKS5 support when policy allows it. | | `enable_socks5_udp` | `true` | Allows UDP over SOCKS5 when SOCKS5 is available. | | `allow_upstream_proxy` | `true` | Lets sandboxed networking honor an upstream proxy from the environment. | | `dangerously_allow_non_loopback_proxy` | `false` | Keeps listener endpoints on loopback unless you deliberately expose them beyond localhost. | | `dangerously_allow_all_unix_sockets` | `false` | Keeps Unix socket access allowlist-based unless you deliberately bypass that protection. | ### Traffic outside the command network proxy The network proxy filters scripts, programs, and child processes that run inside the local command sandbox. It does not filter web search, app or connector tool calls, MCP server connections, browser or Computer Use activity, Codex cloud tasks, or the client's model and authentication requests. These surfaces use separate service connections, feature settings, workspace policies, or environment controls. Browser tools separately check managed network denies and exclusive allowlists before accessing an origin. Browser origin policies can further restrict site access, uploads, downloads, and developer tools. See [managed browser controls](https://learn.chatgpt.com/docs/enterprise/managed-configuration#control-browser-and-computer-use). For managed users, combine command network policy with controls such as `allowed_web_search_modes`, approved `mcp_servers`, and feature requirements for apps, plugins, browsers, or Computer Use. See [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration). You can also control the [web search tool](https://platform.openai.com/docs/guides/tools-web-search) without granting full network access to spawned commands. Codex defaults to using a web search cache to access results. The cache is an OpenAI-maintained index of web results, so cached mode returns pre-indexed results instead of fetching live pages. This reduces exposure to prompt injection from arbitrary live content. Treat web results as untrusted. If you are using `--yolo` or another [full access sandbox setting](#common-sandbox-and-approval-combinations), web search defaults to live results. Use `--search` or set `web_search = "live"` to allow live browsing, or set it to `"disabled"` to turn the tool off: ```toml web_search = "cached" # default # web_search = "disabled" # web_search = "live" # same as --search ``` Set `web_search = "indexed"` when external web access should be gated by the search index. Use caution when enabling network access or web search in Codex. Prompt injection can cause the agent to fetch and follow untrusted instructions. ## Defaults and recommendations - On launch, Codex detects whether the folder is version-controlled and recommends: - Version-controlled folders: `Auto` (workspace write + on-request approvals) - Non-version-controlled folders: `read-only` - Depending on your setup, Codex may also start in `read-only` until you explicitly trust the working directory (for example, via an onboarding prompt or `/permissions`). - The workspace includes the current directory and temporary directories like `/tmp`. Use the `/status` command to see which directories are in the workspace. - To accept the defaults, run `codex`. - You can set these explicitly: - `codex --sandbox workspace-write --ask-for-approval on-request` - `codex --sandbox read-only --ask-for-approval on-request` ### Protected paths in writable roots In the default `workspace-write` sandbox policy, writable roots still include protected paths: - `/.git` is protected as read-only whether it appears as a directory or file. - If `/.git` is a pointer file (`gitdir: ...`), the resolved Git directory path is also protected as read-only. - `/.agents` is protected as read-only when it exists as a directory. - `/.codex` is protected as read-only when it exists as a directory. - Protection is recursive, so everything under those paths is read-only. ### Run without approval prompts You can disable approval prompts with `--ask-for-approval never` or `-a never` (shorthand). This option works with all `--sandbox` modes, so you still control Codex's level of autonomy. Codex makes a best effort within the constraints you set. If you need Codex to read files, make edits, and run commands with network access without approval prompts, use `--sandbox danger-full-access` (or the `--dangerously-bypass-approvals-and-sandbox` flag). Use caution before doing so. For a middle ground, `approval_policy = { granular = { ... } }` lets you keep specific approval prompt categories interactive while automatically rejecting others. The granular policy covers sandbox approvals, execpolicy-rule prompts, MCP prompts, `request_permissions` prompts, and skill-script approvals. ### Automatic approval reviews By default, approval requests route to you: ```toml approvals_reviewer = "user" ``` Automatic approval reviews apply when approvals are interactive, such as `approval_policy = "on-request"` or a granular approval policy. Set `approvals_reviewer = "auto_review"` to route eligible approval requests through a reviewer agent before Codex runs the request: ```toml approval_policy = "on-request" approvals_reviewer = "auto_review" ``` For the full reviewer lifecycle, trigger conditions, configuration precedence, and failure behavior, see [Auto-review](https://learn.chatgpt.com/docs/sandboxing/auto-review). The reviewer evaluates only actions that already need approval, such as sandbox escalations, blocked network requests, `request_permissions` prompts, or side-effecting app and MCP tool calls. Actions that stay inside the sandbox continue without an extra review step. The reviewer policy checks for data exfiltration, credential probing, persistent security weakening, and destructive actions. Low-risk and medium-risk actions can proceed when policy allows them. The policy denies critical-risk actions. High-risk actions require enough user authorization and no matching deny rule. Prompt-build, review-session, and parse failures fail closed. Timeouts are surfaced separately, but the action still does not run. The [default reviewer policy](https://github.com/openai/codex/blob/main/codex-rs/core/src/guardian/policy.md) is in the open-source Codex repository. Enterprises can replace its tenant-specific section with `guardian_policy_config` in managed requirements. Local `[auto_review].policy` text is also supported, but managed requirements take precedence. For setup details, see [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration#configure-automatic-review-policy). In the ChatGPT desktop app, these reviews appear as automatic review items with a status such as Reviewing, Approved, Denied, Aborted, or Timed out. They can also include a risk level and user-authorization assessment for the reviewed request. Automatic review uses extra model calls, so it can add to Codex usage. Admins can constrain it with `allowed_approvals_reviewers`. ### Common sandbox and approval combinations | Intent | Flags / config | Effect | | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | Auto (preset) | _no flags needed_ or `--sandbox workspace-write --ask-for-approval on-request` | Codex can read files, make edits, and run commands in the workspace. Codex requires approval to edit outside the workspace or to access network. | | Safe read-only browsing | `--sandbox read-only --ask-for-approval on-request` | Codex can read files and run commands within the read-only sandbox. Actions outside the sandbox can require approval. | | Read-only non-interactive (CI) | `--sandbox read-only --ask-for-approval never` | Codex can read files and run commands within the read-only sandbox; it never asks for approval. | | Auto-review mode | `--sandbox workspace-write --ask-for-approval on-request -c approvals_reviewer=auto_review` or `approvals_reviewer = "auto_review"` | Same sandbox boundary as standard on-request mode, but eligible approval requests are reviewed by Auto-review instead of surfacing to the user. | | Dangerous full access | `--dangerously-bypass-approvals-and-sandbox` (alias: `--yolo`) | No sandbox; no approvals _(not recommended)_ | For non-interactive runs, use `codex exec --sandbox workspace-write`; Codex keeps older `codex exec --full-auto` invocations as a deprecated compatibility path and prints a warning. #### Configuration in `config.toml` For the broader configuration workflow, see [Config basics](https://learn.chatgpt.com/docs/config-file/config-basic), [Advanced Config](https://learn.chatgpt.com/docs/config-file/config-advanced#approval-policies-and-sandbox-modes), and the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference). ```toml # Interactive approvals with a read-only sandbox approval_policy = "on-request" sandbox_mode = "read-only" allow_login_shell = false # optional hardening: disallow login shells for shell-based tools # Optional: Allow network in workspace-write mode [sandbox_workspace_write] network_access = true # Optional: granular approval policy # approval_policy = { granular = { # sandbox_approval = true, # rules = true, # mcp_elicitations = true, # request_permissions = false, # skill_approval = false # } } ``` You can also save presets as [profile files](https://learn.chatgpt.com/docs/config-file/config-advanced#profiles), then select them with `codex --profile profile-name`: ```toml # ~/.codex/full_auto.config.toml approval_policy = "on-request" sandbox_mode = "workspace-write" ``` ```toml # ~/.codex/readonly_quiet.config.toml approval_policy = "never" sandbox_mode = "read-only" ``` ### Test the sandbox locally To see what happens when a command runs under the Codex sandbox, use these Codex CLI commands: ```bash # macOS codex sandbox macos [--permissions-profile ] [--log-denials] [COMMAND]... # Linux codex sandbox linux [--permissions-profile ] [COMMAND]... # Windows codex sandbox windows [--permissions-profile ] [COMMAND]... ``` The `sandbox` command is also available as `codex debug`, and the platform helpers have aliases (for example `codex sandbox seatbelt` and `codex sandbox landlock`). ## OS-level sandbox Codex enforces the sandbox differently depending on your OS: - **macOS** uses Seatbelt policies and runs commands using `sandbox-exec` with a profile (`-p`) that corresponds to the `--sandbox` mode you selected. When restricted read access enables platform defaults, Codex appends a curated macOS platform policy (instead of broadly allowing `/System`) to preserve common tool compatibility. - **Linux** uses `bwrap` plus `seccomp` by default. - **Windows** supports [MXC](https://learn.chatgpt.com/docs/windows/windows-sandbox#windows-sandbox), with `elevated` and `unelevated` as legacy fallbacks. In [Windows Subsystem for Linux 2 (WSL2)](https://learn.chatgpt.com/docs/windows/wsl), Codex uses the Linux sandbox implementation. WSL1 was supported through Codex `0.114`; starting in `0.115`, the Linux sandbox moved to `bwrap`, so WSL1 is no longer supported. If you use the Codex IDE extension on Windows, it supports WSL2 directly. Set the following in your VS Code settings to keep the agent inside WSL2 whenever it's available: ```json { "chatgpt.runCodexInWindowsSubsystemForLinux": true } ``` This ensures the IDE extension inherits Linux sandbox semantics for commands, approvals, and filesystem access even when the host OS is Windows. Learn more in the [WSL guide](https://learn.chatgpt.com/docs/windows/wsl). When running on Windows, prefer MXC when the device and policy support it by setting this in `config.toml`: ```toml [features] prefer_mxc = true ``` Keep a permitted legacy implementation in `windows.sandbox` for fallback. See the [Windows setup guide](https://learn.chatgpt.com/docs/windows/windows-sandbox#enable-mxc) for configuration and compatibility limits. When you run Linux in a containerized environment such as Docker, the sandbox may not work if the host or container configuration blocks the namespace, setuid `bwrap`, or `seccomp` operations that Codex needs. In that case, configure your Docker container to provide the isolation you need, then run `codex` with `--sandbox danger-full-access` (or the `--dangerously-bypass-approvals-and-sandbox` flag) inside the container. ### Run Codex in Dev Containers If your host cannot run the Linux sandbox directly, or if your organization already standardizes on containerized development, run Codex with Dev Containers and let Docker provide the outer isolation boundary. This works with Visual Studio Code Dev Containers and compatible tools. Use the [Codex secure devcontainer example](https://github.com/openai/codex/tree/main/.devcontainer) as a reference implementation. The example installs Codex, common development tools, `bubblewrap`, and firewall-based outbound controls. Devcontainers provide substantial protection, but they do not prevent every attack. If you run Codex with `--sandbox danger-full-access` or `--dangerously-bypass-approvals-and-sandbox` inside the container, a malicious project can exfiltrate anything available inside the devcontainer, including Codex credentials. Use this pattern only with trusted repositories, and monitor Codex activity as you would in any other elevated environment. The reference implementation includes: - an Ubuntu 24.04 base image with Codex and common development tools installed; - an allowlist-driven firewall profile for outbound access; - VS Code settings and extension recommendations for reopening the workspace in a container; - persistent mounts for command history and Codex configuration; - `bubblewrap`, so Codex can still use its Linux sandbox when the container grants the needed capabilities. To try it: 1. Install Visual Studio Code and the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). 2. Copy the Codex example `.devcontainer` setup into your repository, or start from the Codex repository directly. 3. In VS Code, run `Dev Containers: Open Folder in Container...` and select `.devcontainer/devcontainer.secure.json`. 4. After the container starts, open a terminal and run `codex`. You can also start the container from the CLI: ```bash devcontainer up --workspace-folder . --config .devcontainer/devcontainer.secure.json ``` The example has three main pieces: - `.devcontainer/devcontainer.secure.json` controls container settings, capabilities, mounts, environment variables, and VS Code extensions. - `.devcontainer/Dockerfile.secure` defines the Ubuntu-based image and installed tools. - `.devcontainer/init-firewall.sh` applies the outbound network policy. The reference firewall is intentionally a starting point. If you depend on domain allowlisting for isolation, implement DNS rebinding and DNS refresh protections that fit your environment, such as TTL-aware refreshes or a DNS-aware firewall. Inside the container, choose one of these modes: - Keep Codex's Linux sandbox enabled if the Dev Container profile grants the capabilities needed for `bwrap` to create the inner sandbox. - If the container is your intended security boundary, run Codex with `--sandbox danger-full-access` inside the container so Codex does not try to create a second sandbox layer. ## Version control Codex works best with a version control workflow: - Work on a feature branch and keep `git status` clean before delegating. This keeps Codex patches easier to isolate and revert. - Prefer patch-based workflows (for example, `git diff`/`git apply`) over editing tracked files directly. Commit frequently so you can roll back in small increments. - Treat Codex suggestions like any other PR: run targeted verification, review diffs, and document decisions in commit messages for auditing. ## Monitoring and telemetry Codex supports opt-in monitoring via OpenTelemetry (OTel) to help teams audit usage, investigate issues, and meet compliance requirements without weakening local security defaults. Telemetry is off by default; enable it explicitly in your configuration. ### Overview - Codex turns off OTel export by default to keep local runs self-contained. - When enabled, Codex emits structured log events covering chats, API requests, SSE/WebSocket stream activity, user prompts (redacted by default), tool approval decisions, and tool results. - Codex tags exported events with `service.name` (originator), CLI version, and an environment label to separate dev/staging/prod traffic. ### Enable OTel (opt-in) Add an `[otel]` block to your Codex configuration (typically `~/.codex/config.toml`), choosing an exporter and whether to log prompt text. ```toml [otel] environment = "staging" # dev | staging | prod exporter = "none" # none | otlp-http | otlp-grpc log_user_prompt = false # redact prompt text unless policy allows ``` - `exporter = "none"` leaves instrumentation active but doesn't send data anywhere. - To send events to your own collector, pick one of: ```toml [otel] exporter = { otlp-http = { endpoint = "https://otel.example.com/v1/logs", protocol = "binary", headers = { "x-otlp-api-key" = "${OTLP_TOKEN}" } }} ``` ```toml [otel] exporter = { otlp-grpc = { endpoint = "https://otel.example.com:4317", headers = { "x-otlp-meta" = "abc123" } }} ``` Codex batches events and flushes them on shutdown. Codex exports only telemetry produced by its OTel module. ### Event categories Representative event types include: - `codex.conversation_starts` (model, reasoning settings, sandbox/approval policy) - `codex.api_request` (attempt, status/success, duration, and error details) - `codex.sse_event` (stream event kind, success/failure, duration, plus token counts on `response.completed`) - `codex.websocket_request` and `codex.websocket_event` (request duration plus per-message kind/success/error) - `codex.user_prompt` (length; content redacted unless explicitly enabled) - `codex.tool_decision` (approved/denied, source: configuration vs. user) - `codex.tool_result` (duration, success, output snippet) Associated OTel metrics (counter plus duration histogram pairs) include `codex.api_request`, `codex.sse_event`, `codex.websocket.request`, `codex.websocket.event`, and `codex.tool.call` (with corresponding `.duration_ms` instruments). For the full event catalog and configuration reference, see the [Codex configuration documentation on GitHub](https://github.com/openai/codex/blob/main/docs/config.md#otel). ### Security and privacy guidance - Keep `log_user_prompt = false` unless policy explicitly permits storing prompt contents. Prompts can include source code and sensitive data. - Route telemetry only to collectors you control; apply retention limits and access controls aligned with your compliance requirements. - Treat tool arguments and outputs as sensitive. Favor redaction at the collector or SIEM when possible. - Review local data retention settings (for example, `history.persistence` / `history.max_bytes`) if you don't want Codex to save session transcripts under `CODEX_HOME`. See [Advanced Config](https://learn.chatgpt.com/docs/config-file/config-advanced#history-persistence) and [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference). - If you run the CLI with network access turned off, OTel export can't reach your collector. To export, allow network access in `workspace-write` mode for the OTel endpoint, or export from Codex cloud with the collector domain on your approved list. - Review events periodically for approval/sandbox changes and unexpected tool executions. OTel is optional and designed to complement, not replace, the sandbox and approval protections described above. ## Managed configuration Enterprise admins can configure Codex security settings for their workspace in [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration). See that page for setup and policy details. --- # Custom instructions with AGENTS.md Codex reads `AGENTS.md` files before doing any work. By layering global guidance with project-specific overrides, you can start each task with consistent expectations, no matter which repository you open. ## How Codex discovers guidance Codex builds an instruction chain when it starts (once per run; in the TUI this usually means once per launched session). Discovery follows this precedence order: 1. **Global scope:** In your Codex home directory (defaults to `~/.codex`, unless you set `CODEX_HOME`), Codex reads `AGENTS.override.md` if it exists. Otherwise, Codex reads `AGENTS.md`. Codex uses only the first non-empty file at this level. 2. **Project scope:** Starting at the project root (typically the Git root), Codex walks down to your current working directory. If Codex cannot find a project root, it only checks the current directory. In each directory along the path, it checks for `AGENTS.override.md`, then `AGENTS.md`, then any fallback names in `project_doc_fallback_filenames`. Codex includes at most one file per directory. 3. **Merge order:** Codex concatenates files from the root down, joining them with blank lines. Files closer to your current directory override earlier guidance because they appear later in the combined prompt. Codex skips empty files and stops adding files once the combined size reaches the limit defined by `project_doc_max_bytes` (32 KiB by default). For details on these knobs, see [Project instructions discovery](https://learn.chatgpt.com/docs/config-file/config-advanced#project-instructions-discovery). Raise the limit or split instructions across nested directories when you hit the cap. ## Create global guidance Create persistent defaults in your Codex home directory so every repository inherits your working agreements. 1. Ensure the directory exists: ```bash mkdir -p ~/.codex ``` 2. Create `~/.codex/AGENTS.md` with reusable preferences: ```md # ~/.codex/AGENTS.md ## Working agreements - Always run `npm test` after modifying JavaScript files. - Prefer `pnpm` when installing dependencies. - Ask for confirmation before adding new production dependencies. ``` 3. Run Codex anywhere to confirm it loads the file: ```bash codex --ask-for-approval never "Summarize the current instructions." ``` Expected: Codex quotes the items from `~/.codex/AGENTS.md` before proposing work. Use `~/.codex/AGENTS.override.md` when you need a temporary global override without deleting the base file. Remove the override to restore the shared guidance. ## Layer project instructions Repository-level files keep Codex aware of project norms while still inheriting your global defaults. 1. In your repository root, add an `AGENTS.md` that covers basic setup: ```md # AGENTS.md ## Repository expectations - Run `npm run lint` before opening a pull request. - Document public utilities in `docs/` when you change behavior. ``` 2. Add overrides in nested directories when specific teams need different rules. For example, inside `services/payments/` create `AGENTS.override.md`: ```md # services/payments/AGENTS.override.md ## Payments service rules - Use `make test-payments` instead of `npm test`. - Never rotate API keys without notifying the security channel. ``` 3. Start Codex from the payments directory: ```bash codex --cd services/payments --ask-for-approval never "List the instruction sources you loaded." ``` Expected: Codex reports the global file first, the repository root `AGENTS.md` second, and the payments override last. Codex stops searching once it reaches your current directory, so place overrides as close to specialized work as possible. Here is a sample repository after you add a global file and a payments-specific override: ## Add code review rules For [Codex code review in GitHub](https://learn.chatgpt.com/docs/third-party/github#customize-what-codex-reviews), add a `## Code Review Rules` section to the `AGENTS.md` closest to the code the rules govern. Put repository-wide checks at the root and service-specific checks in a nested file. ```md ## Code Review Rules ### Experiment cohorts - Do not filter treatment comparisons on post-exposure behavior, including conversion or retention. Safe path: build cohorts from assignment or exposure; report conversion as an outcome. ``` Keep rules concise, explain the behavior to flag and any safe path or exception, and reserve formatting and lint checks for CI. See [Customize what Codex reviews](https://learn.chatgpt.com/docs/third-party/github#customize-what-codex-reviews) for setup and rule-writing guidance. ## Customize fallback filenames If your repository already uses a different filename (for example `TEAM_GUIDE.md`), add it to the fallback list so Codex treats it like an instructions file. 1. Edit your Codex configuration: ```toml # ~/.codex/config.toml project_doc_fallback_filenames = ["TEAM_GUIDE.md", ".agents.md"] project_doc_max_bytes = 65536 ``` 2. Restart Codex or run a new command so the updated configuration loads. Now Codex checks each directory in this order: `AGENTS.override.md`, `AGENTS.md`, `TEAM_GUIDE.md`, `.agents.md`. Filenames not on this list are ignored for instruction discovery. The larger byte limit allows more combined guidance before truncation. With the fallback list in place, Codex treats the alternate files as instructions: Set the `CODEX_HOME` environment variable when you want a different profile, such as a project-specific automation user: ```bash CODEX_HOME=$(pwd)/.codex codex exec "List active instruction sources" ``` Expected: The output lists files relative to the custom `.codex` directory. ## Verify your setup - Run `codex --ask-for-approval never "Summarize the current instructions."` from a repository root. Codex should echo guidance from global and project files in precedence order. - Use `codex --cd subdir --ask-for-approval never "Show which instruction files are active."` to confirm nested overrides replace broader rules. - To audit which instruction files Codex loaded, opt into a plaintext TUI log with `codex -c log_dir=./.codex-log` and check `./.codex-log/codex-tui.log`, or inspect the most recent `session-*.jsonl` file if you enabled session logging. - If instructions look stale, restart Codex in the target directory. Codex rebuilds the instruction chain on every run (and at the start of each TUI session), so there is no cache to clear manually. ## Troubleshoot discovery issues - **Nothing loads:** Verify you are in the intended repository and that `codex status` reports the workspace root you expect. Ensure instruction files contain content; Codex ignores empty files. - **Wrong guidance appears:** Look for an `AGENTS.override.md` higher in the directory tree or under your Codex home. Rename or remove the override to fall back to the regular file. - **Codex ignores fallback names:** Confirm you listed the names in `project_doc_fallback_filenames` without typos, then restart Codex so the updated configuration takes effect. - **Instructions truncated:** Raise `project_doc_max_bytes` or split large files across nested directories to keep critical guidance intact. - **Profile confusion:** Run `echo $CODEX_HOME` before launching Codex. A non-default value points Codex at a different home directory than the one you edited. ## Next steps - Visit the official [AGENTS.md](https://agents.md) website for more information. - Review [Prompting Codex](https://learn.chatgpt.com/docs/prompting) for conversational patterns that pair well with persistent guidance. --- # Rules Use rules to control which commands Codex can run outside the sandbox. Rules are experimental and may change. ## Create a rules file For Local computer access with Work Cloud, configure supported managed command rules with the `rules` TOML field in Agent Security. These rules apply to local executors; Work cloud containers use existing Work Cloud policies. These local `.rules` instructions apply to Codex; don't assume Local computer access with Work Cloud reads local rule files. See [Managed configuration](https://learn.chatgpt.com/docs/enterprise/managed-configuration) and the [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference) for managed Work requirements. 1. Create a `.rules` file under a `rules/` folder next to an active config layer (for example, `~/.codex/rules/default.rules`). 2. Add a rule. This example prompts before allowing `gh pr view` to run outside the sandbox. ```python # Prompt before running commands with the prefix `gh pr view` outside the sandbox. prefix_rule( # The prefix to match. pattern = ["gh", "pr", "view"], # The action to take when Codex requests to run a matching command. decision = "prompt", # Optional rationale for why this rule exists. justification = "Viewing PRs is allowed with approval", # `match` and `not_match` are optional "inline unit tests" where you can # provide examples of commands that should (or should not) match this rule. match = [ "gh pr view 7888", "gh pr view --repo openai/codex", "gh pr view 7888 --json title,body,comments", ], not_match = [ # Does not match because the `pattern` must be an exact prefix. "gh pr --repo openai/codex view 7888", ], ) ``` 3. Restart Codex. Codex scans `rules/` under every active config layer at startup, including [Team Config](https://learn.chatgpt.com/docs/enterprise/admin-setup#step-4-standardize-local-configuration-with-team-config) locations and the user layer at `~/.codex/rules/`. Project-local rules under `/.codex/rules/` load only when the project `.codex/` layer is trusted. When you add a command to the allow list in the TUI, Codex writes to the user layer at `~/.codex/rules/default.rules` so future runs can skip the prompt. When Smart approvals are enabled (the default), Codex may propose a `prefix_rule` for you during escalation requests. Review the suggested prefix carefully before accepting it. Admins can also enforce restrictive `prefix_rule` entries from [`requirements.toml`](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml). ## Understand rule fields `prefix_rule()` supports these fields: - `pattern` **(required)**: A non-empty list that defines the command prefix to match. Each element is either: - A literal string (for example, `"pr"`). - A union of literals (for example, `["view", "list"]`) to match alternatives at that argument position. - `decision` **(defaults to `"allow"`)**: The action to take when the rule matches. Codex applies the most restrictive decision when more than one rule matches (`forbidden` > `prompt` > `allow`). - `allow`: Run the command outside the sandbox without prompting. - `prompt`: Prompt before each matching invocation. - `forbidden`: Block the request without prompting. - `justification` **(optional)**: A non-empty, human-readable reason for the rule. Codex may surface it in approval prompts or rejection messages. When you use `forbidden`, include a recommended alternative in the justification when appropriate (for example, `"Use \`rg\` instead of \`grep\`."`). - `match` and `not_match` **(defaults to `[]`)**: Examples that Codex validates when it loads your rules. Use these to catch mistakes before a rule takes effect. When Codex considers a command to run, it compares the command's argument list to `pattern`. Internally, Codex treats the command as a list of arguments (like what `execvp(3)` receives). ## Shell wrappers and compound commands Some tools wrap several shell commands into a single invocation, for example: ```text ["bash", "-lc", "git add . && rm -rf /"] ``` Because this kind of command can hide more than one action inside one string, Codex treats `bash -lc`, `bash -c`, and their `zsh` / `sh` equivalents specially. ### When Codex can safely split the script If the shell script is a linear chain of commands made only of: - plain words (no variable expansion, no `VAR=...`, `$FOO`, `*`, etc.) - joined by safe operators (`&&`, `||`, `;`, or `|`) then Codex parses it (using tree-sitter) and splits it into individual commands before applying your rules. The script above is treated as two separate commands: - `["git", "add", "."]` - `["rm", "-rf", "/"]` Codex then evaluates each command against your rules, and the most restrictive result wins. Even if you allow `pattern=["git", "add"]`, Codex won't automatically allow `git add . && rm -rf /` because it evaluates `rm -rf /` separately. This prevents dangerous commands from being smuggled in alongside safe ones. ### When Codex does not split the script If the script uses more advanced shell features, such as: - redirection (`>`, `>>`, `<`) - substitutions (`$(...)`, `...`) - environment variables (`FOO=bar`) - wildcard patterns (`*`, `?`) - control flow (`if`, `for`, `&&` with assignments, etc.) then Codex doesn't try to interpret or split it. In those cases, the entire invocation is treated as: ```text ["bash", "-lc", ""] ``` and your rules are applied to that **single** invocation. With this handling, you get the security of per-command evaluation when it's safe to do so, and conservative behavior when it isn't. ## Test a rule file Use `codex execpolicy check` to test how your rules apply to a command: ```shell codex execpolicy check --pretty \ --rules ~/.codex/rules/default.rules \ -- gh pr view 7888 --json title,body,comments ``` The command emits JSON showing the strictest decision and any matching rules, including any `justification` values from matched rules. Use more than one `--rules` flag to combine files, and add `--pretty` to format the output. ## Understand the rules language The `.rules` file format uses `Starlark` (see the [language specification](https://github.com/bazelbuild/starlark/blob/master/spec.md)). Its syntax is like Python, but it's designed to be safe to run: the rules engine can run it without side effects (for example, touching the filesystem). --- # Speed You can increase model speed in Codex in exchange for higher usage. ## Fast mode Fast mode speeds up supported models, including GPT-6.1 Sol, GPT-6 Astra, GPT-6 Sol, and GPT-6 Luna, where available. For GPT-5.6 and GPT-5.5, the speed increase is 1.5x. Use `/fast` in the CLI to toggle Fast mode. Use `/statusline` to show it in the footer. You can also persist the default with `service_tier = "fast"` plus `[features].fast_mode = true` in `config.toml`. Fast mode is available in the ChatGPT desktop app, Codex CLI, and IDE extension when you sign in with ChatGPT. For supported models, Fast mode uses included subscription limits at 2.5x the Standard rate. Purchased credits and Enterprise pay-as-you-go usage are billed at 2x the Standard rate. ## Ultrafast mode Ultrafast supports GPT-6 Astra and GPT-6.1 Sol. GPT-6 Astra Ultrafast generates tokens up to 8x faster than GPT-6 Astra in Standard mode in Codex. Ultrafast is available in Codex and ChatGPT Work on Pro $500 and eligible Enterprise and Edu plans. On Pro $500, Ultrafast uses your included usage first, then your available credits after that allowance runs out. Ultrafast mode bills purchased credits and Enterprise pay-as-you-go usage at 6x the Standard rate. Ultrafast uses included subscription limits at 8x the Standard rate. For Enterprise workspaces, Ultrafast is off by default. Workspace owners can enable access for selected users or the workspace through [workspace permissions](https://learn.chatgpt.com/docs/enterprise/roles-and-workspace-permissions). Existing [per-user spend controls](https://learn.chatgpt.com/docs/enterprise/usage-limits) apply to eligible Ultrafast usage. ## Availability and billing details **ChatGPT Work and Codex share usage.** Both use the same pricing, credits, and usage limits. See [Codex pricing](https://learn.chatgpt.com/docs/pricing) for details. See [Models](https://learn.chatgpt.com/docs/models) for model availability and [Pricing](https://learn.chatgpt.com/docs/pricing#token-rates) for token rates. ### Ultrafast plan and workspace requirements - Eligible Enterprise workspaces use credit-based or USD usage-based agreements. Usage is billed according to the workspace's agreement. - Eligible Edu plans use credits. Legacy Enterprise plans that rely on rate limits instead of usage-based billing aren't supported. Other self-serve plans don't have access to Ultrafast at launch, even with purchased credits. GPT-6.1 Sol Ultrafast supports inference residency in the United States and Europe (EEA + Switzerland). GPT-6 Astra Ultrafast supports inference residency in the United States only. ### API billing With an API key, Codex uses API token pricing instead, and ChatGPT credit multipliers don't apply. For API availability, request configuration, and pricing, see [Ultrafast mode in the API](https://developers.openai.com/api/docs/guides/ultrafast-mode). ## Retirement and migration [GPT-5.5 retires](https://learn.chatgpt.com/docs/models#gpt-55-retirement) from ChatGPT, ChatGPT Work, and Codex on all plans on October 14, 2026. The OpenAI API isn't affected. --- # Subagents ChatGPT Work and Codex can run subagent workflows by spawning specialized agents in parallel and then collecting their results in one response. This can be particularly helpful for complex tasks that are highly parallel, such as codebase exploration or implementing a multi-step feature plan. In local Codex clients, you can also define custom agents with different model configurations and instructions for different tasks. ## Availability ChatGPT Work exposes subagent workflows and activity to eligible accounts. Current Codex releases enable subagent workflows by default. Subagent activity appears in the ChatGPT desktop app, Codex CLI, and the IDE extension. Because each subagent does its own model and tool work, subagent workflows consume more tokens than comparable single-agent runs. In ChatGPT Work, ask ChatGPT to delegate independent work to subagents. The agents run in ChatGPT's hosted environment, and the chat shows their activity and results. At most intelligence levels, ask for delegation explicitly. With Ultra, ChatGPT can proactively delegate work when parallel agents would materially improve speed or quality. Ask Codex in an app chat to delegate independent parts of the work to subagents. Current local Codex releases delegate when you ask directly or when applicable `AGENTS.md` or skill instructions request it. The app surfaces each subagent thread so you can inspect its work and the summary returned to the main chat. Ask Codex in an interactive CLI session to use subagents. Codex can also follow applicable `AGENTS.md` or skill instructions that request delegation. Use `/agent` to inspect and switch between agent threads while they run. The main thread collects the subagent results into its final response. Ask Codex in an IDE chat to delegate independent parts of the work to subagents. Codex can also follow applicable `AGENTS.md` or skill instructions that request delegation. When the background-agent UI is available, active subagents appear above the composer. Expand the panel to see their status, stop all active subagents, or open an individual subagent thread. ## Why subagent workflows help Even with large context windows, models have limits. If you flood the main chat (where you're defining requirements, constraints, and decisions) with noisy intermediate output such as exploration notes, test logs, stack traces, and command output, the session can become less reliable over time. This is often described as: - **Context pollution**: useful information gets buried under noisy intermediate output. - **Context rot**: performance degrades as the chat fills up with less relevant details. For background, see the Chroma writeup on [context rot](https://research.trychroma.com/context-rot). Subagent workflows help by moving noisy work off the main thread: - Keep the **main agent** focused on requirements, decisions, and final outputs. - Run specialized **subagents** in parallel for exploration, tests, or log analysis. - Return **summaries** from subagents instead of raw intermediate output. They can also save time when the work can run independently in parallel, and they make larger-shaped tasks more tractable by breaking them into bounded pieces. For example, Codex can split analysis of a multi-million-token document into smaller problems and return distilled takeaways to the main thread. As a starting point, use parallel agents for read-heavy tasks such as exploration, tests, triage, and summarization. Be more careful with parallel write-heavy workflows, because agents editing code at once can create conflicts and increase coordination overhead. ## Core terms Codex uses a few related terms in subagent workflows: - **Subagent workflow**: A workflow where Codex runs parallel agents and combines their results. - **Subagent**: A delegated agent that Codex starts to handle a specific task. - **Agent thread**: The thread where a subagent does its work. Supported clients let you open these threads to inspect progress or results. ## Triggering subagent workflows At most intelligence levels, ask for subagents or parallel agent work directly. Ultra enables proactive delegation, so ChatGPT can delegate suitable independent work without a separate request. Ask for subagents or parallel agent work directly. Codex can also delegate when applicable project or skill instructions request it. In practice, manual triggering means using direct instructions such as "spawn two agents," "delegate this work in parallel," or "use one agent per point." Subagent workflows consume more tokens than comparable single-agent runs because each subagent does its own model and tool work. A good subagent prompt should explain how to divide the work, whether Codex should wait for all agents before continuing, and what summary or output to return. ```text Review this branch with parallel subagents. Spawn one subagent for security risks, one for test gaps, and one for maintainability. Wait for all three, then summarize the findings by category with file references. ``` ## Choosing models and reasoning Different agents need different model and reasoning settings. In ChatGPT Work, choose a model and an intelligence level from the composer. Available intelligence levels can include **Light**, **Medium**, **High**, **Extra High**, and **Max**, depending on the selected model. **Ultra** is available only to eligible accounts and supported models. It uses maximum reasoning and lets ChatGPT proactively delegate suitable work to subagents. At other intelligence levels, ask for subagents explicitly when you want work delegated in parallel. If you don't configure a subagent model or `model_reasoning_effort`, the subagent inherits the parent agent's model and reasoning effort. If an explicit spawn request or an `[agents]` default selects a model without an explicit or configured reasoning effort, the subagent uses that model's default reasoning effort. To balance intelligence, speed, and price for each task, request a specific model or reasoning effort in your prompt, configure `[agents]` defaults in `config.toml`, or set `model` and `model_reasoning_effort` directly in the custom agent file. For example, use `gpt-6-luna` for fast scans or a higher-effort `gpt-6.1-sol` configuration for more demanding reasoning. For most tasks in Codex, start with `gpt-6.1-sol` when your signed-in account or workspace has [access](https://learn.chatgpt.com/docs/models#gpt-6.1-sol). Otherwise, choose a model available to you. Use `gpt-6-luna` when you want a faster, lower-cost option for lighter subagent work. ### Model choice - **`gpt-6.1-sol`**: Start here for demanding agents. Use it for ambiguous, multi-step work that needs planning, tool use, validation, and follow-through across a larger context. - **`gpt-6-luna`**: Use for fast, narrowly scoped agents handling clear, repeatable, or high-volume work. ### Reasoning effort (`model_reasoning_effort`) For GPT-6.1 Sol, use a reasoning effort supported by your client and selected model. For explicit model settings, start with `high` for GPT-6 Luna or `low` for GPT-6 Astra. Adjust for the task using a level the selected model supports. - **`ultra`**: Use for the deepest reasoning when the selected model supports it. - **`max`** and **`xhigh`**: Use for especially demanding reasoning when the selected model supports these levels. - **`high`**: Use when an agent needs to trace complex logic, check assumptions, or work through edge cases (for example, reviewer or security-focused agents). - **`medium`**: Balances speed and depth. - **`low`**: Use when the task is straightforward and speed matters most. Higher reasoning effort increases response time and token usage, but it can improve quality for complex work. For details, see [Models](https://learn.chatgpt.com/docs/models), [Config basics](https://learn.chatgpt.com/docs/config-file/config-basic), and [Configuration Reference](https://learn.chatgpt.com/docs/config-file/config-reference). ## Orchestration and thread controls ChatGPT or Codex handles orchestration across agents, including spawning new subagents, routing follow-up instructions, waiting for results, and closing agent threads. When many agents are running, Codex waits until all requested results are available, then returns a consolidated response. At most intelligence levels, ChatGPT spawns agents after a direct request. With Ultra, ChatGPT can also delegate proactively when parallel work is useful. Current local Codex releases spawn agents after a direct request or applicable project or skill instruction. To see it in action, try the following prompt on your project: ```text I would like to review the following points on the current PR (this branch vs main). Spawn one agent per point, wait for all of them, and summarize the result for each point. 1. Security issue 2. Code quality 3. Bugs 4. Race 5. Test flakiness 6. Maintainability of the code ``` ## Managing subagents Open **Subagents** to see read-only **Active** and **Done** lists. Select a completed subagent to inspect its details and result. The web sidebar reports subagent activity; it doesn't provide controls to stop or steer an individual subagent. - Open a subagent thread from the activity shown in the main thread to inspect its work. - Ask Codex directly to steer a running subagent, stop it, or close completed subagent threads. > Illustration: Codex desktop chat showing two subagents working in parallel. > Illustration: Codex desktop Subagents panel with no active subagents and three completed audits. - Use `/agent` in the CLI to switch between active agent threads and inspect the ongoing thread. - Ask Codex directly to steer a running subagent, stop it, or close completed agent threads. - When the background-agent panel is available, expand it to inspect status, stop active subagents, or open a subagent thread. - Ask Codex directly to steer a running subagent, stop it, or close completed subagent threads. ## Approvals and sandbox controls Subagents inherit your current sandbox policy. ChatGPT Work runs subagents in its hosted environment and doesn't expose a local Codex sandbox or approval-mode control. Subagents use the tools available to the parent chat. Website and connector permissions remain tool-specific. Subagents inherit the permission mode selected beneath the composer. Choose the permission mode for the parent turn before you ask Codex to delegate work. In interactive CLI sessions, approval requests can surface from inactive agent threads even while you are looking at the main thread. The approval overlay shows the source thread label, and you can press `o` to open that thread before you approve, reject, or answer the request. In non-interactive flows, or whenever a run can't surface a fresh approval, an action that needs new approval fails and Codex surfaces the error back to the parent workflow. Codex also reapplies the parent turn's live runtime overrides when it spawns a child. That includes sandbox and approval choices you set interactively during the session, such as `/permissions` changes or `--yolo`, even if the selected custom agent file sets different defaults. Subagents inherit the permission mode selected beneath the composer. Choose the permission mode for the parent turn before you ask Codex to delegate work. You can also override the sandbox configuration for individual [custom agents](#custom-agents), such as explicitly marking one to work in read-only mode. ## Custom agents Codex ships with built-in agents: - `default`: general-purpose fallback agent. - `worker`: execution-focused agent for implementation and fixes. - `explorer`: read-heavy codebase exploration agent. To define your own custom agents, add standalone TOML files under `~/.codex/agents/` for personal agents or `.codex/agents/` for project-scoped agents. Each file defines one custom agent. Codex loads these files as configuration layers for spawned sessions, so custom agents can override the same settings as a normal Codex session config. That can feel heavier than a dedicated agent manifest, and the format may evolve as authoring and sharing mature. Every standalone custom agent file must define: - `name` - `description` - `developer_instructions` If a custom agent file sets `model` or `model_reasoning_effort`, the value in the file takes precedence. Before applying the file, Codex resolves each setting from an explicit spawn value, then the corresponding `[agents]` default, then the parent's value. If an explicit spawn request or an `[agents]` default selects a model and neither supplies a reasoning effort, Codex uses that model's default effort. A custom agent file that sets only `model` preserves this previously resolved effort. Set `model_reasoning_effort` in the file too if the selected model doesn't support that effort or you want a different one. Other session settings, such as `sandbox_mode`, `mcp_servers`, and `skills.config`, inherit from the parent when the custom agent file omits them. ### Global settings Global subagent settings still live under `[agents]` in your [configuration](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence). | Field | Type | Required | Purpose | | ------------------------------------------- | ------- | :------: | ------------------------------------------------------------------- | | `agents.enabled` | boolean | No | Enable or disable multi-agent tools. | | `agents.max_concurrent_threads_per_session` | number | No | Cap concurrently open spawned-agent threads, excluding the primary. | | `agents.default_subagent_model` | string | No | Set the default model for spawned agents. | | `agents.default_subagent_reasoning_effort` | string | No | Set the default reasoning effort for spawned agents. | | `agents.interrupt_message` | boolean | No | Record a model-visible message when an agent turn is interrupted. | **Notes:** - `agents.enabled` defaults to `true`. Set it to `false` to disable multi-agent tools. - When you leave `agents.max_concurrent_threads_per_session` unset, Codex chooses the default. Existing configurations can keep using `agents.max_threads` as a legacy alias. - Explicit spawn values override `agents.default_subagent_model` and `agents.default_subagent_reasoning_effort`. - `agents.interrupt_message` defaults to `true`. Set it to `false` to omit the model-visible interruption message from the agent's context. - If a custom agent name matches a built-in agent such as `explorer`, your custom agent takes precedence. ### Custom agent file schema | Field | Type | Required | Purpose | | ------------------------ | ------ | :------: | --------------------------------------------------------------- | | `name` | string | Yes | Agent name Codex uses when spawning or referring to this agent. | | `description` | string | Yes | Human-facing guidance for when Codex should use this agent. | | `developer_instructions` | string | Yes | Core instructions that define the agent's behavior. | You can also include other supported `config.toml` keys in a custom agent file, such as `model`, `model_reasoning_effort`, `sandbox_mode`, `mcp_servers`, and `skills.config`. Codex identifies the custom agent by its `name` field. Matching the filename to the agent name is the simplest convention, but the `name` field is the source of truth. ### Example custom agents The best custom agents are narrow and opinionated. Give each one clear job, a tool surface that matches that job, and instructions that keep it from drifting into adjacent work. The examples use [GPT-6.1 Sol](https://learn.chatgpt.com/docs/models#gpt-6.1-sol) where your signed-in account or workspace has access. If it isn't available, choose a model you can use. #### Example 1: PR review This pattern splits review across three focused custom agents: - `pr_explorer` maps the codebase and gathers evidence. - `reviewer` looks for correctness, security, and test risks. - `docs_researcher` checks framework or API documentation through a dedicated MCP server. Project config (`.codex/config.toml`): ```toml [agents] max_concurrent_threads_per_session = 8 ``` `.codex/agents/pr-explorer.toml`: ```toml name = "pr_explorer" description = "Read-only codebase explorer for gathering evidence before changes are proposed." model = "gpt-6-luna" model_reasoning_effort = "high" sandbox_mode = "read-only" developer_instructions = """ Stay in exploration mode. Trace the real execution path, cite files and symbols, and avoid proposing fixes unless the parent agent asks for them. Prefer fast search and targeted file reads over broad scans. """ ``` `.codex/agents/reviewer.toml`: ```toml name = "reviewer" description = "PR reviewer focused on correctness, security, and missing tests." model = "gpt-6.1-sol" model_reasoning_effort = "medium" sandbox_mode = "read-only" developer_instructions = """ Review code like an owner. Prioritize correctness, security, behavior regressions, and missing test coverage. Lead with concrete findings, include reproduction steps when possible, and avoid style-only comments unless they hide a real bug. """ ``` `.codex/agents/docs-researcher.toml`: ```toml name = "docs_researcher" description = "Documentation specialist that uses the docs MCP server to verify APIs and framework behavior." model = "gpt-6-luna" model_reasoning_effort = "high" sandbox_mode = "read-only" developer_instructions = """ Use the docs MCP server to confirm APIs, options, and version-specific behavior. Return concise answers with links or exact references when available. Do not make code changes. """ [mcp_servers.openaiDeveloperDocs] url = "https://developers.openai.com/mcp" ``` This setup works well for prompts like: ```text Review this branch against main. Have pr_explorer map the affected code paths, reviewer find real risks, and docs_researcher verify the framework APIs that the patch relies on. ``` #### Example 2: Frontend integration debugging This pattern is useful for UI regressions, flaky browser flows, or integration bugs that cross application code and the running product. Project config (`.codex/config.toml`): ```toml [agents] max_concurrent_threads_per_session = 6 ``` `.codex/agents/code-mapper.toml`: ```toml name = "code_mapper" description = "Read-only codebase explorer for locating the relevant frontend and backend code paths." model = "gpt-6-luna" model_reasoning_effort = "high" sandbox_mode = "read-only" developer_instructions = """ Map the code that owns the failing UI flow. Identify entry points, state transitions, and likely files before the worker starts editing. """ ``` `.codex/agents/browser-debugger.toml`: ```toml name = "browser_debugger" description = "UI debugger that uses browser tooling to reproduce issues and capture evidence." model = "gpt-6.1-sol" model_reasoning_effort = "medium" sandbox_mode = "workspace-write" developer_instructions = """ Reproduce the issue in the browser, capture exact steps, and report what the UI actually does. Use browser tooling for screenshots, console output, and network evidence. Do not edit application code. """ [mcp_servers.chrome_devtools] url = "http://localhost:3000/mcp" startup_timeout_sec = 20 ``` `.codex/agents/ui-fixer.toml`: ```toml name = "ui_fixer" description = "Implementation-focused agent for small, targeted fixes after the issue is understood." model = "gpt-6-luna" model_reasoning_effort = "high" developer_instructions = """ Own the fix once the issue is reproduced. Make the smallest defensible change, keep unrelated files untouched, and validate only the behavior you changed. """ [[skills.config]] path = "/Users/me/.agents/skills/docs-editor/SKILL.md" enabled = false ``` This setup works well for prompts like: ```text Investigate why the settings modal fails to save. Have browser_debugger reproduce it, code_mapper trace the responsible code path, and ui_fixer implement the smallest fix once the failure mode is clear. ``` --- # Use ChatGPT Work and Codex with Amazon Bedrock Configure local ChatGPT Work and Codex surfaces to use OpenAI models available through Amazon Bedrock. In this setup, the local client sends model requests to Bedrock using AWS-managed authentication and access controls. This page covers direct access to Bedrock. If your organization already provides a model gateway, follow [Use API/provider credentials](https://learn.chatgpt.com/docs/enterprise/connect-to-a-gateway). To configure a gateway backed by Bedrock, see [Bedrock through LiteLLM](https://learn.chatgpt.com/docs/enterprise/bedrock-through-litellm). ## How it works When you configure a local ChatGPT Work or Codex surface with Amazon Bedrock as the model provider, the OpenAI-hosted Responses API isn't in the request path. The local client sends model requests to Amazon Bedrock, and Bedrock provides an OpenAI-compatible Responses API implementation for supported OpenAI models. Authentication is AWS-native. Users authenticate with a Bedrock API key or AWS IAM credentials. They do not use ChatGPT sign-in or `OPENAI_API_KEY` for this provider. ## Before you start Make sure you have: - Credentials for the AWS account you want to use. - Access to supported OpenAI models in Amazon Bedrock. - Access to an AWS Region where the selected model is available. - AWS permission to invoke the selected model or inference profile. Check the model-specific IAM requirements. For example, GPT-6 Sol through Runtime also requires `bedrock:InvokeModel` on the account's default project. See AWS's [GPT-6 Sol setup instructions](https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-openai-gpt-6-sol.html). ## Configure the provider Codex allows you to configure the provider by setting `model_provider` in `~/.codex/config.toml`. The ChatGPT desktop app, Codex CLI, IDE extension, and SDK read the same local configuration layers. Choose the provider for the Amazon Bedrock endpoint you want to use: Bedrock Runtime for cross-Region inference (CRIS), or Bedrock Mantle for in-Region inference. Use Bedrock Runtime for new configurations: ```toml model_provider = "amazon-bedrock-runtime" web_search = "disabled" ``` Hosted web search isn't available on Bedrock Runtime. If you need it, use [Bedrock Mantle](#use-mantle-for-hosted-web-search). The `amazon-bedrock` provider selects Mantle; `amazon-bedrock-runtime` selects Runtime. ### Use Mantle for hosted web search For the Bedrock Mantle endpoint: ```toml model_provider = "amazon-bedrock" web_search = "cached" ``` ### Choose a model Codex uses the configured `model_provider` to choose which models appear in the model picker: models supported through the Bedrock Runtime endpoint for `amazon-bedrock-runtime`, or through the Bedrock Mantle endpoint for `amazon-bedrock`. You can optionally specify a [supported model](#supported-models) in the configuration file. The built-in provider supplies its own model catalog. When switching endpoints, change the provider and any explicit model ID together. Model availability varies by AWS Region. Refer to AWS [Regional availability by models](https://docs.aws.amazon.com/bedrock/latest/userguide/models-region-compatibility.html#model-regions-openai). ## Authentication options Local ChatGPT Work and Codex surfaces support two Bedrock authentication paths. They check them in this order: 1. Bedrock API key. 2. AWS SDK credential chain. ### Option 1: Bedrock API key Set the Bedrock API key in the environment the local client reads. You must specify a Region when using API-key authentication. ```shell export AWS_BEARER_TOKEN_BEDROCK= export AWS_REGION=us-east-2 ``` On Windows PowerShell: ```powershell $env:AWS_BEARER_TOKEN_BEDROCK = "" $env:AWS_REGION = "us-east-2" ``` ### Option 2: AWS SDK credentials Use this path when your organization manages Bedrock access through the AWS SDK credential chain. The local client can use these standard AWS SDK credential sources: #### Shared AWS configuration files Configure the shared AWS `config` and `credentials` files: ```shell aws configure ``` #### Environment variables Set the standard AWS SDK credential environment variables: ```shell export AWS_ACCESS_KEY_ID= export AWS_SECRET_ACCESS_KEY= export AWS_SESSION_TOKEN= ``` #### AWS Management Console credentials Log in with AWS Management Console credentials: ```shell aws login ``` #### AWS SSO or a named profile Log in with AWS SSO and select the named profile: ```shell aws sso login --profile codex-bedrock export AWS_PROFILE=codex-bedrock ``` #### Federated identity For corporate SSO or OIDC federation, configure a federated identity with `credential_process` outside the local client and let the AWS SDK resolve credentials. Put browser login, token exchange, caching, and refresh in your AWS profile's `credential_process` helper. ## Desktop app and IDE extension Desktop apps and IDE extensions may not inherit environment variables from the shell. Put required values in `~/.codex/.env`, then restart the app or extension. On Windows, the default path is `%USERPROFILE%\.codex\.env`. ```shell export AWS_BEARER_TOKEN_BEDROCK= export AWS_REGION=us-east-2 ``` ## Verify setup - In Codex CLI, open `/status` and confirm the model provider matches your endpoint: `amazon-bedrock` for Mantle in-Region inference, or `amazon-bedrock-runtime` for Runtime Global or Geo cross-Region inference. - In the ChatGPT desktop app, select Work or Codex and start a new task after restarting the app. - In the IDE extension, start a new session after restarting the extension. - Confirm the selected model is available in the configured AWS Region and that the AWS identity has permission to access it. Then send a short prompt in a new task: ```text Reply with exactly: bedrock-ok ``` Expect `bedrock-ok`. Confirm the provider and model in the client; the reply alone doesn't identify the route. For rollout qualification, use a disposable folder with read-only permissions and verify a harmless local tool task and a follow-up turn. ## Supported models Use an inference profile ID for Bedrock Runtime provider or a model ID for Bedrock Mantle provider. The selected model or profile must be available in your AWS Region and accessible to your AWS identity. ### Global and Geo cross-Region inference using the Bedrock Runtime endpoint Global CRIS can route requests to supported commercial AWS Regions worldwide, whereas Geo CRIS routes requests within the profile's geography. Choose a routing scope that meets your AWS permissions and data-residency requirements. Use `model_provider = "amazon-bedrock-runtime"` with the optional `model` configuration set to an inference profile ID from the following lists. The provider uses `https://bedrock-runtime.{region}.amazonaws.com/openai/v1`, where `{region}` is the supported source AWS Region from which you send requests. Both Global and Geo CRIS use this endpoint address. #### Global CRIS Supported models and inference profile IDs: - GPT-6 Astra: `global.openai.gpt-6-astra` - GPT-6 Sol: `global.openai.gpt-6-sol` - GPT-6 Luna: `global.openai.gpt-6-luna` For example, configure Astra with Global CRIS in `~/.codex/config.toml`: ```toml model_provider = "amazon-bedrock-runtime" model = "global.openai.gpt-6-astra" ``` #### United States Geo CRIS Supported models and inference profile IDs: - GPT-6 Astra: `us.openai.gpt-6-astra` - GPT-6 Sol: `us.openai.gpt-6-sol` - GPT-6 Luna: `us.openai.gpt-6-luna` Codex's built-in Runtime model picker lists the United States Geo and Global variants. Model and CRIS availability vary by source AWS Region. See AWS [Supported Regions and models for inference profiles](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html), which links to each model's exact inference profile IDs and regional availability, and AWS [Regional availability by models](https://docs.aws.amazon.com/bedrock/latest/userguide/models-region-compatibility.html#model-regions-openai) before selecting a provider and a model. ### In-Region inference using the Bedrock Mantle endpoint Use `model_provider = "amazon-bedrock"` with an optional model ID. The provider uses `https://bedrock-mantle.{region}.api.aws/openai/v1`. Supported models and model IDs: - GPT-6 Astra: `openai.gpt-6-astra` - GPT-6 Sol: `openai.gpt-6-sol` - GPT-6 Luna: `openai.gpt-6-luna` GPT-6 Sol and Luna are available through Mantle in `us-east-1` (N. Virginia). Model availability varies by AWS Region. See AWS [Regional availability by models](https://docs.aws.amazon.com/bedrock/latest/userguide/models-region-compatibility.html#model-regions-openai) before selecting a provider and a model. For GPT-6 Astra, refer to the [Bedrock model page for GPT-6 Astra](https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-openai-gpt-6-astra.html). ## Feature availability This configuration supports local ChatGPT Work and Codex workflows. Hosted ChatGPT Work on the web, Codex cloud, and features that depend on OpenAI-hosted cloud services or cloud-managed discovery aren't currently available. Hosted web search is unavailable on Runtime; use [Mantle](#use-mantle-for-hosted-web-search) if you need it. Codex Security CLI uses its own provider configuration. Follow its [Amazon Bedrock setup](https://learn.chatgpt.com/docs/security/cli/reference) rather than the native client settings above. Fast Mode isn't available with Amazon Bedrock. Fast Mode uses priority processing, and the initial Amazon Bedrock offering supports on-demand inference only.
* Feature is currently limited to only specific regions. Check the individual feature documentation to learn more about regional restrictions.
† Local plugin bundles and OpenAI-curated plugins that don't require ChatGPT authentication, including Codex Security, are available. Plugins that require ChatGPT authentication, connectors, or cloud-hosted sharing aren't available. ## Troubleshooting If setup fails, check the following: - The model ID exactly matches a supported model. - You use the correct model provider for the endpoint: `amazon-bedrock-runtime` for Runtime endpoint or `amazon-bedrock` for Mantle endpoint. - You specify an AWS Region where the model is available. - The Bedrock API key or AWS credentials are valid and not expired. - The AWS identity has permission to access the selected Bedrock model. - `AWS_BEARER_TOKEN_BEDROCK` isn't set to an expired or unintended key. - For desktop app or IDE extension usage, required environment variables are present in `~/.codex/.env`. For AWS SDK profile authentication, run `aws sts get-caller-identity --profile codex-bedrock` to confirm the identity for your selected profile. Replace `codex-bedrock` with your profile name, or omit `--profile` when using the default credential chain. This checks AWS identity, not permission to invoke a Bedrock model. Check `AWS_BEARER_TOKEN_BEDROCK` separately so an unintended API key doesn't select a different authentication path. ## Support boundaries OpenAI Support can help with ChatGPT Work and Codex client setup, configuration, local CLI behavior, desktop app behavior, IDE extension behavior, and the local product experience. For AWS credentials, IAM permissions, Bedrock model access, quotas, billing, regional availability, Bedrock request failures, AWS service logs, or Bedrock service behavior, contact the customer's AWS administrator or AWS Support. --- # Annotations Extensibility The Browser Annotation API lets your website customize what people select, what context accompanies their feedback, and which controls they use to preview changes before sending an annotation to ChatGPT. In ChatGPT Enterprise and Edu workspaces, an admin must allow **Site annotation customizations** through workspace policy. [Browser annotations](https://learn.chatgpt.com/docs/browser?surface=app#app-comment-on-the-page) work on your site without any code changes. People can select part of a page, add a comment, and send it in Context to Codex or ChatGPT Work. As a developer, you can use the Browser Annotation API to provide context or controls specific to your application. For example, you can attach previews for component variants in a design system preview for developers to know how to update the components on a website. To get help understanding the Browser Annotation API or adding annotation support to your website, install the Annotations Extensibility plugin. [Install the Annotations Extensibility plugin](https://chatgpt.com/plugins/Plugin_94f13f4285908191bb882d31b1ffc59e) **Try it** See the Browser Annotation API in action on this guide. 1. Open this page in ChatGPT's built-in browser. 2. Try opening the suggested prompt that will appear in this card. 3. Enter [Annotation mode](https://learn.chatgpt.com/docs/browser?surface=app#app-comment-on-the-page), then select the table below or a code sample to switch between predefined layouts and themes. 4. You can still annotate any item on the page and see default annotation behavior. [Open in ChatGPT's browser](https://chatgpt.com/codex/deeplink?url=https%3A%2F%2Flearn.chatgpt.com%2Fdocs%2Fannotations-extensibility) ## Choose what to customize Start with the integration that fits your website: | Goal | Integration | | ---------------------------------------------------------------- | -------------------------------------------------------------- | | Make a card or other group of elements selectable as one object | [Selection targets](#customize-selection-targets) | | Let people select a phrase or sentence | [Text selection containers](#enable-text-selection) | | Include additional context with a selection | [Selection metadata](#add-context-to-a-selection) | | Open an annotation from your own button with a suggested comment | [Annotation requests](#open-an-annotation-from-your-website) | | Request feedback on an exact passage from your own UI | [Text-range requests](#request-an-annotation-for-a-text-range) | | Show advanced controls when an annotation opens | [Editor defaults](#choose-the-editors-default-mode) | | Preview application properties or collect choices | [Custom controls](#add-custom-controls) | | Select individual objects drawn inside a canvas | [Annotation surfaces](#make-canvas-objects-selectable) | | Turn Annotation mode on or off from your site | [Annotation mode controls](#control-annotation-mode) | This guide targets the DevDay 2026 release of the ChatGPT desktop app and later. The JavaScript API is available through `document.oai.annotation` in the app's built-in browser, on secure, top-level pages such as HTTPS or localhost. When enabled, the browser installs it before your page's scripts run. Feature-detect each method to support older or unsupported browsers, then initialize your integration once its DOM elements exist. No readiness event or polling is needed. API methods return synchronously, and registration handles are ready to use immediately. The browser can finish loading the annotation editor afterward. A surface's `hitTest` callback can return a promise. ## Customize selection targets By default, Annotation mode selects elements from the page's DOM, favoring targets such as text, images, and controls. To make a larger object selectable, mark its containing region with `oai-annotation-container` and its selectable descendants with `oai-annotatable`. This example makes a chart card selectable as one object: ```html

Q3 Revenue

$120,000 this quarter

``` Pointing anywhere within the card highlights the entire card. The optional `oai-annotatable` value gives the object a name shown to the user and the model. Choose names that distinguish nearby objects, or omit the value. The container defines where these selection rules apply. An `oai-annotatable` attribute on its own doesn't change selection behavior. Within a container, the browser selects the nearest marked target containing the element under the pointer. Nested containers use the nearest container. Unmarked areas inside a container create a webpage annotation; areas outside all containers keep the default behavior. ## Enable text selection Add `oai-annotation-container-text` to a region to let people drag to select text during Annotation mode. The attribute doesn't need a value: ```html

Design guidelines

Use consistent spacing between related components.

Leave more space between separate groups.

``` Releasing a nonempty selection opens the text annotation editor with the selected range and its context. Clicking without selecting text doesn't create an annotation. **Escape** or a canceled gesture cancels the selection. The nearest text or DOM selection container determines how a gesture begins. Text containers don't use `oai-annotatable` markers for element picking. Nest an `oai-annotation-container` to restore element picking, or a text container to restore text selection. If both attributes are on one element, text selection takes precedence. Text selection follows the page's normal selection rules and can extend beyond the starting container. A container doesn't clip the range or enable selection inside an iframe. Text fields remain selectable, but ordinary page clicks and native actions on controls remain blocked during Annotation mode. Explicit `request()` calls keep their existing behavior. Text selection containers take effect only during Annotation mode when the site annotation capability and per-site setting are enabled. ## Add context to a selection Add `oai-annotation-metadata` to a marked target to include context that may not be visible on the page. For example, a fictional contact row can include an email address for a request to draft an email: ```html
Alex Morgan
Project lead
```