Stopping the permission prompts: every option ranked by blast radius

"How do I make Claude Code stop asking me" has about six different answers depending on how much risk you're willing to trade for how much quiet. Ranked from smallest blast radius to largest — not from easiest to hardest, which is a different ordering entirely and part of why people jump straight to the bottom of this list.

On this page

1. Allow rules

Blast radius: exactly whatever's on the list. The narrowest fix, and the right first move for almost every project — describe the handful of commands you already trust and leave everything else prompting:

{
  "permissions": {
    "allow": ["Bash(git diff:*)", "Bash(git status:*)", "Bash(npm test:*)", "Read(./src/**)"]
  }
}

Sane when: your task's dangerous surface is small and knowable ahead of time — a CI job that only ever runs tests and reads source, say. Not sane when: the task is open-ended (a general-purpose coding agent) and you'd be listing an unbounded set of commands to keep up with what it actually needs, at which point you're either under-matching (still prompting constantly) or over-matching (writing rules broad enough to defeat the point).

2. acceptEdits mode

Blast radius: every file edit, but nothing else. One step up from allow rules — instead of listing files, you accept the whole category of "changes to files in this project" while Bash and MCP tools still prompt:

{ "permissions": { "defaultMode": "acceptEdits" } }

Sane when: the risky part of your workflow is a shell command or an external side effect (a deploy, an API call), not the edits themselves — you're fine letting the model iterate on code freely and just want the gate on the step that actually does something to the outside world. Not sane when: the edits themselves are the risk — a config file that ships credentials somewhere, a CI file that controls what runs next.

3. Auto-allow, but sandboxed

Blast radius: contained by wherever the sandbox's walls are, not by the rule list — this is the same bypassPermissions/--dangerously-skip-permissions switch as rung 6 below, but flipped on inside a disposable container with a scratch filesystem, no real credentials, and restricted network egress instead of on your actual machine:

docker run --rm -v "$PWD":/work -w /work --network=agent-egress-only \
  anthropic/claude-code-sandbox \
  claude -p --dangerously-skip-permissions "run the full test suite and fix failures"

Sane when: the task genuinely needs to run an unpredictable set of commands and you've decided the acceptable answer to "what if it does something bad" is "it ruins a container we throw away," not "nothing bad happens." Not sane when: the container can still reach something that matters — a mounted credential, a network path to production — because then you've bought the appearance of containment without the substance of it. This is the same flag as rung 6; the sandbox is doing all the safety work here, not the permission system, which is exactly why it deserves its own rung instead of being lumped in with the unsandboxed case.

4. Hooks with real logic

Blast radius: whatever your hook script actually implements — as narrow or as broad as you write it, which is both the appeal and the risk, since now it's code you own and have to test rather than a static list:

#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
if [[ "$cmd" == *"terraform apply"* ]]; then
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask"}}'
else
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}'
fi

Sane when: the safe/unsafe line depends on something a static pattern can't express — the content of a diff, the time of day, a call to an external policy service. Not sane as your only line of defense: the default hook timeout is 600 seconds, and a hook that hangs or crashes fails open — the call proceeds through the normal flow as if the hook never fired. Test the failure path deliberately (kill the hook mid-run) before trusting it; see the hooks guide for the full stdin/stdout contract across PreToolUse, PermissionRequest, and the others.

5. --permission-prompt-tool

Blast radius: as narrow as "a specific human said yes to this specific call" — the tightest option on this list for a decision that's genuinely a judgment call, at the cost of latency and needing somewhere durable to hold a pending request while you wait:

claude -p "deploy to prod" --permission-prompt-tool mcp__yourservice__permission_prompt

Sane when: the action is rare enough and consequential enough that a few minutes' (or hours') delay for a real answer is worth it — a production deploy, an irreversible delete. Not sane for routine, frequent calls, where the latency defeats the purpose of running unattended at all. See the undocumented contract for the exact payload shape and a from-scratch server; pendnt's own permission_prompt tool is one hosted implementation of that same contract if you'd rather not run the durable-wait server yourself.

6. --dangerously-skip-permissions, unsandboxed

Blast radius: everything, all at once, with no safety net beneath it. Bash, Edit, Write, every MCP tool — approved automatically, on the machine you actually care about, with no allow-rule check and no hook able to catch a mistake before it runs for real. See the dedicated guide for exactly what it turns off. Sane when: you've read that guide, understood it's all-or-nothing, and are running it somewhere the container/sandbox rung above would have covered anyway — at which point you're really just doing rung 3 without the container, which isn't actually a reason to skip the container. Reach for this last, and prefer rung 3's sandboxed version of the same flag if "unattended and permissive" is genuinely what the task needs.

The unattended case

These rungs compose rather than compete, and a real unattended job usually wants several at once: allow rules for the routine steps (rung 1), a hook for the handful of genuinely dangerous ones (rung 4), --permission-prompt-tool for the ones that need an actual human decision (rung 5), all of it inside a sandbox as the backstop for when the rules above have a bug (rung 3). That combination gets most of the unattended convenience people reach for rung 6 to get, without rung 6's actual failure mode: one bad tool call with nothing left to catch it. See running claude -p on cron for the rest of what an unattended job needs beyond permissions — locking, timeouts, and exit codes.