Permissions, Sandboxes, and Approvals: Customizing Security Settings
📚 Series Navigation: The previous article 14 · Four Daily Workflows integrated Codex into your daily development rhythm. This article shifts perspective—managing "what it is allowed to touch" rather than "how it works." From prompting for every command to running completely unattended, we will explain how to adjust sandbox and approval settings, and when to use which mode.
Let me share a stupid mistake I made last winter. I had just gotten comfortable configuring Codex, and to avoid prompts, I set sandbox_mode permanently to danger-full-access in my ~/.codex/config.toml. Later, in a temporary directory not initialized with Git, I asked it to "clean up unused files." It began scanning my entire home directory because under full access mode, there was no workspace boundary restricting it. I scrambled to hit Esc to interrupt the execution, and my back was cold.
Looking back, the issue wasn't Codex; it was me: I configured a dangerous setting intended for isolated containers as my global default. It didn't fail; I simply loosened the reins where I shouldn't have.
Article 02 explained sandboxes and approvals using the analogies of "playground fences" and "reception desks + guards." This article bypasses definitions to focus on: how to configure and select settings. Which modes to pair, how to adjust them on the fly via the command line, how to save them in configuration files, and where to draw the line for dangerous modes.
After reading this article, you will get:
- A matrix explaining how the three sandbox modes (
read-only/workspace-write/danger-full-access) pair with the three approval policies (untrusted/on-request/never) - Configuration templates for both command-line flags (
--sandbox/--ask-for-approval) and persistentconfig.tomldefaults - What default mode Codex assigns on startup (depending on whether the folder has Git initialized) and why
- Important default values—such as network access being disabled by default under
workspace-writemode, and.gitbeing read-only protected - Where the boundary lies for
--yolo(completely open) runs, and why you should avoid it on local and production machines
⚠️ All specific commands, configuration options, and defaults mentioned below are based on the Codex official security and approval documentation; model names and version numbers are subject to change. The permission profiles (permission profiles) mentioned in Section 05 are Beta features subject to change.
01 Understand First: You Are Adjusting Two Independent Dials
Let's clarify a common point of confusion: sandboxes and approvals are not different levels of the same setting; they are independent dials managing separate parameters.
We used analogies in Article 02; here, let's translate them to configurations—they are separate keys in config.toml and separate arguments on the command line:
| Dial | Parameter Managed | Config Key | CLI Flag | Short Flag |
|---|---|---|---|---|
| Sandbox Mode | Action boundaries (file system & network) | sandbox_mode | --sandbox | -s |
| Approval Policy | Prompting rules (whether to pause for human review) | approval_policy | --ask-for-approval | -a |
Why emphasize "independent"? Beginners often assume that "enabling full access stops prompt popups"—it does not. Full access (maxing out the sandbox dial) and skipping prompts (maxing out the approval dial) are separate parameters. You can configure "full access to the machine, prompting for every command," or "read-only access, reading quietly without prompting." The combination of these two determine the "strictness" of the agent's permissions.
Analogy: Gears and speed limits on a car. The sandbox is like your gear—P gear (read-only) keeps the car stationary, D gear (workspace-write) lets you drive on roads, and off-road gear (danger-full-access) lets you drive anywhere. The approval policy is like your speed limit alerts—you can set it to alert you only when speeding (on-request), alert you on any unfamiliar action (untrusted), or turn off alerts completely (never). The gear determines where the car can go; the alert determines when it prompts you—they do not replace each other.
Real-world scenarios to understand this separation:
- You want the agent to read code only and write an analysis: set sandbox to
read-only. The approval setting doesn't matter, as it cannot write files anyway. - You want the agent to edit code in the project, but prompt before leaving the folder: set sandbox to
workspace-writeand approval toon-request. This is the daily sweet spot. - You want to run batch tasks in an isolated container without prompt interruptions: set sandbox to
danger-full-accessand approval tonever. Both dials are maxed out—but only inside a container, as emphasized below.
💡 Summary in one sentence: The sandbox (
--sandbox) manages boundaries, and approvals (--ask-for-approval) manage prompting; they are independent dials, represented by separate keys in configurations. The strictness you experience is the combination of these two.

This matrix maps the two dials: the horizontal axis represents sandbox modes (from strict read-only to loose danger-full-access), and the vertical axis represents approval policies (from cautious untrusted to quiet never). The blue intersection workspace-write + on-request is the daily sweet spot, while the red intersection danger-full-access + never (or --yolo) should only be used in isolated containers.
02 Three Sandbox Modes: Defining the Scope of Access
The sandbox dial has three tiers, defined clearly in the official docs. Let's list their capabilities (write access, network access, and use cases)—this is the most important table to memorize:
| Sandbox Mode | Write Access? | Network Access? | Best for |
|---|---|---|---|
read-only | ❌ No (requires approval to write) | ❌ No | Reviewing code, planning, discussing architecture ("don't touch my files") |
workspace-write | ✅ Yes (inside workspace only) | ❌ Off by default; must enable manually | The default sweet spot for daily development |
danger-full-access | ✅ Yes (entire machine) | ✅ Yes | Isolated containers or virtual machines; the name "danger" is not an exaggeration |
Let's highlight details that are easy to get wrong:
First, network access is disabled by default under workspace-write mode. This is counterintuitive—you might assume "write access allows running npm install to download dependencies," it does not. The docs state: network access is disabled under workspace-write mode by default, requiring manual configuration. To enable network access, add this block to your config.toml:
[sandbox_workspace_write]
network_access = trueWhen I first asked Codex to run npm install under workspace-write mode, it hung and returned network errors. I spent time troubleshooting proxy settings before realizing the sandbox blocked network access by default. Keep this in mind.
Second, the workspace is not just the "active directory." The docs clarify that the workspace automatically includes the system temporary directories (like /tmp). To check which directories are inside the workspace, run /status in the session. Expected output:
Sandbox: workspace-write
Approval: on-request
Workspace directories:
/Users/you/myproject
/tmpThe first two lines list the active sandbox and approval modes, and Workspace directories lists the allowed write paths.
Third, some directories remain "read-only protected" even under workspace-write mode. This is a safety measure built into Codex—in a writable workspace, these paths remain protected:
| Protected Path | Reason for Protection |
|---|---|
<workspace>/.git | Prevents the agent from rewriting Git history or corrupting the repository |
<workspace>/.agents | Prevents the agent from modifying its own agent configuration |
<workspace>/.codex | Prevents the agent from modifying Codex configurations |
This protection is recursive—applying to all subfolders and files. You don't have to worry about the agent corrupting your .git folder; Codex locks these directories by default.
Fourth, the sandbox restricts both Codex and its child processes. This was mentioned in Article 02; its practical implication is: if Codex calls git, npm, or test scripts, those child processes are restricted to the same sandbox boundaries—preventing child processes from modifying files outside the allowed directories.
💡 Summary in one sentence: Among the three sandbox modes,
workspace-writeis the daily default, but remember that network access is disabled by default, and.git/.agents/.codexare read-only protected; enablenetwork_accessmanually to allow network calls, and run/statusto check the workspace scope.
03 Three Approval Policies: Defining When to Prompt
The approval dial also has three tiers. While the sandbox defines boundaries, the approval policy defines when to pause execution to ask for confirmation:
| Approval Policy | Agent Behavior | Plain English |
|---|---|---|
untrusted | Runs "known safe" read-only actions automatically; prompts for everything else | Blocks unfamiliar commands; most cautious |
on-request | Runs tasks inside the sandbox automatically, prompting only when stepping out | The most common balanced default |
never | Runs without approval prompts | Used in automation; boundaries are still enforced by the sandbox, making this useful when paired with full access |
A detail from the docs: untrusted is not the same as "read-only." It still runs safe read-only operations automatically, but prompts for commands that "modify state or trigger external execution" (such as destructive Git operations or commands with configuration override parameters). The experience of untrusted is "free to read, prompts to edit," making it stricter and more verbose than on-request.
Another detail: never pairs with any sandbox mode. Beginners assume never (no prompts) implies "no restrictions," which is incorrect. The docs state that --ask-for-approval never pairs with any --sandbox setting—you can configure read-only + never, meaning "read code only, and never prompt me." This is the standard setting for read-only analysis in CI, which is secure. "No prompts" is not "no restrictions"—verifying the "two independent dials" concept.
Who reviews approvals? By default, prompts are sent to you (approvals_reviewer = "user"). The system also supports an auto_review option—letting an automated review agent verify approval requests. This is an advanced capability; its logic and risks are covered in Article 16: Security and Risk Boundaries. For daily workflows, user is sufficient.
💡 Summary in one sentence: Among the three approval policies,
on-requestis the daily default;untrustedis stricter (free to read, prompts to edit);nevermeans "no prompts," not "no restrictions," and pairs with any sandbox mode (likeread-only+neverfor CI analysis).
04 How to Configure: Command-Line Flags vs. config.toml Defaults
Once you select your modes, apply them in two ways: temporary command-line flags, or persistent settings in the configuration file.
On the Fly: Command-Line Flags (Active session only)
Specify flags on startup to configure the active session. The low-risk daily combo:
codex --sandbox workspace-write --ask-for-approval on-requestThe fence is locked, and it prompts only when stepping out. The short flags are -s and -a:
codex -s read-only -a on-request "Review this code, do not edit"To switch modes mid-session, run:
/permissionsSelect your desired level (Read Only / Auto / Full Access etc.) in the menu, applying it instantly. My workflow: when exploring a legacy project, I switch to read-only first to let it read and explain the code, and switch to workspace-write once I understand the codebase—avoiding accidental edits to code I haven't reviewed.
⚠️ Newer menus may vary: from codex-cli 0.142 onwards, the system introduces permission profiles (Beta) to replace old presets. Your
/permissionsmenu may listAsk for approval/Approval for me/Full access(approval settings) rather thanRead Only. To set read-only mode, pass the startup flagcodex --sandbox read-onlyor configuresandbox_mode = "read-only"in~/.codex/config.toml. Subsequent references to switching to read-only via/permissionsfollow this guide.
Let's trace the sandbox and approval check sequence:

Every action runs through two gates: first, Codex checks if the action is inside the sandbox boundaries (managed by sandbox mode); if it steps out, it checks the approval settings (managed by approval policy) to determine whether to prompt you.
Persistently: config.toml Defaults (Applies to all sessions)
To set defaults permanently, add these lines to ~/.codex/config.toml:
approval_policy = "on-request"
sandbox_mode = "workspace-write"For maximum security, configure
approval_policy = "untrusted"andsandbox_mode = "read-only". This starts every session with maximum restriction, letting you delegate permissions manually as needed. Recommended for production codebases and shared environments.
If you use multiple combinations (such as "daily dev vs. CI runs"), save them as profiles using the --profile flag:
# ~/.codex/full_auto.config.toml
approval_policy = "on-request"
sandbox_mode = "workspace-write"# ~/.codex/readonly_quiet.config.toml
approval_policy = "never"
sandbox_mode = "read-only"Launch with the target profile:
codex --profile full_autoNote: Profiles (configuration files) are separate from permission profiles (the Beta path mapping file system and network boundaries). The configurations
sandbox_mode+approval_policyrepresent the primary settings path to master first.
💡 Summary in one sentence: Adjust settings temporarily via
-s/-aor the/permissionsmenu, and persistently viasandbox_mode+approval_policyin~/.codex/config.toml; switch configuration sets using--profile.
05 Advanced Configuration: Fine-Grained Rules and Permission Profiles (Beta)
The standard settings configure global parameters. If you need to manage access at the level of specific commands or file paths, Codex provides two advanced tools.
rules: Custom Command Verification
⚠️ Rules are an experimental feature subject to change.
To restrict specific commands, use rules (rules). Note that the allowed decisions are allow / prompt / forbidden (different from ask or deny in other tools).
This manages specific command boundaries: while the sandbox defines coarse directory boundaries, rules let you configure fine-grained actions—like "allow gh pr view to run without prompts even if it accesses the network," or "block grep to force using rg."
Configure rules in .rules files under ~/.codex/rules/, using Starlark syntax (resembling Python):
prefix_rule(
pattern = ["gh", "pr", "view"],
decision = "prompt",
justification = "Allow viewing PRs, but prompt for confirmation",
)The three decisions are ranked by priority—strictest wins (forbidden > prompt > allow):
| Decision | Result |
|---|---|
allow | Runs without prompting |
prompt | Prompts before running |
forbidden | Blocks execution immediately |
Security detail: if a prompt chains multiple commands like git add . && rm -rf /, Codex splits them and evaluates each command separately—blocking rm -rf / even if git add is allowed, preventing chained bypasses. Verify rule evaluations using codex execpolicy check before deploying them.
permission profiles: Bundling Boundaries (Beta)
⚠️ Permission profiles are a Beta feature and cannot be mixed with standard sandbox settings. If you configure
sandbox_modeor pass--sandbox, Codex defaults to the standard sandbox settings. Use one path or the other.
If you want to configure specific directories as writable, block specific files like .env, or restrict network access to specific domains, use permission profiles (permission profiles). These bundle filesystem rules and network rules into a profile, specified via default_permissions.
The three built-in profiles (prefixed with colons):
| Profile | What It Does |
|---|---|
:read-only | Restricts local commands to read-only access |
:workspace | Allows writing to the workspace root and temporary directories |
:danger-full-access | Removes local sandbox restrictions |
A custom profile (making the workspace writable while blocking access to .env files):
default_permissions = "project-edit"
[permissions.project-edit]
extends = ":workspace"
[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"
"**/*.env" = "deny"
[permissions.project-edit.network]
enabled = true
[permissions.project-edit.network.domains]
"api.openai.com" = "allow"Filesystem access uses three levels: read / write / deny, where deny takes priority (deny > write > read), and specific paths override broad ones. This allows configuring "writable workspace except for .env files." Network access uses a default-deny policy—blocking all domains unless explicitly allowed, and deny overrides allow here too.
My recommendation: beginners should skip profiles and focus on the standard configurations in Section 04. Revisit these advanced tools only when you have strict requirements to protect specific files or domains.
💡 Summary in one sentence: Rules restrict access by command prefix (
allow/prompt/forbidden, strictest wins), and permission profiles (Beta) restrict access by path and domain (denytakes priority); both are advanced settings, so master the standard configurations first.
06 Default Settings and Dangerous Configurations
Now that we have reviewed the mechanics, how do you choose your settings? Codex assigns a default profile on startup based on the target folder.
Default Mode Assignment
Codex checks if the target folder is managed by version control on startup:
| Target Folder | Default Profile |
|---|---|
| Managed by Git (version-controlled) | Auto Mode (workspace-write + on-request) |
| Not managed by Git (non-version-controlled) | read-only Mode |
This is a logical safety measure: if the folder is managed by Git, edits can be reviewed and reverted via git diff, allowing writable access; if the folder is not managed by Git, edits are permanent, so it defaults to read-only to prevent accidental data loss. This explains my winter mistake—running full access in an unmanaged folder removed these guardrails.
Note: under certain conditions, Codex starts in read-only mode until you explicitly authorize the directory (via a setup prompt or running /permissions). If it acts cautiously and reads only, it is waiting for your authorization.
Let's also note the web search default—web search (web_search) defaults to cache (cached) instead of live indexing. It queries a pre-indexed cache maintained by OpenAI, reducing the risk of prompt injections from live pages. However, enabling full access (--yolo) switches web search to live by default. Force live searches using --search, or disable search completely via web_search = "disabled". Security implications are detailed in Article 16: Security and Risk Boundaries.
The --yolo Boundary
Finally, the boundary for completely open runs. It has two configuration paths:
- In configurations: set
sandbox_mode = "danger-full-access"andapproval_policy = "never" - Via CLI flag: pass
--dangerously-bypass-approvals-and-sandbox(alias--yolo)
--yolo bypasses both sandboxes and approvals, letting Codex run edits on your machine without prompts. When to use it:
| Environment | Safe to Run --yolo? |
|---|---|
| Isolated container / VM / Dev Container | ✅ Yes; data loss is restricted to the container |
| CI pipelines running in isolated environments | ✅ Yes |
| Your local machine | ❌ No; keep approvals active to protect your data |
| Production systems with critical data | ❌ Absolutely not |
The docs mark full access as (not recommended). If your local machine doesn't support Linux sandboxes or you use containerized development, configure Docker or dev containers to isolate the environment, and run --yolo inside the container—leaving containerization to manage the safety boundary. The docs provide a reference configuration for secure devcontainers with egress firewalls.
Note: running full access inside a dev container is still not entirely safe—a compromised project can read files exposed to the container (including your Codex credentials). Only run this on trusted repositories, and monitor execution.
My takeaway: only run full access in isolated environments where data loss is inconsequential; avoid it on local and production machines. Bypassing prompts is not worth the security risk.
💡 Summary in one sentence: Codex defaults to Auto mode in Git repositories and Read-only mode in unmanaged folders; web search defaults to cache to prevent injections; run
--yolo(full access) inside isolated containers only, avoiding it on local and production machines.
07 Hands-on: Verifying the Three Permission Levels
Let's run a test in an empty directory to see how Codex behaves under different permission levels.
Step 1: Create an empty directory, and launch Codex
On Mac / Linux (on Windows PowerShell, replace mkdir -p with mkdir):
mkdir -p ~/perm-demo && cd ~/perm-demo
codexSince this folder is not managed by Git, Codex defaults to
read-onlymode on launch.
Step 2: Verify active settings
Check the active session configurations:
/statusExpected behavior: Codex prints the active sandbox, approval modes, and workspace directories.
Step 3: Try writing a file in read-only mode
Verify permission profiles are set to read-only (switch via /permissions to Read Only if not), and prompt:
Create a hello.txt file with the text "hello codex" inside.Expected behavior: Codex does not write the file directly; it pauses to request approval because writing a file violates read-only boundaries. It prompts:
I need to create the file hello.txt, which exceeds read-only permissions. Allow this action?This demonstrates the sandbox and approval gates working together: the sandbox detects the out-of-bounds action, and the approval policy triggers the prompt.
Step 4: Switch to writable mode, and verify the edit
/permissionsSelect Auto or Workspace Write in the menu, and ask it to create the file again.
Expected behavior: It creates the file directly without prompting, as writing to the workspace is allowed under this mode.
Created hello.txtStep 5: Verify default network restrictions
With workspace write active, ask it to make a network call:
Run curl to query https://example.com, and print the response.Expected behavior: Since network access is disabled by default under workspace-write mode (Section 02), Codex either prompts for approval or returns a connection error—confirming that write access does not include network access. To allow it, you would configure network_access = true in config.toml.
Running these steps verifies: "read-only blocks writes," "writable mode allows workspace edits," and "network access is disabled by default."
💡 Summary in one sentence: Verify the three levels in an empty directory—run
/status→ check that read-only prompts for file creation → check that writable mode edits files directly → check that network access is blocked by default.
08 Summary
This article explored sandboxes, approvals, and permissions:
| Goal | Configuration | Key Takeaway |
|---|---|---|
| Limit Scope | Sandbox Mode (--sandbox) | read-only / workspace-write / danger-full-access |
| Limit Prompts | Approval Policy (--ask-for-approval) | untrusted / on-request / never (independent dial) |
| Adjust Temporarily | CLI flags / /permissions menu | Adjust settings on the fly mid-session |
| Set Defaults | config.toml | Set sandbox_mode + approval_policy persistently |
| Fine-Grained Rules | rules / permission profiles | Advanced; customize command prefixes, paths, and domains |
| Full Access | --yolo run | Use inside isolated containers only; avoid on local/prod machines |
You should now understand how sandbox modes and approval policies combine, configure them on the command line or persistently, verify default settings, and understand the yolo run boundary.
Managing these dials allows you to work with Codex safely and productively.
The next article 16 · Security and Risk Boundaries: this article covered configurations, but the broader question remains: to what extent should you trust an AI agent with your system? How do prompt injections exploit network access? How do you prevent data leaks? How do web search caching and automated reviews protect you? Let's discuss when to restrict and when to grant access next.