Skip to content

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 persistent config.toml defaults
  • 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-write mode, and .git being 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:

DialParameter ManagedConfig KeyCLI FlagShort Flag
Sandbox ModeAction boundaries (file system & network)sandbox_mode--sandbox-s
Approval PolicyPrompting 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-write and approval to on-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-access and approval to never. 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.

Permission dials: Sandbox Mode x Approval Policy

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 ModeWrite Access?Network Access?Best for
read-only❌ No (requires approval to write)❌ NoReviewing code, planning, discussing architecture ("don't touch my files")
workspace-write✅ Yes (inside workspace only)Off by default; must enable manuallyThe default sweet spot for daily development
danger-full-access✅ Yes (entire machine)✅ YesIsolated 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:

toml
[sandbox_workspace_write]
network_access = true

When 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:

text
Sandbox: workspace-write
Approval: on-request
Workspace directories:
  /Users/you/myproject
  /tmp

The 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 PathReason for Protection
<workspace>/.gitPrevents the agent from rewriting Git history or corrupting the repository
<workspace>/.agentsPrevents the agent from modifying its own agent configuration
<workspace>/.codexPrevents 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-write is the daily default, but remember that network access is disabled by default, and .git / .agents / .codex are read-only protected; enable network_access manually to allow network calls, and run /status to 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 PolicyAgent BehaviorPlain English
untrustedRuns "known safe" read-only actions automatically; prompts for everything elseBlocks unfamiliar commands; most cautious
on-requestRuns tasks inside the sandbox automatically, prompting only when stepping outThe most common balanced default
neverRuns without approval promptsUsed 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-request is the daily default; untrusted is stricter (free to read, prompts to edit); never means "no prompts," not "no restrictions," and pairs with any sandbox mode (like read-only + never for 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:

bash
codex --sandbox workspace-write --ask-for-approval on-request

The fence is locked, and it prompts only when stepping out. The short flags are -s and -a:

bash
codex -s read-only -a on-request "Review this code, do not edit"

To switch modes mid-session, run:

text
/permissions

Select 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 /permissions menu may list Ask for approval / Approval for me / Full access (approval settings) rather than Read Only. To set read-only mode, pass the startup flag codex --sandbox read-only or configure sandbox_mode = "read-only" in ~/.codex/config.toml. Subsequent references to switching to read-only via /permissions follow this guide.

Let's trace the sandbox and approval check sequence:

Two-tier permission check: sandbox validation first, followed by approval check

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:

toml
approval_policy = "on-request"
sandbox_mode    = "workspace-write"

For maximum security, configure approval_policy = "untrusted" and sandbox_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:

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"

Launch with the target profile:

bash
codex --profile full_auto

Note: Profiles (configuration files) are separate from permission profiles (the Beta path mapping file system and network boundaries). The configurations sandbox_mode + approval_policy represent the primary settings path to master first.

💡 Summary in one sentence: Adjust settings temporarily via -s / -a or the /permissions menu, and persistently via sandbox_mode + approval_policy in ~/.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):

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):

DecisionResult
allowRuns without prompting
promptPrompts before running
forbiddenBlocks 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_mode or 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):

ProfileWhat It Does
:read-onlyRestricts local commands to read-only access
:workspaceAllows writing to the workspace root and temporary directories
:danger-full-accessRemoves local sandbox restrictions

A custom profile (making the workspace writable while blocking access to .env files):

toml
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 (deny takes 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 FolderDefault 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" and approval_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:

EnvironmentSafe 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):

bash
mkdir -p ~/perm-demo && cd ~/perm-demo
codex

Since this folder is not managed by Git, Codex defaults to read-only mode on launch.

Step 2: Verify active settings

Check the active session configurations:

text
/status

Expected 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:

text
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:

text
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

text
/permissions

Select 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.

text
Created hello.txt

Step 5: Verify default network restrictions

With workspace write active, ask it to make a network call:

text
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:

GoalConfigurationKey Takeaway
Limit ScopeSandbox Mode (--sandbox)read-only / workspace-write / danger-full-access
Limit PromptsApproval Policy (--ask-for-approval)untrusted / on-request / never (independent dial)
Adjust TemporarilyCLI flags / /permissions menuAdjust settings on the fly mid-session
Set Defaultsconfig.tomlSet sandbox_mode + approval_policy persistently
Fine-Grained Rulesrules / permission profilesAdvanced; customize command prefixes, paths, and domains
Full Access--yolo runUse 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.