Claude Code bypass permissions: what still stops it

Running claude --dangerously-skip-permissions removes the prompts. It does not remove deny rules or hooks. This guide lists what the mode skips, what still applies, a short hook that denies a command, and where that hook runs out.

Written by Kyle, who made the free send gate mentioned at the end and also sells a paid kit built around it. Independent project, not affiliated with Anthropic. Docs claims checked against code.claude.com on 2026-10-26.

What bypass mode skips

--dangerously-skip-permissions is equivalent to --permission-mode bypassPermissions. Anthropic's permission modes page says the mode disables permission prompts and safety checks so tool calls run immediately, including writes to protected paths such as .git and .claude (the docs note a few exceptions inside .claude). Allow rules have no effect in it. The docs warn to use it only in isolated environments such as containers or VMs where Claude Code cannot damage your host.

That covers file edits, shell commands and MCP tool calls. If an MCP tool can send an email or move money, bypass mode will not stop it and will not ask you first.

What still applies in bypass mode

A deny rule such as Bash(git push *) matches by command pattern, and the permissions docs list command variants that such a pattern does not match, for example git -C . push origin main. A hook can run your own logic, such as "deny unless a human approved this one".

A minimal deny hook

A PreToolUse hook gets JSON on stdin with tool_name and tool_input. Per the hooks reference, exiting with code 2 blocks the tool call and your stderr becomes the message Claude sees. This one denies pushes and PR merges:

#!/bin/bash
# ~/.claude/hooks/deny-push.sh   (chmod +x)
input=$(cat)
if echo "$input" | grep -qE 'git push|gh pr merge'; then
  echo "Blocked: ask the owner to run this themselves." >&2
  exit 2
fi
exit 0
// in settings.json
{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash",
        "hooks": [ { "type": "command", "command": "/Users/you/.claude/hooks/deny-push.sh" } ] }
    ]
  }
}

Use the full path to the script. This is a blunt text match on the whole payload: it will also block a command that merely mentions those words, and a command that builds the string some other way gets past it. Test it by asking Claude to push, and run /hooks to confirm the hook is registered.

One docs detail worth knowing: a hook that exits 2 stops the call before permission rules are evaluated, so the block holds even when an allow rule would otherwise let it through. The same page suggests allowing all of Bash and registering a hook that rejects the few commands you want blocked.

The honest limits

Related guides

The free send gate

If you want this already built for outward actions, the claude-code-send-gate repo (MIT) is a PreToolUse hook that only ever uses deny. It gates MCP tools with send or pay words in the name, shell commands that POST to mail, chat and payment hosts, and browser scripts that click Send or Pay. You approve each action with a code typed in your own terminal, and an away-mode flag denies everything. Its source says it is pattern matching, not a sandbox, and it has the same limit on coordinate clicks described above. Tested on macOS only. I also sell a USD 19 kit around it, The Operator Kit for Claude Code, on the homepage. The gate works without it.

Source on GitHub The kit and store