Claude Code Auto Mode: Classifier Review, Deny Rules, and CI
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.
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.
| Mode | Runs without asking | Best for |
|---|---|---|
Manual (default) | Reads only | Sensitive work you review step by step |
| acceptEdits | Reads, file edits, common filesystem commands | Iterating on code you are reviewing |
| plan | Reads, plus classifier-approved commands when auto mode is available | Exploring before changing anything |
| auto | Everything, with classifier review of risky actions | Long tasks, reducing prompt fatigue |
| dontAsk | Reads and pre-approved tools; anything else is denied | Locked-down CI and scripts |
| bypassPermissions | Everything | Isolated containers and VMs only |
Quick reference
--dangerously-skip-permissionsis 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 -rfon critical paths like/or your home directory. - Administrators can turn modes off in managed settings:
permissions.disableAutoModeandpermissions.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.
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 -- ., andgit 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
disableAutoModein 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.
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
Readon secrets rather than relying on the model to ignore them:Read(./.env),Read(./.env.*),Read(./secrets/**). - Use
askrules for actions you want to approve every time, even in auto mode, such asBash(terraform apply *). /permissionslists every active rule and the settings file it came from.
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.jsonQuick reference
- dontAsk already allows file reads inside the working directories and read-only shell commands, so the allowlist only needs the extra commands.
--max-turnsand--max-budget-usdapply only in print mode; set both so a stuck run ends on its own.--output-format jsongives the next CI step a parseable result; there is no--output-fileflag, 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 likeRead .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
disableAutoModesetting.
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.
References
- Claude Code docs: Choose a permission mode — checked Oct 17, 2026
- Claude Code docs: Configure permissions — checked Oct 17, 2026
- Claude Code docs: CLI reference — checked Oct 17, 2026
Shoaib Hossain
Author, Core Concept LearningRelated Articles
Explore this topic