A free tool from Angelia · Updated 30 October 2026

# 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

Permission mode for new sessions

`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.

- Edit files in the project folder `Edit(./**)`
- Run npm scripts and tests `Bash(npm run *)` `Bash(npm test *)`
- Stage and commit with git `Bash(git add *)` `Bash(git commit *)`
- Search the web `WebSearch`
- Fetch any web page `WebFetch`

Other commands to allow

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

Sites it may fetch

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

MCP servers it may use

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

Other folders it may work in

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

- Push with git `Bash(git push *)`
- Publish a package `Bash(npm publish *)`
- Delete files with rm `Bash(rm *)`

Other commands to ask about

Never touch

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

- .env files, at any depth `.env` `.env.*`
- Folders named secrets, at any depth `secrets/**`
- Key and certificate files `*.pem` `*.key`
- SSH keys `~/.ssh/**`
- Cloud logins `~/.aws/**` `~/.config/gcloud/**` `~/.kube/**`
- Token files `~/.netrc` `~/.npmrc` `~/.git-credentials` `~/.config/gh/**`
- Shell history `~/.zsh_history` `~/.bash_history`
- Claude Code's transcripts of all your sessions `~/.claude/projects/**` `~/.claude/history.jsonl`
- sudo `Bash(sudo *)`
- Force push `Bash(git push --force *)` `Bash(git push -f *)`
- curl and wget `Bash(curl *)` `Bash(wget *)`
- Every web fetch `WebFetch`
- Every MCP server `mcp__*`

Other files and folders

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/**`).

Other commands to block

Locks

- Nobody can start this project in bypass mode `disableBypassPermissionsMode`
- File tools never read outside the working folders `blockReadsOutsideWorkingDirectories` (Claude Code 2.1.257 or later)

## 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:

- `default`: ask before edits and commands.
- `acceptEdits`: edit files and run `mkdir`, `mv` and the like in the project without asking; still ask before other commands.
- `plan`: read and plan, no edits.
- `dontAsk`: never ask; refuse anything that would need your yes.

`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

- **Commands** match the command text Claude Code is about to run. Claude Code splits `&&`, `;` and pipes, and every part must match on its own. A trailing ` *` also matches the bare command: `Bash(npm test *)` covers `npm test`.
- **Paths** follow `.gitignore` patterns. A bare file name like `.env` matches at any depth under the project folder. `~/.ssh/**` is in your home folder. `/src/**` is `src` in the project, not on the disk root; write `//` for that.

## 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](https://code.claude.com/docs/en/sandboxing). It applies the same limits to every command at the operating system level.

## With Angelia

[Angelia](https://useangelia.com/) 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`.

- Every profile is denied, for reading and editing: your credential folders and files (`~/.ssh`, `~/.aws`, `~/.gnupg`, `~/.config/gh`, `~/.netrc`, `~/.npmrc`, shell history and more); Angelia's own secrets; each CLI's transcripts; the other profiles' folders. A credential folder stays open only to a profile whose `add_dirs` names it.
- A skill or MCP server the profile may not use is denied too. A denied skill is also taken out of the profile's skills folder, because a deny rule does not stop a skill typed as `/name`. Angelia removes only the links it made there; a denied skill you put there by hand stops compile until you move it.
- Angelia changes only the entries it wrote. Your own rules in the same file stay.
- Angelia starts no agent for a profile that was never compiled, or whose compiled deny rules were removed since.
- The same limit applies: the rules hold the file tools, not every program. `sandbox: true` on a profile turns on Claude Code's sandbox for it.

## Sources

- [Configure permissions](https://code.claude.com/docs/en/permissions), Claude Code docs: rule syntax, order, path patterns, limits.
- [Claude Code settings](https://code.claude.com/docs/en/settings): where the files live and how they combine.
- [Settings reference, permission settings](https://code.claude.com/docs/en/settings-reference#permission-settings): every key under `permissions`.

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

## More tools

- [Telegram bot token and chat id checker](https://useangelia.com/tools/telegram-bot-check/)
- [Docs](https://useangelia.com/docs/)
- [Guides](https://useangelia.com/guides/)

## 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](https://useangelia.com/) · [Security model](https://useangelia.com/docs/security/) · [GitHub](https://github.com/korengast/angelia)

Angelia · open source, MIT [Docs](https://useangelia.com/docs/) · [info@useangelia.com](mailto:info@useangelia.com) · [GitHub](https://github.com/korengast/angelia)
