# Control What Claude Code Can Do: Permissions

> Claude Code now starts in auto mode on Pro, Max and Team plans. Shift+Tab to switch, and write allow/deny rules that actually match the command.

- Canonical: https://guides-ai.pages.dev/guides/claude-code-permissions/
- Plate 03.07 · Topic: Claude Code commands (https://guides-ai.pages.dev/topics/commands/)
- Published: 02 Sept 2026 · Updated: 06 Sept 2026 · 4 min read
- Source site: guides-ai — https://guides-ai.pages.dev/

The old advice that "Claude Code asks before it edits files" is no longer true by default. On
**Pro, Max and Team plans, interactive terminal sessions start in auto mode**, where a
classifier reviews actions instead of you and Claude edits most files and runs most commands
without a prompt. On other plans, Manual mode is the starting point.

## 1. Check the mode you're in

The status bar names it: `⏸ manual mode on`, `⏵⏵ accept edits on`, `⏸ plan mode on`,
`⏵⏵ auto mode on`, `⏵⏵ bypass permissions on`.

## 2. Cycle with Shift+Tab

From auto the first press goes to `default`, then the cycle runs
`default` → `acceptEdits` → `plan` → back to `default`.

- **`default`** (labeled **Manual**) — prompts on first use of each tool.
- **`acceptEdits`** — accepts edits and common filesystem commands in your working directory.
- **`plan`** — explores but doesn't edit. See [plan mode](/guides/claude-code-plan-mode/).
- **`auto`** — auto-approves with background safety checks.
- **`bypassPermissions`** — skips prompts. Containers and VMs only.

Set the starting mode with `defaultMode` in a settings file, or `--permission-mode` at launch.

## 3. Write rules that match

Rules are `Tool` or `Tool(specifier)`. Memorize the wildcard trap: **put the `*` after the
subcommand.** `Bash(git log *)` allows only `git log`; `Bash(git *)` allows every git command,
`git push` included.

```json
{
  "permissions": {
    "allow": ["Bash(npm run *)", "Bash(git commit *)", "Read", "Edit"],
    "deny": ["Bash(rm *)", "Read(./.env)", "Read(./.env.*)"]
  }
}
```

What it does: pre-approves npm scripts, commits and file access; refuses every `rm` and any
read of your env files. `Bash(ls:*)` is another way to write `Bash(ls *)`.

Note the deny rule is `Bash(rm *)`, not `Bash(rm -rf *)`: a narrower one is sidestepped by any
other flag. Read and Edit rules use gitignore syntax, so `Read(.env)` matches at any depth.

## 4. Check what's actually loaded

```text
/permissions
```

What it does: lists every rule and the settings file it came from, and lets you add or remove
one mid-turn. Which file to use is covered in
[Claude Code settings.json](/guides/claude-code-settings-json/).

## Verify it worked

Ask Claude to run one command you denied. It should refuse without prompting. If it asks
instead, your rule didn't match — rules are enforced by Claude Code, not by the model, so no
amount of `CLAUDE.md` text changes what's allowed. Real [permissions](/glossary/#permissions)
beat instructions every time.

Next: [work across a whole repo safely](/guides/claude-code-whole-codebase-safely/).

Source: [Configure permissions](https://code.claude.com/docs/en/permissions).
