Claude Code Auto Mode: How to Configure It Like an Expert
Not Just Turn It On
Claude Code Auto Mode: How to Configure It Like an Expert
Not Just Turn It On

Auto mode isn’t “YOLO mode.” It’s a classifier you can teach here’s how to configure it so Claude stops asking about routine work without opening a door to disasters.
Most people meet Claude Code auto mode the same way: they get tired of approving every git push, every file write, every curl, so they flip auto mode on and hope for the best.
That works until the classifier blocks something routine (pushing to your own company repo) or you start wondering what it would let through.
Here’s the mental model that fixes both problems: **auto mode is not a blank check.
It’s a second gate.* Every tool call gets routed through a classifier that blocks anything irreversible, destructive, or aimed outside* your environment.
Your job isn’t to trust it blindly it’s to teach it what your environment actually is.
This guide is the configuration reference, turned into something you can actually act on.
TL;DR: Auto mode runs tool calls through a classifier that blocks risky or “external” actions. For most teams, the only field you need is
autoMode.environmenta plain-English description of your trusted repos, buckets, and domains. Always keep"$defaults"in any list you edit, and useclaude auto-mode config/critiqueto verify your rules.
[embed]The 100 Most Followed Tags on Medium And How I’d Actually Use Themmedium.com
How auto mode actually works
When auto mode is on, Claude Code doesn’t just run whatever it wants.
Two gates apply, in order:
- The permissions system first. Your explicit
denyandaskrules are evaluated before the classifier. Apermissions.denyrule blocks an action outright the classifier never even sees it. - The classifier second. Whatever survives gets routed through a classifier that blocks anything irreversible, destructive, or pointed outside your environment.
By default, the classifier trusts only your working directory and the current repo’s configured remotes.
Everything else pushing to your company’s GitHub org, writing to a team S3 bucket, hitting an internal
API is treated as potentially “external” and blocked until you say otherwise.
That default is exactly why people hit false positives.
The fix is configuration, not frustration.
Rule of thumb: if Claude keeps getting blocked doing something legitimate, the classifier is missing context so give it context.
Where the classifier reads its configuration
This part trips people up, so get it straight early.
The classifier reads from two places:
1. Your CLAUDE.md. The classifier reads the same CLAUDE.md Claude itself loads. So a behavioral line like never force push steers both Claude and the classifier at once. Project conventions belong here.
2. The autoMode settings block, read from these scopes:
Scope File Use for One developer ~/.claude/settings.json Personal trusted infrastructure One project, one developer .claude/settings.local.json Per-project trusted buckets or services Organization-wide Managed settings Trusted infra for all developers Per-invocation --settings flag or Agent SDK (inline JSON) Automation overrides
Two critical details most people miss:
- The classifier does not read
autoModefrom shared, checked-in.claude/settings.json. That's deliberate: a cloned repo can't inject its own allow rules into your machine. - Entries from each scope are combined (additive). A developer can extend
environment,allow,soft_deny, andhard_deny, but can't remove entries that managed settings provide. Becauseallowacts as an exception to soft blocks, a developer'sallowcan override an orgsoft_denyso this is additive, not a hard policy boundary.
Expert takeaway: if something must never run regardless of intent or classifier config, don’t use
soft_deny. Usepermissions.denyin managed settings it blocks before the classifier and can't be overridden.
The one field most teams actually need: autoMode.environment
For most organizations, autoMode.environment is the only thing you'll set.
It tells the classifier which repos, buckets, and domains are trusted — which is how it decides what “external” means.
Anything not listed is a potential exfiltration target.
Crucially, entries are prose, not regex or tool patterns. Write them the way you’d describe your infrastructure to a new engineer.
Keep the literal "$defaults" string to splice the built-in defaults in alongside yours:
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.example.com/acme-corp and all repos under it",
"Trusted cloud buckets: s3://acme-build-artifacts, gs://acme-ml-datasets",
"Trusted internal domains: *.corp.example.com, api.internal.example.com",
"Key internal services: Jenkins at ci.example.com, Artifactory at artifacts.example.com"
]
}
}
A thorough environment section covers:
- Organization your company name and what Claude Code is mainly used for.
- Source control every GitHub/GitLab/Bitbucket org developers push to.
- Cloud providers and trusted buckets bucket names/prefixes Claude can read and write.
- Trusted internal domains internal APIs, dashboards, services (
*.internal.example.com). - Key internal services CI, artifact registries, package indexes, incident tooling.
- Additional context regulated industry, multi-tenant infra, compliance constraints.
Here’s a fill-in-the-blanks template drop the lines that don’t apply:
{
"autoMode": {
"environment": [
"$defaults",
"Organization: {COMPANY_NAME}. Primary use: {PRIMARY_USE_CASE}",
"Source control: {SOURCE_CONTROL, e.g. GitHub org github.example.com/acme-corp}",
"Cloud provider(s): {CLOUD_PROVIDERS, e.g. AWS, GCP, Azure}",
"Trusted cloud buckets: {TRUSTED_BUCKETS}",
"Trusted internal domains: {TRUSTED_DOMAINS}",
"Key internal services: {SERVICES}",
"Additional context: {EXTRA, e.g. regulated industry, compliance requirements}"
]
}
}
A sane rollout (you don’t need everything on day one):
- Start with
$defaultsplus your source-control org and key internal services this kills the most common false positive (pushing to your own repos). - Add trusted domains and cloud buckets next.
- Fill the rest as real blocks come up.
The more specific your context, the better the classifier separates routine internal work from genuine exfiltration.
Overriding the block and allow rules (carefully)
Beyond environment, three fields let you replace the classifier's built-in rule lists:
autoMode.hard_denyunconditional security boundaries.autoMode.soft_denydestructive actions that explicit user intent can clear.autoMode.allowexceptions to soft block rules.
Inside the classifier, precedence runs in four tiers:
**hard_deny** blocks unconditionally intent andallowdon't apply.**soft_deny* blocks next intent andallowcan* override it.**allow** overrides matchingsoft_denyrules as exceptions.- Explicit user intent overrides remaining soft blocks if your message directly and specifically describes the exact action.
That last tier matters more than it looks.
General requests don’t count as intent:
“Clean up the repo” does not authorize a force-push. “Force-push this branch” does.
When to reach for each:
- Loosen → add to
allowwhen the classifier keeps flagging a routine pattern the defaults miss. - Tighten → add to
soft_denyfor destructive risks specific to your environment, or tohard_denyfor boundaries that must never be crossed.
A complete example that keeps every default and layers org-specific rules on top:
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.example.com/acme-corp and all repos under it"
],
"allow": [
"$defaults",
"Deploying to the staging namespace is allowed: staging is isolated and resets nightly",
"Writing to s3://acme-scratch/ is allowed: ephemeral bucket with a 7-day lifecycle"
],
"soft_deny": [
"$defaults",
"Never run database migrations outside the migrations CLI, even against dev databases",
"Never modify files under infra/terraform/prod/: prod changes go through review"
],
"hard_deny": [
"$defaults",
"Never send repository contents to third-party code-review APIs"
]
}
}
The mistake that quietly disables your safety net
This is the single most important warning in the whole feature:
If you set
environment,allow,soft_deny, orhard_denywithout"$defaults", you replace the entire default list for that section.
A soft_deny array without "$defaults" throws away every built-in soft block — including force push, curl | bash, and production deploys.
A hard_deny without "$defaults" discards the built-in data-exfiltration and auto-mode-bypass protections.
Each section is independent, so setting environment alone leaves the other three defaults intact.
Only omit "$defaults" when you genuinely intend to own the list and if you do, run claude auto-mode defaults, copy the built-ins in, and edit deliberately.
Inspect and validate your config (do this every time)
Three CLI subcommands keep you honest:
# Print the built-in environment/allow/soft_deny/hard_deny rules
claude auto-mode defaults
# Print what the classifier ACTUALLY uses (your settings + defaults), $defaults expanded
claude auto-mode config
# Get AI feedback on your custom allow/soft_deny/hard_deny rules
claude auto-mode critique
The expert habit:
- Save your settings.
- Run
claude auto-mode configto confirm the effective rules and that"$defaults"expanded where you expected. - If you wrote custom rules, run
claude auto-mode critiqueto catch entries that are ambiguous, redundant, or likely to cause false positives.
Need to rewrite a built-in rule rather than add alongside it? Save claude auto-mode defaults to a file, edit the lists, and paste the result in place of "$defaults".
When something gets blocked: the denial loop
Denials aren’t dead ends.
When auto mode blocks a call, it’s recorded in /permissions under Recently denied.
Press r on a denied action to mark it for retry on exit, Claude Code tells the model it may retry and resumes.
But repeated denials for the same destination are a signal, not noise: the classifier is missing context. Add that destination to autoMode.environment, then run claude auto-mode config to confirm it took effect.
For automation, you can react to denials programmatically with the PermissionDenied hook.
Many people probably already know this,
but for terminal users: press Shift + Tab and switch to Auto Mode.

An expert setup checklist
- Put behavioral rules (
never force push, etc.) inCLAUDE.mdso both Claude and the classifier follow them. - Set
autoMode.environmentwith"$defaults"+ your source-control org and key internal services first. - Add trusted domains and buckets as prose, not regex.
- Keep
"$defaults"in every list you touch. - Use
permissions.deny(managed settings) for true never-allowed actions notsoft_deny. - Run
claude auto-mode configafter every change; runcritiqueon custom rules. - Treat repeated denials as missing
environmentcontext.
Final thought
Auto mode rewards people who treat it as a system to configure, not a switch to flip.
Spend twenty minutes describing your real infrastructure in environment, keep the defaults intact, and verify with the CLI and you get the best of both worlds: Claude stops nagging you about routine work, while the genuinely dangerous and "external" actions still get stopped at the gate.
That’s the difference between using auto mode and running it like an expert.
Follow me on Medium Jerry PM for more iOS and developer writing.
I also build prompt packs. They are more structured, easier to learn from, and you can reuse the templates for your own projects.
source-code kits, and developer guides over on Gumroad including resources for structuring your own reusable prompt library.
Thank you for reading! , If this saved you from guessing at your tags, If you enjoyed it, please consider clapping and following for more updates! 👏
메타데이터
- post_id
- 063bcacf8ebf
- slug
- claude-code-auto-mode-how-to-configure-it-like-an-expert-063bcacf8ebf
- url
- https://medium.com/@21zerixpm/claude-code-auto-mode-how-to-configure-it-like-an-expert-063bcacf8ebf
- canonical_url
- https://medium.com/@21zerixpm/claude-code-auto-mode-how-to-configure-it-like-an-expert-063bcacf8ebf
- author_url
- https://medium.com/@21zerixpm
- status
- ok
- fetched_at
- 2026-07-12 01:24:19