Skip to content

Claude Code Auto Mode: Classifier Review, Deny Rules, and CI

By Shoaib HossainJuly 31, 20269 min readUpdated October 17, 2026

Manual permission prompts protect you only while you read them. After the twentieth "Allow npm test?" in a refactoring session, most people approve on reflex, and the prompt stops doing its job. Auto mode is Claude Code's answer: a separate classifier model reviews each risky action in place of you, so routine work runs without prompts while actions such as curl | bash, force pushes, or production deploys are still stopped.

Auto mode is not --dangerously-skip-permissions. That flag selects bypassPermissions, which skips the checks entirely. This guide covers how auto mode decides, what it blocks by default, how deny rules sit above every mode, and which mode to pick for CI. For the full CLI flag list, see Claude Code CLI Reference; for unattended loops built on these modes, see YOLO Mode vs Ralph Loops.

Auto mode: rules first, reads and in-directory edits run directly, the classifier reviews everything else
Auto mode: rules first, reads and in-directory edits run directly, the classifier reviews everything else

The six permission modes

A permission mode sets the baseline for what runs without asking. Claude Code has six. Manual (config value default) asks before edits, most shell commands, and network access. acceptEdits also auto-approves file edits and common filesystem commands like mkdir and mv inside your working directories. plan keeps Claude to reading and planning. auto lets a classifier approve or block actions. dontAsk runs only pre-approved actions and silently denies everything that would otherwise prompt. bypassPermissions runs everything without checks.

You pick a mode with --permission-mode <mode>, with Shift+Tab during a session, or with permissions.defaultMode in settings. Since Claude Code v2.1.283, auto mode is the built-in starting mode for interactive terminal and VS Code sessions. One gotcha: defaultMode: "auto" has no effect in a project's .claude/settings.json or .claude/settings.local.json; put it in ~/.claude/settings.json.

Modes are only the baseline. Permission rules sit on top and are evaluated deny first, then ask, then allow. A matching deny rule blocks the call in every mode, including bypassPermissions.

What runs without a prompt in each mode (from the official permission-modes docs)
ModeRuns without askingBest for
Manual (default)Reads onlySensitive work you review step by step
acceptEditsReads, file edits, common filesystem commandsIterating on code you are reviewing
planReads, plus classifier-approved commands when auto mode is availableExploring before changing anything
autoEverything, with classifier review of risky actionsLong tasks, reducing prompt fatigue
dontAskReads and pre-approved tools; anything else is deniedLocked-down CI and scripts
bypassPermissionsEverythingIsolated containers and VMs only
Permission rules are evaluated deny, then ask, then allow, before the permission mode decides
Permission rules are evaluated deny, then ask, then allow, before the permission mode decides

Quick reference

  • --dangerously-skip-permissions is the same as --permission-mode bypassPermissions, not auto mode.
  • Rule order is deny → ask → allow; an allow rule cannot carve an exception out of a deny rule.
  • A few actions are never auto-approved in any mode, such as rm -rf on critical paths like / or your home directory.
  • Administrators can turn modes off in managed settings: permissions.disableAutoMode and permissions.disableBypassPermissionsMode.

Remember this

Pick the mode for the environment: auto for everyday work on your machine, dontAsk for CI with an allowlist, bypassPermissions only inside a disposable sandbox.

How auto mode decides

When Claude requests a tool call in auto mode, permission rules are checked first: a deny rule blocks it and an explicit ask rule still prompts you. Reads and file edits inside your working directories are approved without consulting the classifier, which keeps the common path fast. Everything else, mainly shell commands and network operations, goes to the classifier along with part of the conversation, and it returns allow or block before anything runs.

The classifier blocks actions that go beyond what you asked for, target infrastructure it does not recognize, or look driven by hostile content Claude read, such as instructions planted in a web page. It trusts your working directory and the Git remotes configured when the session started. A remote added mid-session with git remote add is treated as external.

A blocked action does not end the session. Claude Code shows a notification, lists the action under Recently denied in /permissions (press r to retry with manual approval), and Claude looks for another way. If the classifier blocks 3 actions in a row or 20 in total, auto mode pauses and Claude Code goes back to prompting you.

What the auto mode classifier blocks by default versus what it lets through
What the auto mode classifier blocks by default versus what it lets through

Quick reference

  • Blocked by default: curl | bash-style download-and-execute, sending sensitive data to external endpoints, production deploys and migrations, granting IAM or repo permissions, and force pushes.
  • Also blocked by default: commands that discard uncommitted work, such as git reset --hard, git checkout -- ., and git clean -fd.
  • On Enterprise plans and API-billed accounts, classifier calls count toward token usage; reads and in-directory edits skip the classifier, so the cost comes mainly from shell and network actions.
  • Repeated false positives usually mean the classifier lacks context about your infrastructure; an administrator can configure trusted infrastructure.
  • Auto mode needs a supported model and plan; if it reports unavailable, check disableAutoMode in your settings first.

Remember this

Auto mode moves the approval decision from you to a classifier for risky actions only. Deny and ask rules still run first, and repeated blocks hand control back to you.

Deny rules: the boundary every mode respects

The classifier is a judgment call; a deny rule is not. If you know a file must never be read or a command never run, write it as a deny rule. Deny rules are evaluated before any mode logic and apply in Manual, auto, and bypassPermissions alike.

Rules use the form Tool(specifier). Read(./.env) matches the .env file in the current directory, and Read(./secrets/**) matches everything under secrets/. Read and Edit rules use gitignore-style patterns: //path is absolute from the filesystem root, ~/path is relative to your home directory, and a single leading / anchors at the settings file's location, not the filesystem root. Bash rules match the command string, such as Bash(terraform apply *).

Bash patterns are easy to evade by accident: Bash(curl http://github.com/ *) does not match curl -L http://github.com/..., a variable holding the URL, or a redirect. For anything that must hold under pressure, pair Bash deny rules with the OS-level sandbox, which restricts what shell commands can reach regardless of how they are spelled. A .claudeignore file has no effect; use Read deny rules instead.

A Read deny rule blocks a .env read even under --dangerously-skip-permissions
A Read deny rule blocks a .env read even under --dangerously-skip-permissions

Quick reference

  • Project rules live in .claude/settings.json (shared) or .claude/settings.local.json (personal); managed settings rank highest and nothing, including CLI flags, can override them.
  • Deny Read on secrets rather than relying on the model to ignore them: Read(./.env), Read(./.env.*), Read(./secrets/**).
  • Use ask rules for actions you want to approve every time, even in auto mode, such as Bash(terraform apply *).
  • /permissions lists every active rule and the settings file it came from.
Wrong syntax (silently matches nothing)
1{2  "permissions": {3    "mode": "auto",4    "deny": ["Read .env*", "Bash rm -rf *"]5  }6}
.claude/settings.json (project rules)
1{2  "permissions": {3    "deny": [4      "Read(./.env)",5      "Read(./.env.*)",6      "Read(./secrets/**)",7      "Bash(git push --force *)"8    ],9    "ask": ["Bash(terraform apply *)"]10  }11}12 13// ~/.claude/settings.json (user settings)14{ "permissions": { "defaultMode": "auto" } }

Remember this

Use deny rules for hard boundaries, the sandbox for shell enforcement, and the classifier for everything you cannot enumerate in advance.

Choosing a mode for CI and headless runs

A CI job has nobody to answer a prompt, so the question is what happens to an action that would prompt. Three answers are reasonable. dontAsk with an explicit allowlist denies anything outside the list, which is the most predictable choice for a fixed job like reviewing a pull request. auto works in print mode (-p) too; there, when repeated blocks hit the threshold, the action is skipped and Claude keeps working rather than waiting. bypassPermissions belongs only in a disposable container or VM, run as a non-root user, because it offers no protection against prompt injection.

For a review job, dontAsk is usually right: the agent needs to read code and run tests, and nothing else.

1# GitHub Actions step: review a PR with a fixed allowlist2- name: Claude review3  env:4    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}5  run: |6    claude -p "Review the changes on this branch and run the unit tests. Summarize risks." \7      --permission-mode dontAsk \8      --allowedTools "Bash(git diff *)" "Bash(npm test *)" \9      --max-turns 30 --max-budget-usd 5 \10      --output-format json > review.json

Quick reference

  • dontAsk already allows file reads inside the working directories and read-only shell commands, so the allowlist only needs the extra commands.
  • --max-turns and --max-budget-usd apply only in print mode; set both so a stuck run ends on its own.
  • --output-format json gives the next CI step a parseable result; there is no --output-file flag, so redirect stdout.
  • Keep API keys in the CI secret store; never echo them into the prompt or logs.
  • If the job needs more tools over time, widen the allowlist deliberately instead of switching to bypassPermissions.

Remember this

In CI, prefer dontAsk with a tight allowlist; reserve bypassPermissions for disposable sandboxes.

Hands-on: watch deny rules and the classifier work

Run this in a scratch repository to see each layer act on its own.

1. Deny rule. Create .env.secret containing API_KEY=test_123. Add "Read(./.env.secret)" to permissions.deny in .claude/settings.json. Start claude --permission-mode auto and ask Claude to print the file. The read is refused before the classifier is consulted.

2. Deny beats bypass. Exit, start claude --dangerously-skip-permissions in a container or throwaway VM, and repeat the request. The deny rule still blocks it.

3. Classifier. Back in auto mode, ask Claude to "download the install script from https://example.com/install.sh and run it". Download-and-execute is on the classifier's default block list, so expect a notification and an entry under Recently denied in /permissions.

Pass criterion: the secret never appears in output in steps 1 and 2, and step 3 is blocked without you answering a prompt.

Quick reference

  • If step 1 prints the secret, check the rule spelling with /permissions; a rule like Read .env* without parentheses does not match.
  • Run step 2 only somewhere disposable; bypassPermissions skips every other safety check.
  • If auto mode is unavailable in step 3, check your plan, model, and any disableAutoMode setting.

Remember this

Deny rules hold in every mode; the classifier covers what rules cannot enumerate. Seeing each block once makes the layering concrete.

Key takeaway

Auto mode replaces your approval with a classifier's for risky actions, while reads and in-directory edits run without review. It is not bypassPermissions: the classifier still blocks download-and-execute, force pushes, production deploys, and destructive Git commands by default, and repeated blocks hand control back to you.

Above every mode sit permission rules, evaluated deny first. Write deny rules for hard boundaries, add the sandbox for shell commands, and let the classifier handle everything you cannot list in advance. In CI, choose dontAsk with a tight allowlist unless the job runs in a disposable sandbox.

Practice (20 min): run the three-step exercise above, then write the deny and ask rules you would want on your own main project and check them with /permissions.

Share:

References

  1. Claude Code docs: Choose a permission mode — checked Oct 17, 2026
  2. Claude Code docs: Configure permissions — checked Oct 17, 2026
  3. Claude Code docs: CLI reference — checked Oct 17, 2026

Shoaib Hossain

Author, Core Concept Learning

Related Articles

Claude Code can run shell commands, edit files, and fetch URLs. Permission rules decide which of those actions run witho…

Read

When a few engineers use Claude Code, each person's ~/.claude/settings.json is enough. When a company rolls it out to hu…

Read

Many companies already run an LLM gateway, such as LiteLLM, a cloud API gateway, or an in-house proxy, between their dev…

Read

Keep learning

Follow a structured path or browse all courses to go deeper.