Claude Code Auto Mode Config: hard_deny, soft_deny, and allow

Coffee Summary

  • FACT (docs): Auto mode routes tool calls through a classifier that blocks irreversible, destructive, or out-of-environment actions; permissions.deny / permissions.ask still run before the classifier.
  • FACT: Org trust is configured mainly via autoMode.environment (repos, buckets, domains, services) — destinations not listed are treated as potential exfiltration targets.
  • FACT: Override lists are prose rules: autoMode.hard_deny (unconditional), autoMode.soft_deny (user intent / allow can clear), autoMode.allow (exceptions to soft blocks).
  • FACT: Include "$defaults" in each array you customize or you replace that section’s built-in rules entirely.
  • FACT: Inspect with claude auto-mode defaults, config, critique, and reset (version notes apply).

What happened

Anthropic’s Claude Code docs page “Configure auto mode” is the reference for telling the classifier which repos, buckets, and domains your organization trusts — and how to override defaults with hard_deny, soft_deny, and allow.

Auto mode is available across major providers (Anthropic API, AWS/Bedrock, Google Agent Platform, Microsoft Foundry, Claude apps gateway), subject to model and Team/Enterprise controls. On some providers, v2.1.158–v2.1.206 required CLAUDE_CODE_ENABLE_AUTO_MODE=1; v2.1.207 removed that requirement.

Why it matters

Default trust is narrow: the working directory and the current repo’s configured remotes. Pushes to a company org remote or writes to a team bucket stay blocked until you extend autoMode.environment.

For platform and security teams, hard_deny / soft_deny / allow encode irreversible boundaries without turning auto mode off. Omitting "$defaults" discards that section’s built-in soft/hard protections — the sharpest misconfig risk.

What changed (ops model)

Precedence inside the classifier (FACT)

  1. 1. hard_deny — blocks unconditionally; user intent and allow do not override.
  2. 2. soft_deny — blocks next; explicit user intent and allow can override.
  3. 3. allow — exceptions to matching soft_deny rules.
  4. 4. Explicit user intent — only when the user’s message directly names the exact action. Vague asks (“clean up the repo”) do not authorize force-push.

Before the classifier: permissions.deny never runs; permissions.ask always prompts for matching rules (e.g., Bash(git push ), Bash(gh pr create )).

Where autoMode is read (FACT)

Scope File / channel Use
One developer ~/.claude/settings.json Personal trusted infra
Organization-wide Managed settings Distributed trust + deny
Per invocation --settings / Agent SDK JSON Automation overrides

FACT: The classifier does not read autoMode from project .claude/settings.json or .claude/settings.local.json (repo-inject risk). Move any local block to user settings. Developers can add entries but cannot remove managed ones; a developer allow can still override an org soft_deny (additive merge).

Minimal org pattern



{

  "autoMode": {

    "environment": [

      "$defaults",

      "Source control: github.example.com/acme-corp and all repos under it",

      "Trusted cloud buckets: s3://acme-build-artifacts",

      "Trusted internal domains: *.corp.example.com"

    ],

    "allow": ["$defaults", "Deploying to staging is allowed: isolated, resets nightly"],

    "soft_deny": ["$defaults", "Never run DB migrations outside the migrations CLI"],

    "hard_deny": ["$defaults", "Never send repository contents to third-party code-review APIs"]

  }

}

Entries are prose, not regex. Optional: autoMode.classifyAllShell: true (v2.1.193+) sends every Bash/PowerShell command through the classifier even when narrow allow rules exist.

CLI inspection checklist (FACT)

  • claude auto-mode defaults / config / critique / reset (reset needs v2.1.212+; managed settings remain).
  • /auto-mode-setup drafts environment entries (Pro/Max/Team; version gates).
  • /permissions → Auto mode tab edits rules without opening files (v2.1.246+).

Who should care

  • Platform / DevEx rolling auto mode fleet-wide.
  • Security / compliance needing non-overridable exfiltration boundaries (hard_deny + managed permissions.deny).
  • Team leads hitting false positives on internal pushes, buckets, and registries.
  • Automation owners using Agent SDK / --settings who must keep "$defaults".

Limitations

  • Documented keys only — do not invent undocumented flags.
  • Version gates matter (classifyAllShell, setup command, Auto tab, reset). Pin fleet version first.
  • Developer allow can override org soft_deny; use managed permissions.deny for must-never actions.
  • Conversation-only boundaries can vanish on compaction — prefer ask/deny rules.
  • Built-in rule text evolves; dump claude auto-mode defaults on your install.

What to do next

  1. 1. Run claude auto-mode defaults and config on a pilot machine; archive the JSON.
  2. 2. Start with environment + "$defaults" (source-control org, domains, buckets, package registry).
  3. 3. Put irreversible boundaries in hard_deny (and/or managed permissions.deny); reviewable destructive ops in soft_deny.
  4. 4. Add allow only for repeated, defensible false positives; optionally permissions.ask for push/PR checkpoints.
  5. 5. Consider classifyAllShell: true when narrow Bash allows are too loose; roll via managed settings and re-check after each minor bump.

AIImpish Take

Auto mode config is an org trust boundary product, not a convenience toggle. environment defines “internal”; hard_deny / soft_deny / allow encode severity; "$defaults" is the safety pin. Ship managed deny for must-never actions, keep custom rules as clear prose, and verify with claude auto-mode config — not vibes.