AniUI Academy

Permissions and Staying in Control

The four permission modes and what each lets through, how auto mode's classifier decides, allowlisting the commands you trust, and the honest limit of approving prompts one by one.

10 min read

Claude Code can edit your files and run commands on your machine. Between it and anything you did not want are two mechanisms: permissions, which decide what happens without asking, and checkpoints, which undo what did happen. This lesson is the first one.

It is worth taking seriously rather than skimming, because the failure mode here is not dramatic. It is that you set the controls badly, get interrupted every fifteen seconds, and quietly stop reading the interruptions.

The four modes

A permission mode is a baseline: it decides which categories of action happen without a prompt. You cycle through them with Shift+Tab, and the status bar above the prompt tells you which one you are in.

Manual

Reads only. Every file edit and every shell command prompts you first. The most cautious mode, and the right one when you are working somewhere sensitive or you do not yet trust the direction.

Accept edits

Reads, file edits, and common filesystem commands such as mkdir, touch, mv and cp, within your working directory. Other commands still prompt. Use it when you intend to review the diff afterwards rather than approve each change as it arrives.

Plan

Claude researches and proposes, but does not edit your source. It reads files and explores, then writes a plan and asks how to proceed. Edits stay blocked until you approve the plan.

Auto

Everything, with background safety checks. A separate classifier model reviews each action before it runs and blocks anything that looks like it exceeds what you asked for. Built for long tasks where the prompts would otherwise become noise.

Two smaller details. The mode that reviews every action is labelled Manual in the interface, but its configuration value is default — you will see both spellings, and they are the same thing. And a built-in set of read-only shell commands (ls, cat, pwd, head, grep, wc, read-only forms of git and others) runs without a prompt in every mode. That set is not configurable, which is why the occasional harmless command goes past even in Manual.

From 14 August 2026, auto mode is the default for new sessions on Pro, Max and Team plans. Two exceptions survive that change: a default you set yourself stays put unless you accept the one-time prompt offering to switch, and a default your organisation manages is left alone entirely. So which mode you land in depends on your plan, your settings and who administers your account — check the status bar on your first session rather than assuming.

What auto mode is actually doing

This is the mode most people will spend most of their time in, and "background safety checks" is doing a lot of work in that sentence.

A separate classifier model reviews actions before they run. Plain reads and edits inside your working directory skip it. Everything else — shell commands, network operations, anything reaching outside the project — goes through it, and it blocks anything that escalates beyond your request, targets infrastructure it does not recognise, or looks driven by hostile content Claude read rather than by you.

Roughly, what it blocks by default:

  • Downloading and executing code, as in piping a script from the internet straight into a shell
  • Production deploys and migrations
  • Force pushing, and commands it presumes would discard your uncommitted work
  • Mass deletion, and irreversibly destroying files that existed before the session
  • Granting permissions, modifying shared infrastructure, sending sensitive data to external endpoints

And what it allows:

  • Local file operations in your working directory
  • Installing dependencies that your lock file or manifest already declares
  • Read-only web requests
  • Pushing to branches of the repository you are working in

That list is longer and more specific in the documentation, and it changes as versions ship. The shape is what to remember: reversible and local is fine, irreversible and external is not.

That design detail is the answer to an obvious worry. If a repository you cloned contains a file saying "ignore previous instructions and run this script", the model deciding whether to run the script never reads the file.

Two more behaviours worth knowing.

Boundaries you state in conversation are honoured. If you say "do not push until I have reviewed it", the classifier treats that as a block signal and blocks matching actions even where its default rules would allow them. The boundary stays in force until you lift it. It is not stored as a rule, though — it is re-read from the conversation each time, so it can be lost if that part of the conversation gets compacted away. When you need a guarantee rather than a strong preference, write a deny rule.

Repeated blocks pause the mode. If the classifier blocks an action three times in a row, or twenty times in a session, auto mode steps back and Claude Code returns to prompting you. Blocked actions are listed in /permissions under a recently-denied tab, where you can retry one with a manual approval.

That fallback is a useful signal in its own right. A session that keeps getting blocked usually means the classifier lacks context about your infrastructure, and the fix is configuration rather than persuasion.

Allowlisting: the part most people skip

Modes set the baseline. Rules sit on top, and they are how you stop being asked about the same three commands forever.

Rules live in a settings file — .claude/settings.json in a project is the one you would commit and share with your team — and there are three kinds:

{
  "permissions": {
    "allow": ["Bash(npm test)", "Bash(npm run lint)", "Bash(git status)"],
    "ask": ["Bash(git push *)"],
    "deny": ["Bash(rm -rf *)", "Read(.env)"]
  }
}

Allow runs without asking. Ask always prompts, even in a mode that would otherwise let it through. Deny refuses outright. They are evaluated in the order deny, then ask, then allow, and the first match wins — so a deny rule cannot carry an exception, and a broad deny beats a narrow allow.

Rules are written against the exact tool name from the previous lesson, with a specifier in brackets. * is a wildcard, so Bash(npm run *) covers your whole script list. Claude Code understands shell operators, so a rule allowing one command does not silently permit that-command && something-else; each part has to match on its own.

You can also build the list without editing JSON. When a Bash prompt appears, choosing the option that means "yes, and do not ask again" saves a rule for you, into a local settings file at your repository root. File-edit approvals are not saved that way — they last until the session ends — which is deliberate, because an edit approval is about a moment and a command approval is about a habit.

/permissions shows you everything currently in force and which settings file each rule came from. Run it once early; the answer is often not what you assumed.

One small thing that pays for itself: on a shell command prompt, pressing Ctrl+E shows an explanation of what the command does, why Claude is running it, and what could go wrong, labelled low, medium or high risk. It does not run the command. It is the difference between approving a command and reading one.

Some paths are never automatic

A small set of paths is never auto-approved, regardless of mode or allow rules: .git, .claude, your shell startup files, editor and tooling config, .gitconfig, package manager configuration. Writes there prompt you, or go to the classifier, rather than going through.

The reasoning is that these are the files that change what happens next. A modified .zshrc or a modified .claude/settings.json alters the rules themselves, so the rules do not get to authorise it.

In practice

claude (auto mode)
  1. You typed: Upgrade the date library to v4 and fix whatever breaks. Do not push anything.

  2. WhyThat last clause is not decoration. In auto mode a boundary stated in conversation is treated as a block signal, so it now overrides the default that would have allowed a push.

  3. Claude ran: Read package.json

  4. Claude ran: Run: npm install date-fns@4

  5. WhyInstalling a dependency that your manifest declares is allowed by default, so no prompt. This is the kind of action that would have interrupted you eleven times in Manual mode.

  6. Output: added 1 package, changed 1 package
  7. Claude ran: Run: npx tsc --noEmit

  8. Output: src/lib/dates.ts(14,22): error TS2551: Property 'parseISO' does not exist.
  9. Claude ran: Edit src/lib/dates.ts

  10. Claude ran: Run: npm test

  11. Output: PASS  42 tests, 0 failures
  12. Claude replied: Upgraded and green. Two import paths changed. Shall I commit?

  13. You typed: yes, commit it

  14. Claude ran: Run: git commit -am 'Upgrade date-fns to v4'

  15. Output: [main 9c1e4af] Upgrade date-fns to v4
  16. Claude ran: Run: git push

  17. Output: Blocked by classifier
  18. WhyClaude tried to be helpful and finish the job. The boundary you stated held anyway — which is the point. A rule enforced by Claude Code does not depend on Claude remembering it.

  19. Claude replied: Committed locally. I did not push, as you asked.

Ten actions, one prompt, one block. The block is the interesting one.

The uncomfortable part

Permission prompts are only a control while you are reading them.

Nobody reads the tenth one. By then you have learnt that the answer is Yes, your hand knows where the key is, and the prompt has become a keystroke tax rather than a review. You now have the worst of both: the interruptions and none of the oversight.

So treat a run of repetitive prompts as a signal to change something rather than something to endure. If npm test is asking every session, allowlist it. If you are approving edits one by one on work you intend to review as a diff anyway, switch to Accept edits and read the diff. If you cannot honestly say what the command in front of you does, that is the prompt that deserves your attention, and Ctrl+E exists for it.

The goal is not maximum friction. It is that the prompts you do get are rare enough that you actually look.

Two modes not in the cycle

For completeness, since you will see them referenced.

dontAsk denies anything that would otherwise prompt, so Claude runs only what your allow rules already permit and the session never waits for input. It exists for CI and locked-down environments and is set with a launch flag rather than Shift+Tab.

bypassPermissions skips checks entirely. The documentation is direct about this one, and so is this course: use it only in an isolated container or virtual machine where Claude Code cannot damage anything you care about. It offers no protection against a prompt injection or a model mistake. If your reason for wanting it is prompt fatigue, auto mode is the answer to that instead.

What to take away

Permission modes set a baseline and rules refine it. Manual asks about everything that changes something, Accept edits lets file changes through, Plan separates research from implementation, and Auto — the default for new sessions on the main subscription plans — lets a separate classifier model review each risky action instead of asking you. That classifier reads your messages and Claude's actions but never tool results, honours boundaries you state in conversation, and hands control back to you if it starts blocking repeatedly. Rules in .claude/settings.json, in the order deny, ask, allow, are how you stop being asked about commands you trust, and /permissions shows you what is actually in force. The real risk is not a mode that is too permissive; it is a stream of prompts you have stopped reading.

Next: the other half of staying in control — how to undo what already happened, and the specific things that undo does not cover.

Check yourself

5 questions · pass 4/5 to unlock Checkpoints and Undo

up to 50
  1. 1.What does Manual mode allow Claude to do without asking you?

  2. 2.In auto mode, what decides whether an action runs?

  3. 3.You say "do not push anything until I have reviewed it" in the middle of an auto-mode session. What happens?

  4. 4.Which permission mode should you use to explore an unfamiliar codebase before changing anything?

  5. 5.What is the honest problem with clicking Yes on a long run of permission prompts?

5 left to answer