The default permission behavior of AI coding tools is intentionally cautious. Every file edit, every shell command — it stops and asks. That’s fine when you’re getting started, but once you start building more projects, the constant approval prompts become a real annoyance.
The goal is to let the tool run freely, but still prompt you (or block outright) for anything destructive.
When you disable permission prompts, the tool will execute commands without asking — including ones that delete files, overwrite content, or modify system settings. If the AI misunderstands your intent, there’s nothing stopping it from making a destructive change before you can intervene. Make sure you’re working inside a git repo so you can roll back if something goes wrong, or in a sandbox environment to isolate any damage to the rest of your system. Either way, take the time to set up the ask and deny rules in this guide before enabling bypass mode.
Table of contents
Open Table of contents
Claude Code
Claude Code stores its settings in a JSON file. You have two locations:
- Project-level:
.claude/settings.jsoninside your repo - Global (applies to every session):
~/.claude/settings.json
For a global setup that follows you everywhere, use the global file. If it doesn’t exist yet, create it.
.claude/settings.json
{
"permissions": {
"defaultMode": "bypassPermissions",
"ask": [
"Bash(rm -rf:*)",
"Bash(rm -r:*)",
"Bash(sudo:*)",
"Bash(chmod:*)",
"Bash(chown:*)",
"Bash(curl:*)",
"Bash(wget:*)"
],
"deny": ["Bash(mkfs:*)", "Bash(dd:*)"]
}
}
How it works
defaultMode: "bypassPermissions" tells Claude Code to auto-approve everything. From there, you layer in exceptions:
ask— Claude will pause and prompt you before running these. Good for commands that are legitimate in dev work but destructive enough to want a heads-up. You’d probably say yes torm -rf node_modulesorsudo apt install— but you want to know about it first.deny— Hard block. Claude won’t run these at all and will tell you it can’t proceed.mkfsformats disks.ddwrites raw to block devices. There’s no scenario where Claude should be touching those unattended.
The evaluation order is: deny → ask → allow. Deny rules always win, regardless of the mode.
If you want Claude Code to skip the bypass mode warning prompt on startup, add "skipDangerousModePermissionPrompt": true as a top-level key alongside permissions.
If a project has its own .claude/settings.json, those rules take precedence. A project could potentially override your global deny rules, so keep an eye on that.
Codex
Codex uses TOML instead of JSON, and the permission model works at the OS level rather than per-command patterns.
The config lives at ~/.codex/config.toml.
.codex/config.toml
model = "gpt-5.4"
approval_policy = "never"
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true
How it works
approval_policy = "never" is the equivalent of bypassPermissions — no confirmation dialogs.
sandbox_mode = "workspace-write" is where Codex differs from Claude Code. Instead of a blocklist of specific commands, Codex uses OS-level sandboxing (Landlock + seccomp on Linux) to restrict what the process can actually reach. With workspace-write, Codex can read and write inside your project directory but is restricted from touching the broader filesystem.
This means rm -rf outside your workspace directory gets blocked at the OS level — not by a pattern rule, but because the process physically can’t reach those paths.
workspace-write grants write access to wherever you launch Codex from. If you run it from your home directory, that’s your workspace. Always launch from inside your project folder.
network_access = true inside the sandbox allows outbound requests. Set it to false if you want to prevent Codex from making arbitrary network calls.
OpenCode
OpenCode uses a JSON config at ~/.config/opencode/opencode.json. Its permission model is pattern-based like Claude Code, but with one key difference: the last matching rule wins (not the first).
opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "allow",
"rm -rf *": "ask",
"rm -r *": "ask",
"sudo *": "ask",
"chmod *": "ask",
"chown *": "ask",
"curl *": "ask",
"wget *": "ask",
"mkfs *": "deny",
"dd *": "deny"
}
}
}
How it works
"*": "allow" at the top is the bypass — it auto-approves everything. Since the last matching rule wins, you put the catch-all first and then override it with more specific rules below.
The ask and deny values work the same way as Claude Code:
ask— prompts before runningdeny— blocks the command entirely
OpenCode uses command * with a space and a shell-style glob. Claude Code uses Bash(command:*). Same intent, different format.
Comparison
| Claude Code | Codex | OpenCode | |
|---|---|---|---|
| Config file | ~/.claude/settings.json | ~/.codex/config.toml | ~/.config/opencode/opencode.json |
| Format | JSON | TOML | JSON |
| Bypass setting | "defaultMode": "bypassPermissions" | approval_policy = "never" | "*": "allow" |
| Blocking approach | Pattern rules (deny wins first) | OS-level sandbox (Landlock+seccomp) | Pattern rules (last rule wins) |
| Ask rules | ✅ | ❌ (sandbox only) | ✅ |
| Hard deny rules | ✅ | ❌ (sandbox only) | ✅ |
Codex’s sandbox approach is more heavy-handed but also more reliable — a pattern rule can be circumvented by a slightly different command, while a filesystem restriction cannot. Claude Code and OpenCode give you more granular control at the cost of needing to maintain the blocklist yourself.
For local dev, any of these configs will get you a frictionless workflow without leaving the door wide open.