Kipt

Claude Code permissions: allow, ask and deny rules, modes and safe defaults

Claude Code permissions explained: allow, ask and deny rule syntax, permission modes, the /permissions dialog, managed policies and a safe default setup.

By the Kipt team · Updated 24 October 2026

Claude Code permissions are rules in your settings files that say which tools Claude can use without asking (allow), which always need confirmation (ask), and which are blocked (deny). Rules are checked in the order deny, then ask, then allow, and a permission mode such as Manual, acceptEdits, plan or auto sets the baseline for everything the rules don't cover.

This guide covers the rule syntax, the modes, the /permissions dialog, managed policies, and a safe starting configuration. All of it is based on the official permissions documentation and permission modes page.

How do Claude Code permissions work?

In Manual mode, Claude Code asks before it does anything that changes your machine. Since v2.1.283, interactive terminal and VS Code sessions start in auto mode instead (see the modes below), while claude -p starts in Manual. In Manual mode the defaults look like this:

Tool type Example Asks first? "Yes, and don't ask again"
Read-only File reads, Grep No, inside your working directories Not needed
Bash commands Shell execution Yes, except a built-in set of read-only commands Saved per repository and command
File modification Edit and write files Yes Until the session ends
Web fetch WebFetch Yes, except some preapproved documentation domains Saved per repository and domain
Web search WebSearch Yes Saved per repository

The built-in read-only commands include ls, cat, pwd, head, tail, grep, find, wc, diff and read-only forms of git. That set is not configurable, but you can add an ask or deny rule to make one of them prompt.

One point the docs stress: permission rules are enforced by Claude Code, not by the model. Telling Claude "never run git push" in CLAUDE.md shapes what it tries, but only a rule, a mode or a hook actually stops it.

What is the permission rule syntax?

A rule is either a tool name, Tool, or a tool with a specifier, Tool(specifier).

Rule Matches
Bash Every Bash command
Bash(npm run build) Exactly npm run build
Bash(npm run *) npm run build, npm run test --watch, and bare npm run
Read(./.env) Reading .env in the current directory
WebFetch(domain:example.com) Fetches to example.com
mcp__github__* Every tool from the github MCP server
Agent(Explore) The Explore subagent

Rules go in the permissions block of a settings file:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

How Bash wildcards behave:

  • Put the * after the subcommand. Bash(git log *) allows only git log commands; Bash(git *) allows every git command. Claude Code warns at startup about an allow rule with a * before the subcommand.
  • The space matters. Bash(ls *) matches ls -la but not lsof. Bash(ls*) matches both.
  • :* is an alternative trailing wildcard, so Bash(ls:*) equals Bash(ls *).
  • Compound commands are split. A rule like Bash(safe-cmd *) does not approve safe-cmd && other-cmd. Each part must match on its own, and a deny rule applies if any part matches.
  • Some wrappers are stripped, such as timeout, time, nice and nohup, so Bash(npm test *) also matches timeout 30 npm test.

A Bash rule matches the text Claude writes, so it is not a hard security boundary. Bash(git push *) in deny stops git push origin main but not git -C . push origin main, and Bash(curl *) doesn't stop /usr/bin/curl. For enforcement that doesn't depend on command text, use the sandbox or a PreToolUse hook.

How do Read, Edit, WebFetch and MCP rules work?

Read and Edit rules use gitignore-style patterns. The leading characters decide where a path anchors:

Pattern Meaning Example
//path Absolute path from the filesystem root Read(//Users/alice/secrets/**)
~/path From your home directory Read(~/Documents/*.pdf)
/path Relative to the settings source (the project, in project settings) Edit(/src/**/*.ts)
path or ./path Relative to the current directory Read(*.env)

The common trap: /Users/alice/file is not an absolute path. A single leading slash anchors at the settings source, so in user settings Read(/secrets/**) means ~/.claude/secrets/**. Use // for real absolute paths.

Other details worth knowing:

  • Edit rules cover every built-in tool that edits files. Rules written as Write(path) or Glob(path) are accepted but never match, so use Edit(...) and Read(...).
  • A Read deny also blocks Edit and Write on that path.
  • Read and Edit denies are best-effort for shell commands. They cover recognized commands such as cat, head and sed, but not grep -r pattern . or a script that opens files itself. The docs recommend the sandbox for OS-level blocking.
  • WebFetch rules match hostnames. WebFetch(domain:*.example.com) matches subdomains but not example.com itself, so add both if you need both.
  • MCP rules use the tool name. mcp__puppeteer__* covers a whole server, and mcp__puppeteer__puppeteer_navigate covers one tool.

What are the Claude Code permission modes?

The mode sets what runs without a prompt before any rule is considered:

Mode Runs without asking Suited to
default (shown as Manual) Reads only Sensitive work, unfamiliar code
acceptEdits Reads, file edits and common filesystem commands like mkdir and mv Iterating on code you review
plan Reads; edits wait until you approve a plan Exploring before changing anything
auto Everything, with a background classifier checking actions Long tasks, fewer prompts
dontAsk Reads and pre-approved tools; anything else is denied Locked-down CI and scripts
bypassPermissions Everything Isolated containers and VMs only

Ways to pick a mode:

  • During a session, press Shift+Tab to cycle modes. The status bar shows the current one.
  • For one session, start with claude --permission-mode plan (or any mode name).
  • As a default, set permissions.defaultMode in a settings file. auto and bypassPermissions don't take effect from project or local settings, so put those in ~/.claude/settings.json.

Since v2.1.283, interactive terminal and VS Code sessions start in auto mode when no flag or setting picks another mode, while claude -p runs start in Manual. Auto mode needs a supported model, and administrators can turn it off. A few things are never auto-approved in any mode, including tools matched by an explicit ask rule and recognized rm commands aimed at critical paths. Writes to protected paths such as .git, .vscode and the .claude folder are not pre-approved by allow rules, and they prompt in Manual and acceptEdits modes. For plan mode specifically, see the Claude Code plan mode guide.

How do you manage rules with /permissions?

Run /permissions to see every rule and the settings file it comes from. You can add or remove rules there, even while Claude is working; the change applies from Claude's next tool call.

When you answer a prompt with "Yes, and don't ask again" for a Bash command or a fetch domain, Claude Code saves an allow rule to .claude/settings.local.json at the repository root. That rule then applies in every session in the repository, including subdirectories and worktrees. Approving a compound command like git status && npm test saves separate rules for the parts that needed approval.

Two more controls are handy:

  • Comments on prompts. On most prompts, move to Yes or No and press Tab to attach a note. A comment on No tells Claude why you refused, and it keeps working.
  • Extra directories. By default Claude can access only the folder where you started it. Add more with --add-dir, /add-dir, or additionalDirectories in settings.

How do managed policies and precedence work?

Permission rules follow normal settings precedence, with one strong guarantee: if a tool is denied at any level, no other level can allow it. A user-level deny beats a project allow, and a managed deny can't be overridden by --allowedTools.

For organizations, administrators deploy managed settings that users can't override. The keys that matter for permissions:

  • permissions.deny in managed settings blocks a tool on every machine.
  • allowManagedPermissionRulesOnly makes managed settings the only source of permission rules.
  • permissions.disableBypassPermissionsMode set to "disable" removes bypass mode and makes Claude Code reject --dangerously-skip-permissions. It works from any scope, so you can set it for yourself too.
  • permissions.disableAutoMode set to "disable" removes auto mode.

Project files have a safety step of their own. permissions.allow rules and additionalDirectories in a committed .claude/settings.json apply only after you accept the workspace trust dialog for that folder, and the dialog lists what they would grant. Deny and ask rules apply immediately because they only restrict.

What is a safe default permission setup?

A reasonable starting point for a project, adapted from the official example settings files:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git diff *)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Guidelines that follow from the docs:

  1. Allow the commands you run all day, like your test and lint scripts, with narrow patterns. Prefer Bash(npm run *) over Bash(npm *).
  2. Put irreversible actions in ask, such as pushes and deploys.
  3. Deny secrets by path, then add the sandbox so shell commands can't read them either.
  4. Don't allow environment runners broadly. Bash(npx *) or Bash(docker exec *) approves whatever follows. Write Bash(devbox run npm test) style rules instead.
  5. Use bypass mode only inside a container or VM, and run it as a non-root user.
  6. Reach for a hook when you need logic, such as "allow all Bash except these commands." A hook that exits with code 2 blocks the call even when an allow rule matches.

Keep your reusable prompts with your rules

Permission rules make a project safer to hand to an agent; good prompts and skills make it more useful. Kipt stores your prompts and Agent Skills as Markdown in a private GitHub repo you own, and installs every skill into Claude Code or Codex with one npx skills add command, so the same workflows follow you to each project.

Questions

In what order does Claude Code check permission rules?

Deny first, then ask, then allow. The first match in that order decides, and a more specific rule does not change the order. So a broad deny rule like Bash(aws *) blocks a command even if a narrower allow rule like Bash(aws s3 ls) also matches.

Where does Claude Code save 'Yes, and don't ask again'?

For Bash commands and web fetch domains, Claude Code saves an allow rule to .claude/settings.local.json at the root of the git repository, so it applies to future sessions anywhere in that repository. File edit approvals are not saved to a file; they last until the session ends.

How do I stop Claude Code from reading my .env file?

Add Read deny rules such as Read(./.env) and Read(./.env.*) to permissions.deny in your settings. These rules cover Claude's file tools and recognized commands like cat, but not a command such as grep -r run over the folder. For an OS-level block on every shell command, turn on the sandbox as well.

How do I skip all permission prompts in Claude Code?

Start with claude --dangerously-skip-permissions, which is the same as --permission-mode bypassPermissions. The docs say to use it only in isolated environments such as containers or VMs. Deny rules and explicit ask rules still apply even in this mode.

What is the difference between auto mode and bypassPermissions?

Auto mode removes routine prompts but has a separate classifier model review actions before they run, blocking ones that go beyond your request. bypassPermissions skips prompts with no classifier review. Both still respect deny rules.

Why does Claude Code still ask after I allowed a command?

An ask rule from any settings file outranks an allow rule, so check /permissions for a matching ask rule. Writes to protected paths such as .git and .claude are not pre-approved by allow rules and prompt in Manual and acceptEdits modes. In a project's shared settings, allow rules only apply after you accept the workspace trust dialog.

More in Claude Code

All guides

Keep your prompts and skills in one place, in your own GitHub. Install every skill with one command.

Get started

Kipt is an independent product, not affiliated with or endorsed by Anthropic, OpenAI, Cursor or GitHub. Claude, ChatGPT, Codex, Cursor and GitHub are trademarks of their owners.