All posts

Claude Code Auto Mode: Setup and Safety Guide

claude-codeauto-modepermissionssecurityindie-dev

Claude Code v2.1.304 shipped this week with a new /auto-mode-setup command, and developers on X picked it up along with a new warning about resuming old chats on Pro and Max plans. The command is small, but it points at a bigger change many people haven’t noticed: since v2.1.283, auto mode is the starting permission mode for interactive terminal and VS Code sessions. If you updated recently and stopped seeing permission prompts, this is why.

This guide covers what auto mode does, what it blocks, how to teach it about your setup, and where to put a human checkpoint back. Everything comes from Anthropic’s docs on permission modes and configuring auto mode, plus the Claude Code changelog.

What auto mode is

In Manual mode (the default value in settings), Claude Code stops and asks before most file edits, shell commands, and network calls. In auto mode a second model, the classifier, reviews those actions instead of you. It blocks anything that escalates beyond what you asked for, targets infrastructure it doesn’t recognize, or appears to be driven by hostile content Claude read along the way.

The docs are direct about the limits: auto mode reduces permission prompts but does not guarantee safety. It fits long tasks where you trust the general direction. It is not a substitute for reviewing sensitive operations.

Here is how it sits next to the other modes:

ModeRuns without askingGood for
default (Manual)Reads onlySensitive work, reviewing every action
acceptEditsReads, file edits, common filesystem commandsIterating on code you review
planReads, plus classifier-approved commands when auto mode is availableExploring before changing anything
autoEverything, with background safety checksLong tasks, fewer prompts
dontAskReads and pre-approved tools; anything else is deniedLocked-down CI and scripts
bypassPermissionsEverything (deny rules still apply)Isolated containers and VMs only

The older permissions deep dive on this blog explains allow and deny lists in general. Auto mode adds the classifier on top of them.

Turn it on, turn it off

You have four ways to control it:

  • During a session: press Shift+Tab. From auto, the first press goes to Manual, then acceptEdits, then plan. The status bar shows ⏵⏵ auto mode on while it’s active.
  • For one run: claude --permission-mode auto. This also works for headless runs: claude -p "Run the tests and fix failures" --permission-mode auto.
  • As your default: set permissions.defaultMode in ~/.claude/settings.json.
  • In VS Code: pick Auto from the mode indicator once. The extension’s claudeCode.initialPermissionMode setting doesn’t accept auto.

One trap from the docs: "defaultMode": "auto" in a project’s .claude/settings.json or .claude/settings.local.json is ignored. Those files live inside the repo, so a cloned project could otherwise switch your mode for you. Put it in your user settings instead.

{
  "permissions": {
    "defaultMode": "auto"
  }
}

To stay in Manual mode by default, set "defaultMode": "default" in the same file. Team admins can remove auto mode entirely with permissions.disableAutoMode set to "disable" in managed settings.

Auto mode needs a supported model. On the Anthropic API that means Claude Opus 4.6 or later, Sonnet 4.6 or later, Haiku 5.5, or a Fable model. Older models such as Sonnet 4.5 or Haiku 4.5 start the session in Manual mode instead.

How each action gets decided

Every tool call goes through a fixed order, and the first match wins:

  1. Your own allow, ask, and deny rules resolve first. A deny rule blocks before the classifier ever sees the call. A content-scoped ask rule like Bash(git push *) still forces a prompt.
  2. Reads and file edits inside your working directory are approved, except writes to protected paths and the first read outside your working directories, which asks you.
  3. Everything else goes to the classifier.
  4. If the classifier blocks, Claude gets a reason, usually the name of the rule it matched, such as [Data Exfiltration], and tries another approach.

When you enter auto mode, Claude Code drops allow rules that amount to “run anything”: Bash(*), wildcard interpreters like Bash(python*), package-manager run commands, and Agent rules. Narrow rules like Bash(npm test) keep working, and the dropped rules come back when you leave auto mode.

The classifier sees your messages, Claude’s tool calls, and your CLAUDE.md. It does not see tool results, so a malicious README or web page can’t talk to it directly. That also means a line in CLAUDE.md such as “never force push” steers both Claude and the classifier.

Subagents get the same treatment. The classifier checks the task before a subagent starts, reviews each of its actions, and reviews its final report before the main session reads it.

What it blocks by default

The full list is long. The ones you are most likely to hit in day-to-day app work:

  • Downloading and running code, like curl | bash
  • Force pushes, and git reset --hard, git checkout -- ., git clean -fd, or git stash drop, which can throw away uncommitted work
  • git commit --amend on a commit Claude didn’t create in this session
  • Production deploys and migrations
  • Printing a live credential or token into the transcript or a file
  • Sending sensitive data to an outside endpoint
  • Merging a pull request no human approved, or disabling CI checks
  • Changing where pushes go with git remote add or git remote set-url, unless you named the new remote
  • Running another agent with its safety checks turned off, such as --dangerously-skip-permissions

And what it allows by default:

  • Local file work in your working directory
  • Installing dependencies already declared in your lock file or manifest
  • Reading .env and sending those credentials to the API they belong to
  • Read-only HTTP requests
  • Pushing to any branch of the repo you’re in, including the default branch, and opening a matching pull request

That last item matters if main deploys your site or app. More on that below.

To read every rule word for word, run:

claude auto-mode defaults

Add --label 'Git Destructive' (or the start of any rule name) to print one rule.

Teach it your setup with /auto-mode-setup

Out of the box, the classifier trusts your working directory and the git remotes configured when the session started. Every other host, bucket, or service counts as external. That is why pushing to your own second repo or calling your own API can get blocked.

/auto-mode-setup fixes this by drafting autoMode.environment entries for you. Type it at the prompt:

/auto-mode-setup

It asks how you use the project, then offers two optional scans. It always reads:

  • The project’s CLAUDE.md, README.md, config files, and git remotes
  • Your existing autoMode and permissions.allow settings
  • Hosts, buckets, and command names from Claude’s commands in your recent sessions in this project, never your messages

The optional scans add the first word of each command in your shell history, and the remote hosts of repos under your home directory.

You accept or discard the draft as a whole. An accepted draft goes into ~/.claude/settings.json, and Claude Code then offers to remove allow rules that auto mode ignores anyway, like Bash(*). Check the result with:

claude auto-mode config

The docs list a Pro, Max, or Team plan and v2.1.228 or later as requirements, and the command doesn’t run in cloud sessions. The v2.1.304 changelog extends it to Bedrock, Vertex, Foundry, the Claude apps gateway, and sessions with telemetry turned off. Claude Code also offers the command on its own, in a dialog titled “Teach auto mode about your environment?”, once auto mode has blocked several actions and you have no environment entries.

Write environment entries by hand

You can also write the entries yourself. They are plain sentences, not regex. Describe your infrastructure the way you’d brief a new teammate. Keep "$defaults" in the list, or you replace the built-in entries:

{
  "autoMode": {
    "environment": [
      "$defaults",
      "Source control: github.com/your-username and all repos under it",
      "Trusted internal domains: api.yourapp.com, staging.yourapp.com",
      "Key internal services: App Store Connect API for TestFlight uploads"
    ]
  }
}

The same rule applies to the allow, soft_deny, and hard_deny lists. If you set one without "$defaults", you throw away every built-in rule in it. For soft_deny that includes the force-push, curl | bash, and production deploy rules. Like defaultMode: "auto", the autoMode block is read from user settings, managed settings, or the --settings flag, never from a project’s .claude/settings.json.

If you write custom rules, claude auto-mode critique reviews them and flags entries that are vague, redundant, or likely to cause false positives. claude auto-mode reset removes your autoMode section and goes back to defaults. You can edit all of this without touching JSON, too: run /permissions and open the Auto mode tab.

Put a human checkpoint back on git push

For solo developers this is the setting most worth adding. If merging or pushing to main triggers a deploy (common with Cloudflare, Vercel, or Netlify setups), auto mode will happily push there because it’s your repo. An ask rule brings the prompt back for those commands while everything else stays hands-off:

{
  "permissions": {
    "ask": [
      "Bash(git push *)",
      "Bash(gh pr create *)"
    ]
  }
}

The docs point out that these rules match how the command is written. git -C some/dir push doesn’t start with git push, so it slips past. For a checkpoint that reads the whole command, add a PreToolUse hook.

The three ways to draw a line, from the config docs:

You wantUseIn auto mode
A prompt before the actionpermissions.askAlways prompts for a matching command
The action to never runpermissions.denyBlocked before the classifier is asked
A limit for this session onlySay it, like “don’t push until I review”Blocked, but compaction can drop the message

That last row deserves a note. Boundaries you state in chat work, but the classifier re-reads them from the transcript each time. If compaction summarizes the message away, the boundary goes with it. Anything you care about long term belongs in a rule.

Approvals work the same way in reverse. “You can force-push” clears nothing. “Force-push the fix-login branch” names the action and its target, so it clears that one push.

When something gets denied

A denial shows up as a notice near the input, such as bash denied by auto mode · [Data Exfiltration] · /permissions. To deal with it:

  • Open /permissions and go to Recently denied. Press r on an action to let Claude retry it.
  • If Claude needs a destination for the whole task, add it to autoMode.environment.
  • If it’s a routine command you never want reviewed, add an allow rule.
  • If it’s a one-off you meant, say so specifically in your next message.

If the classifier blocks 3 times in a row or 20 times in a session, auto mode pauses and Claude Code goes back to prompting you. Approving the prompted action turns auto mode back on. These numbers can’t be changed.

Does auto mode cost extra?

Sometimes. On Enterprise plans and on Claude API, Bedrock, Agent Platform, and Foundry accounts, classifier calls count toward your token usage. Each check sends part of the transcript plus the pending action, and adds a round trip before the command runs. Reads and working-directory edits skip the classifier, so most of the overhead comes from shell commands and network calls. When the server does the review as part of the normal model request (check Auto mode server in /status), there are no separate classifier calls.

If you watch your limits closely, our guide to Claude Code usage limits covers where the rest of your tokens go. The same v2.1.304 release added a warning on Pro and Max when resuming an old conversation would use a noticeable share of your 5-hour limit.

A sensible setup for a solo app developer

For small iPhone apps like the ones in the ZenoLab app catalog, most of the work is SwiftUI edits, builds, and tests in one repo. That is the case auto mode handles well. A setup that follows the docs:

  1. Leave auto mode on for normal sessions.
  2. Run /auto-mode-setup once in each main project, then read the draft before accepting it.
  3. Add permissions.ask rules for git push and anything that uploads a build or deploys.
  4. Add permissions.deny rules for things that must never happen, such as reading a signing certificate folder.
  5. Put rules like “never force push” in CLAUDE.md so both Claude and the classifier see them.
  6. Switch to Manual or plan mode with Shift+Tab for a risky change, such as a StoreKit or data migration update in an app like Molip.

If you’re new to building this way, vibe coding iOS apps with Claude Code covers the rest of the workflow.

Sources

Frequently asked questions

What is auto mode in Claude Code?

Auto mode is a permission mode where a separate classifier model reviews Claude's actions instead of asking you. Reads and edits in your working directory run straight away, and shell commands, network calls, and other risky actions go to the classifier, which blocks anything that goes beyond your request, targets infrastructure it doesn't recognize, or looks driven by hostile content.

How do I turn on auto mode in Claude Code?

On Claude Code v2.1.283 or later, interactive terminal and VS Code sessions start in auto mode when nothing else sets a permission mode. You can also press Shift+Tab to cycle to it, start with claude --permission-mode auto, or set permissions.defaultMode to auto in ~/.claude/settings.json. The auto value has no effect in a project's .claude/settings.json.

What does /auto-mode-setup do?

It drafts autoMode.environment entries, and sometimes rule entries, from your project's CLAUDE.md, README, config files, git remotes, and the hosts and commands from your recent sessions. You accept or discard the whole draft, and an accepted draft is written to ~/.claude/settings.json.

Can auto mode push to main without asking?

Yes. By default auto mode allows pushes to any branch of the repository you're working in, including the default branch, and allows creating pull requests. If a push to main deploys your app, add permissions.ask rules such as Bash(git push *) so Claude Code prompts you first.

Is auto mode safe to use?

It reduces risk compared with skipping permissions, but Anthropic's docs say it does not guarantee safety. Use it for tasks where you trust the general direction, keep deny rules for things that must never run, and add ask rules for actions you always want to approve yourself.

Why does auto mode keep blocking the same action?

Repeated denials for one destination usually mean the classifier doesn't know it's yours. Add the host, repo, or bucket to autoMode.environment or run /auto-mode-setup. After 3 blocks in a row or 20 in a session, auto mode pauses and Claude Code goes back to asking you.

More from the studio.

The apps this workflow ships live on the ZenoLab apps page, with every release in the shiplog.