Skip to main content

Mental Model

Claude Code's configuration system has five scopes, three permission types, six permission modes, and over 100 environment variables. This page maps the entire system so you know exactly what controls what.

The Five Scopes

Every setting in Claude Code belongs to one of five scopes. Settings merge from lowest to highest priority, with more specific scopes overriding broader ones.

Managed (highest priority)

CLI arguments

Local (.claude/settings.local.json)

Project (.claude/settings.json)

User (~/.claude/settings.json) (lowest priority)
ScopeLocationWho It AffectsCommitted to Git?
ManagedServer-managed, MDM/plist/registry, or managed-settings.jsonAll users on the machineDeployed by IT
CLI args--model, --permission-mode, --allowedTools, etc.Current session only✗ No
Local.claude/settings.local.jsonYou, in this repo onlyNo (gitignored)
Project.claude/settings.jsonAll collaborators✓ Yes
User~/.claude/settings.jsonYou, across all projects✗ No

Array merge behavior: Array-valued settings like permissions.allow are concatenated and deduplicated across scopes, not replaced. Lower-priority scopes add entries without overriding higher-priority ones.

Managed tier precedence: Within the managed tier, the order is: server-managed > MDM/OS-level policies > file-based (managed-settings.d/*.json + managed-settings.json) > HKCU registry (Windows only). Only one managed source is used — sources do not merge across tiers.

Managed Settings Delivery

Managed settings reach machines through multiple channels:

  • Server-managed: Anthropic's servers via Claude.ai admin console
  • macOS MDM: com.anthropic.claudecode managed preferences domain (Jamf, Kandji)
  • Windows Group Policy: HKLM\SOFTWARE\Policies\ClaudeCode registry key
  • Windows user-level: HKCU\SOFTWARE\Policies\ClaudeCode (lowest policy priority)
  • File-based: Platform-specific paths with a drop-in directory

File-based paths:

PlatformPath
macOS/Library/Application Support/ClaudeCode/managed-settings.json
Linux/WSL/etc/claude-code/managed-settings.json
WindowsC:\Program Files\ClaudeCode\managed-settings.json

The drop-in directory managed-settings.d/ sits alongside the main file. Files are sorted alphabetically and deep-merged. Use numeric prefixes (10-telemetry.json, 20-security.json) to control merge order.

# Example: managed-settings.d/ drop-in directory
/etc/claude-code/
  managed-settings.json              # Base managed config
  managed-settings.d/
    10-telemetry.json                # {"disableTelemetry": true}
    20-security.json                 # {"permissions": {"deny": [...]}}
    30-models.json                   # {"availableModels": ["sonnet"]}
// 20-security.json — merged into managed-settings.json
{
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)"
    ]
  },
  "allowManagedPermissionRulesOnly": true
}

Permission System Architecture

Three Rule Types

TypeEffect
AllowClaude uses the tool without prompting
AskPrompts for confirmation each time
DenyBlocks the tool entirely

Evaluation order: deny → ask → allow. First match wins. Deny always takes precedence over everything.

Six Permission Modes

ModeBehavior
defaultPrompts on first use of each tool
acceptEditsAuto-accepts file edits and common filesystem commands in working directory
planRead-only — Claude can analyze but not modify
autoBackground classifier reviews commands (research preview)
dontAskAuto-denies unless pre-approved via permissions.allow
bypassPermissionsSkips all prompts except writes to .git, .claude, .vscode, .idea, .husky

Set via permissions.defaultMode in settings or --permission-mode at startup.

Permission Rule Syntax

Rules follow the format Tool or Tool(specifier).

Bash patterns:

Bash                          # Matches ALL Bash commands
Bash(npm run build)           # Exact match
Bash(npm run *)               # Glob wildcard (space = word boundary)
Bash(npm*)                    # No space = no word boundary; matches "npm" and "npmrc"
Bash(git * main)              # Wildcard in middle
Bash(* --version)             # Wildcard at start

Read/Edit patterns (gitignore syntax):

Read(./.env)                  # Relative to current directory
Read(/src/**/*.ts)            # Relative to project root
Read(~/Documents/*.pdf)       # Home directory
Read(//Users/alice/secrets)   # Absolute path (double slash!)
Edit(/docs/**)                # Recursive in project docs/

Other tools:

WebFetch(domain:example.com)  # Domain restriction
mcp__puppeteer                # All tools from an MCP server
mcp__puppeteer__navigate      # Specific MCP tool
Agent(Explore)                # Specific subagent

Compound Command Awareness

Claude Code is shell-aware. Bash(safe-cmd *) does NOT allow safe-cmd && dangerous-cmd. Shell operators (&&, ||, ;, |, |&, &, newlines) are recognized and each subcommand must match independently.

Process wrappers: Before matching, Claude Code strips timeout, time, nice, nohup, stdbuf, and bare xargs. So Bash(npm test *) also matches timeout 30 npm test.

Managed-Only Settings

These settings have NO effect in user or project settings — they only work in managed settings:

SettingPurpose
allowManagedHooksOnlyBlock all non-managed hooks
allowManagedMcpServersOnlyOnly allow admin-defined MCP servers
allowManagedPermissionRulesOnlyBlock user/project permission rules
forceRemoteSettingsRefreshBlock startup until remote settings fetched
sandbox.filesystem.allowManagedReadPathsOnlyOnly admin-defined read paths
sandbox.network.allowManagedDomainsOnlyOnly admin-defined network domains

Placing these in project or user settings does nothing — no error, no warning, just silent ignore.

Model Selection Strategy

Available Models and Aliases

AliasModelBest For
sonnetSonnet 4.6Daily coding, implementation, fast iteration
opusOpus 4.6Complex reasoning, architecture, debugging
haikuHaiku 4.5Simple tasks, quick lookups, background work
bestCurrently Opus 4.6Maximum capability
opusplanOpus for planning, Sonnet for executionBest cost/quality ratio
sonnet[1m]Sonnet 4.6 with 1M contextLong sessions, large codebases
opus[1m]Opus 4.6 with 1M contextComplex work in large codebases

Model Priority Order

  1. /model <alias> during session (highest)
  2. claude --model <alias> at startup
  3. ANTHROPIC_MODEL environment variable
  4. model field in settings.json (lowest)

Effort Levels

Controls adaptive reasoning depth. Supported on Opus 4.6 and Sonnet 4.6.

LevelUse Case
lowFast, straightforward tasks
mediumDefault for Pro/Max subscribers
highDefault for API/Team/Enterprise; complex work
maxDeepest reasoning, Opus 4.6 only, does not persist

Set via /effort, --effort flag, CLAUDE_CODE_EFFORT_LEVEL env var, or effortLevel in settings. Include "ultrathink" in a prompt to trigger high effort for a single turn.

Cost Guidance

Opus 4.6 is roughly 15x more expensive than Haiku. Pick models deliberately:

Task TypeRecommended Model
Exploration, simple lookupshaiku
Daily implementation, code reviewsonnet
Complex debugging, architectureopus
Mixed complexity projectsopusplan
Large codebase navigationsonnet[1m] or opus[1m]

The Profile System

Claude Code has no built-in profile system. Profiles are achieved through CLAUDE_CONFIG_DIR, which points to a fully isolated configuration directory — credentials, settings, history, plugins, agents, hooks.

# Create profile directories
mkdir -p ~/.claude-work ~/.claude-personal
 
# Shell aliases
alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'
alias claude-personal='CLAUDE_CONFIG_DIR=~/.claude-personal claude'

Each profile directory is completely independent. Switching profiles means switching everything.

Community tools for profile management:

  • claude-code-profiles: Complete isolated profile directories
  • claudectx: claudectx work switches in one command
  • claude-provider: Plugin + CLI for switching providers

Key Environment Variables

Over 100 environment variables exist. These are the ones that matter most:

CategoryVariablePurpose
AuthANTHROPIC_API_KEYAPI key
AuthCLAUDE_CODE_OAUTH_TOKENOAuth access token
ModelANTHROPIC_MODELOverride model selection
ModelCLAUDE_CODE_SUBAGENT_MODELModel for subagents
BehaviorCLAUDE_CONFIG_DIRConfig directory (default ~/.claude)
BehaviorCLAUDE_CODE_DISABLE_CLAUDE_MDSSkip CLAUDE.md loading
PerformanceBASH_DEFAULT_TIMEOUT_MSBash timeout (default 120000ms)
PerformanceCLAUDE_AUTOCOMPACT_PCT_OVERRIDEAuto-compaction trigger (1-100)
CI/CDDISABLE_TELEMETRYDisable telemetry
CI/CDCLAUDE_CODE_SKIP_PROMPT_HISTORYSkip writing transcripts
CloudCLAUDE_CODE_USE_BEDROCKUse AWS Bedrock provider
CloudANTHROPIC_BASE_URLAPI endpoint override (proxies/gateways)

All env vars can also be set in settings.json under the env key, making them version-controllable.

The settings.json Schema

Add the official JSON Schema for IDE autocomplete:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json"
}

This gives you validation and autocomplete for every field in your editor. The schema covers all settings.json fields including permissions, hooks, sandbox, model, env, and the 50+ other configuration options.