Angelia

A free tool from Angelia · Updated

Claude Code permissions: settings.json allow, ask, deny

Claude Code reads its permission rules from .claude/settings.json. Tick what the agent may do without asking, what it must ask about, and what it must never touch. The page writes the file for you. It runs in your browser and sends nothing.

Each choice shows the rules it adds. Type one item per line in the text boxes.

Start mode

auto and bypassPermissions do not take effect from a project's settings, so they are not here. Set them in ~/.claude/settings.json if you need them.

Allow without asking

Reading files inside the project needs no rule. Claude Code does it without asking.

A command becomes Bash(command). A * matches any text, so put it after the subcommand: git log *, not git *.

A domain becomes WebFetch(domain:docs.python.org). *.github.com covers the subdomains, not github.com itself.

The server's name as you configured it. github becomes mcp__github__*, every tool of that server.

These go to additionalDirectories. Claude Code then treats them like the project folder. Like allow rules, they take effect only after you accept the trust dialog for the project.

Always ask first
Never touch

Each file rule is written twice, as Read and Edit, so no file tool opens or changes the path.

Patterns as in .gitignore. ~/ is your home folder, // the disk root, one / the project folder. A line that starts with ! opens a file again: !.env.example after the .env files above. It cannot open a file inside a folder blocked as a whole (secrets/**).

Locks

Your settings file

Save it as .claude/settings.json in the project. If the file exists, add the permissions block to it. Claude Code reloads the file when it changes. The start mode applies to new sessions.

5 allow, 2 ask and 33 deny rules.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(npm test *)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "WebSearch"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm publish *)"
    ],
    "deny": [
      "Read(.env)",
      "Edit(.env)",
      "Read(.env.*)",
      "Edit(.env.*)",
      "Read(secrets/**)",
      "Edit(secrets/**)",
      "Read(*.pem)",
      "Edit(*.pem)",
      "Read(*.key)",
      "Edit(*.key)",
      "Read(~/.ssh/**)",
      "Edit(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Edit(~/.aws/**)",
      "Read(~/.config/gcloud/**)",
      "Edit(~/.config/gcloud/**)",
      "Read(~/.kube/**)",
      "Edit(~/.kube/**)",
      "Read(~/.netrc)",
      "Edit(~/.netrc)",
      "Read(~/.npmrc)",
      "Edit(~/.npmrc)",
      "Read(~/.git-credentials)",
      "Edit(~/.git-credentials)",
      "Read(~/.config/gh/**)",
      "Edit(~/.config/gh/**)",
      "Read(~/.zsh_history)",
      "Edit(~/.zsh_history)",
      "Read(~/.bash_history)",
      "Edit(~/.bash_history)",
      "Bash(sudo *)",
      "Bash(git push --force *)",
      "Bash(git push -f *)"
    ]
  }
}

allow, ask, deny and defaultMode

The permissions block in .claude/settings.json holds three lists of rules and a start mode. A rule is a tool name, or a tool name with a pattern in brackets: Bash(npm run test *), Read(./.env), WebFetch(domain:docs.python.org). Deny wins over ask, and ask wins over allow.

allow

Claude Code uses these without asking. Bash(npm run test *) runs npm run test with any arguments. Bash(npm run test:*) means the same. In a project file, allow rules take effect only after you accept the trust dialog for the folder.

ask

Claude Code asks you each time, even when an allow rule matches too. Use it for commands that are fine sometimes but leave your machine, such as Bash(git push *) or Bash(npm publish *).

deny

Claude Code never does these, and no allow or ask rule opens them again. Read(./.env) blocks the .env file in the project folder; Read(.env) blocks every .env at or under the project folder. A bare tool name such as WebFetch removes the tool.

defaultMode

The permission mode a new session starts in. A project's settings can set:

bypassPermissions skips every prompt, except the few actions no mode auto-approves. auto and bypassPermissions do not take effect from a project's settings or settings.local.json: set them in ~/.claude/settings.json, or start Claude Code with --permission-mode. "disableBypassPermissionsMode": "disable" stops anyone from starting the project in bypass mode.

A full settings.json example

A project where Claude Code edits files and runs the tests on its own, asks before it pushes or publishes, and never touches secrets:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(npm run test *)",
      "Bash(npm run lint)",
      "Bash(git diff *)",
      "Bash(git commit *)",
      "WebFetch(domain:docs.python.org)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm publish *)"
    ],
    "deny": [
      "Read(./.env)",
      "Edit(./.env)",
      "Read(secrets/**)",
      "Edit(secrets/**)",
      "Read(~/.ssh/**)",
      "Edit(~/.ssh/**)",
      "Bash(sudo *)"
    ],
    "disableBypassPermissionsMode": "disable"
  }
}

How the rules work

What these rules do not stop

The rules bind Claude Code's own tools and the shell commands Claude Code recognizes, such as cat and sed. They do not bind a program that opens files by itself. A Python script can still read a denied .env. A deny rule for curl * does not stop /usr/bin/curl or sh -c 'curl …', and one for git push --force * does not stop git push origin main --force. For a hard limit on files and network, turn on Claude Code's sandbox. It applies the same limits to every command at the operating system level.

With Angelia

Angelia runs Claude Code for each WhatsApp or Telegram chat, in that chat's own profile folder. It writes the deny rules for you: angelia compile <profile> --write puts them into the profile's .claude/settings.json.

Sources

Checked against the docs on 30 October 2026. Claude Code changes often. If a rule behaves differently, the docs win.

Try Angelia

curl -fsSL https://useangelia.com/install | sh

It checks the release's signature, then a wizard pairs your first chat. Free and open source (MIT). How it works · Security model · GitHub