~/.claude.json instead. To pick a file, or check precedence, start with Settings files and precedence.
Settings index
Every key below links to its entry. Scope lists the files it can go in:User is ~/.claude/settings.json, Project is .claude/settings.json, Local is .claude/settings.local.json, and Managed is what your organization deploys. Any file means all four, and Global config means ~/.claude.json.
Model and responses
Choose which models Claude Code uses and how it responds. For how these settings interact with the/model command and environment variables, see Model configuration.
advisorModel
Pick which model answers when Claude calls the server-side advisor tool. Unset it to turn the advisor off. The advisor must be at least as capable as your main model. See Choose an advisor model for the accepted pairings and what happens when you pick one that isn’t accepted.
You don’t usually edit this key by hand. Run /advisor to open a picker that shows the current choice, the models that can advise, and No advisor. Claude Code saves your pick to this key in ~/.claude/settings.json. If you pick from a Remote Control client or in a session attached to a remote worker, the pick applies to that session only and doesn’t change this key.
If your account requires the usage-credits consent, accept it first by running /model fable. Until you do, picking Fable in /advisor saves nothing and Claude Code tells you to run /model fable first.
- Scope:
Any file - Type: string, one of the aliases
"fable","opus", or"sonnet", which resolve to Claude Code’s current default version of that model family, or a full model ID such as"claude-opus-5-5" - Default: unset, so the advisor is off
- Per-session overrides:
--advisortakes precedence over this key for one session.CLAUDE_CODE_DISABLE_ADVISOR_TOOLturns the advisor off, and this key can’t turn it back on
settings.json
"fable" requires Fable access.
alwaysThinkingEnabled
Turn extended thinking off for every session by setting this to false. Thinking is on by default, so true changes nothing. Most people set this through /config rather than by editing the file.
On models that always think, such as Opus 5.5, Sonnet 5.5, Haiku 5.5, and the Fable models, false has no effect. On third-party providers Claude Code omits the thinking parameter instead of turning thinking off, so adaptive-reasoning models may still think. With thinking turned off on the Anthropic API, Claude Code sends effort high instead of a higher level to models it knows don’t accept that combination, such as Opus 5.
- Scope:
Any file - Type: Boolean
true: no effect; thinking is already onfalse: Claude Code turns extended thinking off for every session
- Default: unset, so thinking is on for models that support it
- Per-session overrides:
MAX_THINKING_TOKENStakes precedence over this key for one session:0turns thinking off, under the same model and provider limits asfalse, and a positive value turns thinking on even when this key isfalse. On adaptive-reasoning models the number itself is ignored
settings.json
availableModels
Restrict which models people can select for the main session, subagents, skills, and the advisor. A managed list constrains /model, --model, and the model key in a developer’s own files; a model outside it can’t be selected. With the default prefix matching, this doesn’t touch the Default option on its own; pair it with enforceAvailableModels for that.
- Scope:
Any file. Deploy it in managed settings to enforce it for an organization. - Type: array of model aliases or IDs
- Default: unset, so every model is available
settings.json
"claude-opus-5" also permits later versions that extend it, such as Opus 5.5. To block one of those versions, use deniedModels. To make each model ID entry permit only the version it names, use availableModelsMatch. See Restrict model selection. For third-party provider IDs, see Pin models for third-party deployments.
availableModelsMatch
Choose how availableModels entries match model IDs. By default a model ID entry also permits later versions that extend it, so "claude-opus-5" permits Opus 5.5. With "exact", each model ID entry permits only the version it names, so a newer version of that model stays blocked until you list it. Requires Claude Code v2.1.283 or later.
- Scope:
Managed. Claude Code ignores the key in user, project, and local settings and in--settings, with a warning - Type: string, one of:
"prefix": a model ID entry permits its version and any model ID that extends it with another segment"exact": a model ID entry permits only the version it names, so"claude-opus-5"permits Opus 5 but notclaude-opus-5-5. An entry such as"claude-opus-4-5"also permits its dated Anthropic model IDclaude-opus-4-5-20251101. A family alias such as"opus"still permits the whole family, andbest,opusplan, anddefaultentries are ignored
- Default:
"prefix"
managed-settings.json
"exact", the Default option is also limited to the listed models whenever the list names at least one model or family. See Block specific models or versions.
deniedModels
Block specific models, with or without an availableModels allowlist and even when that list permits them. Claude Code hides a blocked model from the /model picker, and the model can’t be selected anywhere availableModels is enforced. A session on the Default option doesn’t run a blocked model either, as Block specific models or versions describes. Requires Claude Code v2.1.283 or later.
- Scope:
Managed. Claude Code ignores the key in user, project, and local settings and in--settings, with a warning - Type: array of model aliases or IDs
- A family alias such as
"opus"blocks every model in that family - A model ID such as
"claude-opus-5-5"blocks that version in every spelling, including dated and provider-specific IDs - A model ID with no minor version, such as
"claude-opus-5", also blocks later minor versions such as Opus 5.5. Write"claude-opus-5-0"to block Opus 5 alone best,opusplan, anddefaultentries are ignored
- A family alias such as
- Default: unset, so no model is blocked
managed-settings.json
effortLevel
Set a default effort level for models you haven’t saved a level for. Lower levels are faster and cheaper on straightforward tasks, and higher levels reason more deeply on complex problems.
When you run /effort low, medium, high, or xhigh in an interactive session on your machine, Claude Code saves the level for the active model under modelSettings rather than writing this key. Before v2.1.251, /effort wrote this key.
Within the same settings file, Claude Code uses a model’s saved level rather than this key. modelSettings states the cross-file precedence.
In a session attached to a remote worker, in a -p run, and in the Agent SDK, /effort applies to that session only. Adjust effort level lists the interactive picks that also apply to that session only. The message that /effort prints says which happened.
- Scope:
Any file - Type: string, one of:
"low": the least reasoning, for short, scoped, latency-sensitive tasks that aren’t intelligence-sensitive"medium": reduces token usage for cost-sensitive work that can trade off some intelligence"high": balances token usage and intelligence"xhigh": deeper reasoning at higher token spend
- Default: unset
- Per-session overrides:
--efforttakes precedence over this key for one session, andCLAUDE_CODE_EFFORT_LEVELtakes precedence over both
settings.json
~/.claude/settings.json, this key is the older form /effort wrote before it saved levels per model, and it keeps applying where it applied before, on Opus 5, Fable 5.1, and earlier models. Opus 5.5 and models released after it ignore it and start at their own default until you save a level for them, which /effort writes under modelSettings. In project, local, and managed settings, and with --settings, this key applies to every model.
enforceAvailableModels
The /model picker has a Default option, and default model setting describes the model it resolves to. An availableModels allowlist limits the models you can name, but with the default prefix matching it doesn’t remap your account type’s default, so Default can still resolve to a model outside the list. This key closes that gap. Requires Claude Code v2.1.175 or later.
When your organization deploys any managed settings, Claude Code reads this key from the managed source alone and ignores it in your other files.
For how this key applies to the startup model checks, see Amazon Bedrock and Google Cloud’s Agent Platform.
- Scope:
Any file - Type: Boolean
true: when Default would resolve to a model outsideavailableModels, Claude Code resolves it to the first available model in the listfalse: this key doesn’t change how Default resolves
- Default:
false
settings.json
availableModels is unset or empty. See Enforce the allowlist for the Default model. Requires Claude Code v2.1.175 or later.
fallbackModel
Name backup models for Claude Code to try, in order, when your primary model is overloaded or unavailable. Claude Code switches to the next available model in the chain for the rest of the turn and shows a notice. Without a chain, Claude Code retries the same model and then surfaces the server’s error, and you retry or switch models yourself.
A switch means one turn with a cold prompt cache on the fallback model; your next message tries the primary model first again.
- Scope:
Any file - Type: array of model aliases or IDs;
"default"expands to the default model - Default: unset, so a failed request isn’t retried on another model
- Per-session overrides:
--fallback-modeltakes precedence over this key for one session
settings.json
["claude-sonnet-5"] and your user file sets ["claude-haiku-4-5"], the chain is ["claude-sonnet-5"] only. Claude Code keeps at most three distinct allowed models from the list and ignores the rest. See Fallback model chains.
fastMode
Turn fast mode on for sessions where it’s available, for interactive work such as rapid iteration or live debugging where you want speed at a higher cost per token. You don’t usually edit this key yourself. Running /fast writes fastMode: true to ~/.claude/settings.json, and running it again to turn fast mode off removes the key.
On the Anthropic API, only Fable 5.2, Opus 5.5, Opus 5, and Opus 4.8 support fast mode. Running /fast from another model switches you to Opus, and switching to an unsupported model turns fast mode off. See Switch models while fast mode is on. On Google Cloud’s Agent Platform, /fast switches you to Fable 5.2 instead and doesn’t write this key, and Claude Code ignores a saved true.
- Scope:
Any file - Type: Boolean
true: Claude Code turns fast mode on for sessions where it’s available. On Fable 5.2, you must also run/fastwhile using Fable 5.2false: fast mode stays off
- Default: unset, so fast mode is off
- Per-session overrides:
CLAUDE_CODE_DISABLE_FAST_MODEturns fast mode off for one session, and this key can’t turn it back on
settings.json
fastModePerSessionOptIn
Normally, running /fast saves fastMode to a person’s user settings, so new sessions on a supported model start with fast mode on. On Fable 5.2, that happens only if they turned it on while using Fable 5.2. To make each person run /fast in each session they want it, set this key to true. Claude Code leaves fastMode in their file, so turning this key off restores the old behavior.
Owners on Team or Enterprise plans can deploy it organization-wide through server-managed settings. When managed settings set the key, /fast on is refused outside interactive terminal sessions and reports that your organization has disabled fast mode. That covers non-interactive mode, the VS Code extension, and cloud sessions.
- Scope:
Any file - Type: Boolean
true: a savedfastMode: trueno longer turns fast mode on at session start, so each person runs/fastin each session they want it; afastMode: truepassed with--settingsstill counts for that session unless managed settings set this keyfalse: a savedfastMode: trueworks asfastModedescribes
- Default:
false
settings.json
language
Have Claude respond in a language other than English by default. There is no fixed list for responses: Claude Code passes the value verbatim to Claude as an instruction to always respond in that language, so any language name Claude can read works. Claude Code doesn’t check the value, so a misspelled name reaches Claude as written rather than producing an error. The same value sets the language for voice dictation, which does have a fixed list of supported dictation languages, and for auto-generated session titles.
- Scope:
Any file - Type: string, any language name, such as
"japanese","spanish", or"french"; Claude Code doesn’t validate it - Default: unset; session titles then match the language of your conversation
settings.json
maxEffortLevel
Cap the effort level a session can use, leaving lower levels available. Any higher level runs at the cap instead, including one from /effort, the /model picker, --effort, CLAUDE_CODE_EFFORT_LEVEL, a skill’s or subagent’s effort frontmatter, or the model’s own default. Claude Code applies the cap itself before each request, so it holds on every provider, including Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry. Requires Claude Code v2.1.267 or later.
- Scope:
Any file. Deploy it in managed settings to enforce it for an organization. When several scopes set a cap, the lowest applies, so a cap set in one scope can’t be raised from another - Type: string, one of
"low","medium","high","xhigh", or"max". A"max"value sets no cap - Default: unset, so no cap applies
- Per-model caps: add
maxEffortLevelto a model’smodelSettingsentry. That entry replaces this key for the model only within the settings source that sets both, such as your user settings or one managed source. Set"max"there to exempt the model from that source’s cap; Claude Code still applies caps from other sources
medium and exempts Sonnet 4.6:
settings.json
model
Set the model every new session uses, so you don’t have to pick one with /model each time. Setting it here doesn’t stop you from switching mid-session. If your admin set an organization default model to override user selection, you get that model even when you set this key in user, project, or local settings.
- Scope:
Any file - Type: string, a model alias or full model ID
- Default: unset, so Claude Code uses your account’s default model
- Per-session overrides:
--modeltakes precedence overANTHROPIC_MODEL, and both take precedence over this key for one session, including over a managedmodel; anavailableModelslist still applies to the pick
settings.json
ANTHROPIC_DEFAULT_MODEL, which Claude Code uses only when nothing else selects a model.
modelOverrides
Map Anthropic model IDs to provider-specific model IDs, such as Amazon Bedrock inference profile ARNs. Each model picker entry then uses its mapped value when calling the provider API. Administrators use this on Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry to route each model version to a specific inference profile, version name, or deployment for governance, cost allocation, or regional routing.
- Scope:
Any file - Type: object mapping model ID to provider model ID
- Default: unset
settings.json
modelPicker
List the models the /model picker offers, in the order you write them and under labels you choose, so the picker lists the models your organization runs, after the built-in lineup or instead of it. Each row’s model is taken verbatim, so it accepts anything --model accepts: an alias such as opus, an Anthropic model ID, or a provider-format ID for Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or an LLM gateway. Requires Claude Code v2.1.242 or later.
- Scope:
User or managed. Claude Code reads the key from managed settings,--settings, and user settings, and ignores it in project and local settings so a repository you clone can’t relabel the picker. The highest of those three that sets the key supplies the whole lineup, and Claude Code never combines lineups from two sources. - Type: object with an
optionsarray of rows and an optionalreplaceBuiltInOptionsBoolean - Default: unset, so the picker shows the built-in lineup
managed-settings.json
Fields for modelPicker
The key takes two fields, one for the rows themselves and one for whether they replace the built-in lineup or add to it.
An entry in
options can also carry an optional behavesAs string beside its model, which requires v2.1.257 or later. Set it to the ID of a model your Claude Code version already knows, such as claude-opus-4-8, on an entry whose model is newer than your version. Claude Code then applies that known model’s capabilities and effort defaults to the entry instead of treating its model as unknown. The entry’s label and the model ID Claude Code sends in requests don’t change.
With replaceBuiltInOptions on, Claude Code hides every other row: the built-in lineup, the rows it adds for availableModels entries, the models gateway discovery found, and ANTHROPIC_CUSTOM_MODEL_OPTION. With it off, Claude Code skips a listed model that the built-in lineup already covers. A label changes what the picker shows, not which model Claude Code runs.
An availableModels allowlist still applies to these rows. Before you add a listed model to the allowlist, read Merge behavior: a specific model ID narrows its family’s wildcard entry. Claude Code also checks each row against the session before it shows the picker:
- Dropped: a row Claude Code can’t serve, such as a retired model or a model your organization has no access to
- Grayed out: a row you can’t select yet, shown with the reason
- No row survives: Claude Code keeps the built-in lineup, filtered by the allowlist as usual
modelPricing
Report spend at the rates your organization pays instead of list price. Set it when your organization has contracted rates, so the dollar figures developers see match your bill. Claude Code applies the rates in /usage, the status line, the Agent SDK’s total_cost_usd, the --max-budget-usd limit, and the OpenTelemetry cost metric and events. You supply the rates: Claude Code doesn’t read them from your contract or the Claude Console. Requires Claude Code v2.1.242 or later.
- Scope:
Managed. Deploy the key through server-managed settings, an MDM policy, amanaged-settings.jsonfile, or a policy helper. Claude Code ignores it in user, project, and local settings, in--settings, and on Windows in the user-writable HKCU registry. With server-managed settings, each session reports costs at list price until that session’s settings fetch has confirmed the setting. A host application that embeds Claude Code and setsCLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTcan supply a table of its own through the SDKmanagedSettingsoption, which Claude Code uses only when no managed source sets the key and only in Claude Code v2.1.246 or later. - Type: object with an optional
multiplierand an optionaloverridesmap - Default: unset, so Claude Code reports list price unless a host application supplies a table
multiplier alone for a flat discount or markup, overrides alone for per-model rates, or both.
This example sets contracted rates for Sonnet 4.6 and then reduces every figure, the Sonnet row included, by 15%:
managed-settings.json
multiplier above 1, up to 10, to mark every figure up. A markup requires Claude Code v2.1.271 or later. Earlier versions ignore a multiplier above 1 with a warning and keep the rest of the setting.
For the steps, including how to confirm the rates are in effect, see Report spend at your contracted rates.
Fields for modelPricing
Claude Code uses a row’s rates exactly as you wrote them, without adding the fast-mode surcharge or the US-only-inference rate. If you also set
multiplier, Claude Code applies it on top of the row’s rates. Claude Code drops a row with a rate it can’t parse, or a multiplier it can’t parse, and keeps the rest; see Fix a broken settings file.
Which models a modelPricing row applies to
Claude Code decides which models a row applies to from the row’s key:
- A built-in model’s ID: a key Claude Code itself uses for a built-in model, whether that key is the model’s own ID, such as
claude-sonnet-4-6, or its Bedrock, Agent Platform, or Foundry ID. Claude Code applies the row to every dated snapshot ID and provider-specific ID of that model. - Any other key: a key that isn’t a built-in model’s ID, such as a gateway model alias. Claude Code applies the row to that one ID only. When a model ID matches one of your keys exactly and also falls under a row keyed by a built-in model’s ID, Claude Code uses the exact match.
- A Bedrock application inference profile: once Claude Code has resolved the profile to the model it routes to, through your
modelOverridesmap or thebedrock:GetInferenceProfilelookup, Claude Code applies that model’s row to the profile.
modelSettings
Save an effort level for each model you use. Requires Claude Code v2.1.251 or later.
In an interactive session on your machine, when you save low, medium, high, or xhigh as your default with /effort or the /model picker’s effort slider, Claude Code writes that level here under the model you’re using, so you rarely edit this key yourself. When you pick one of those levels in the VS Code extension’s model picker, Claude Code saves it here the same way. The effortLevel entry lists the sessions where /effort applies to that session only.
Edit the key by hand to change or remove a level you saved.
A model’s effortLevel here takes precedence over the top-level effortLevel in the same settings file. Across files, Claude Code resolves each model separately: the highest-precedence settings file that sets either an effortLevel for that model or a top-level effortLevel that applies to that model decides, so an effortLevel in managed settings outranks a level you saved in user settings. Adjust effort level lists what else can override a saved level, such as --effort at launch.
To cap one model’s effort rather than set its level, add a maxEffortLevel field to that model’s entry. The field requires Claude Code v2.1.267 or later.
- Scope:
Any file - Type: object mapping a model name to an object with any of these fields:
effortLevel: one of"low","medium","high", or"xhigh"maxEffortLevel: the highest effort level the model may run atautoCompactWindow: a number of tokens from100000to1000000, or"auto"for the window tuned for the model./autocompactsaves here. For that model, the value takes precedence over a top-levelautoCompactWindowin the same settings file. Requires Claude Code v2.1.288 or later
- Default: unset
claude-opus-5-5, and matches that model’s alias, date-suffixed, [1m], and recognized provider-specific IDs to the same entry.
This example keeps Opus 5.5 at high while other models use their own saved or default levels:
settings.json
/effort auto to clear your saved level for the model you’re using. Claude Code leaves the other entries and any top-level effortLevel in place.
outputStyle
Select an output style by name. An output style is a saved set of instructions that changes Claude’s role, tone, and output format, such as the built-in Explanatory and Learning styles or one you wrote yourself.
If you change this key during a session, Claude uses the new style starting with your next message. For what that message costs in prompt caching, see Changing output style. Before v2.1.251, the edit applied only after you ran /clear or started a new session.
- Scope:
Any file - Type: string, the name of a built-in or custom output style
- Default: unset, so Claude Code uses the default style
settings.json
promptCacheTtl
Choose how long the prompt cache holds the main conversation. This key applies to your interactive, -p, and Agent SDK turns, together with the helpers Claude Code runs inline with them. The one-hour lifetime keeps the cache warm across longer breaks, and the API bills each cache write at a higher rate than at the five-minute lifetime. Requires Claude Code v2.1.242 or later.
- Scope:
Any file - Type: string, one of:
"5m": the cache holds for five minutes"1h": the cache holds for an hour
- Default: unset, so each main-conversation request gets its default lifetime
- Per-session overrides:
FORCE_PROMPT_CACHING_5Mtakes precedence over everything else, thenCLAUDE_CODE_PROMPT_CACHE_TTL, then this key, and lastENABLE_PROMPT_CACHING_1H
settings.json
showThinkingSummaries
See summaries of Claude’s extended thinking in interactive sessions. Set it if you want the full summaries when you expand thinking with Ctrl+O. When unset or false, the Anthropic API redacts thinking blocks and Claude Code shows a collapsed stub.
- Scope:
Any file - Type: Boolean
true: you see full thinking summaries when you expand thinking withCtrl+Ofalse: the Anthropic API redacts thinking blocks and Claude Code shows a collapsed stub
- Default:
false
settings.json
subagentPromptCacheTtl
Choose how long the prompt cache holds the requests Claude Code makes outside the main conversation. This key applies to subagents, workflows, and Claude Code’s own background and helper requests, such as compaction and session titles. The one-hour lifetime keeps the cache warm across longer breaks, and the API bills each cache write at a higher rate than at the five-minute lifetime. Requires Claude Code v2.1.242 or later.
- Scope:
Any file - Type: string, one of:
"5m": the cache holds for five minutes"1h": the cache holds for an hour
- Default: unset, so each of these requests gets its default lifetime
- Per-session overrides:
FORCE_PROMPT_CACHING_5Mtakes precedence over everything else, thenCLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL, then this key, thenENABLE_PROMPT_CACHING_1H, which asks for the one-hour lifetime on every request. For where a subagent’s own frontmatter value ranks, see Choose the TTL yourself
settings.json
promptCacheTtl doesn’t, so set both to choose a lifetime for every request Claude Code makes. For how a subagent’s cache differs from the main conversation’s, see Subagents and the cache.
switchModelsOnFlag
Choose what happens when a safety classifier flags a request: switch to the fallback model and continue, or pause so you can choose between switching and editing the prompt.
- Scope:
Any file. Appears in/configas Switch models when a message is flagged, with the options Switch automatically and Ask each time. - Type: Boolean
true: Claude Code switches to the fallback model and continuesfalse: in an interactive session Claude Code pauses so you can choose between switching and editing the prompt; where no dialog can show, such as a-prun, the flagged request ends as an error
- Default: unset. Claude Code switches automatically, though it may ask first in an interactive session
settings.json
ultracode
Start sessions with ultracode on. With it on, Claude plans a workflow for each substantive task instead of waiting for you to ask. Claude plans workflows only when dynamic workflows are enabled for you and your model supports xhigh effort. The key doesn’t change the session’s effort level: ultracode runs at whichever level the session uses. Claude Code reads this key but never writes it: /effort ultracode turns ultracode on for the current session only.
- Scope:
Any file - Type: Boolean
true: sessions start with ultracode on when dynamic workflows are enabled for you and your model supportsxhighfalse: sessions start with ultracode off
- Default: unset, so ultracode is off
- Per-session overrides:
/effort ultracodeturns ultracode on for one session without this key, and/effort ultracode offturns it off for one session when this key istrue. The--effort ultracodeflag also turns it on for one session, atxhigheffort
settings.json
effortLevel, modelSettings, and the other effort sources, and an effort cap such as maxEffortLevel lowers that level without turning ultracode off. This and the /effort ultracode off form require Claude Code v2.1.284 or later. Before v2.1.284, ultracode: true ran the session at xhigh effort, and an effort cap below xhigh kept ultracode off. An Agent SDK apply_flag_settings control request also accepts the key.
Permission settings
Decide what Claude can do without asking, the default permission mode for new sessions, and what auto mode’s classifier allows. For rule syntax and the permission model, see Configure permissions.allowManagedPermissionRulesOnly
Make managed settings the only settings source of permission rules. Claude Code then ignores allow, ask, and deny rules in user, project, local, and --settings files, ignores --allowedTools, hides the always-allow choices in permission prompts, and stops saving new rules.
When parent settings from an embedding host apply, Claude Code treats them as part of the managed tier. It drops their allow rules and additionalDirectories, and keeps their deny and ask rules except Read and Edit rules whose pattern starts with !. A host can’t carve paths out of the managed rules with a ! rule, whether or not you set this key.
--disallowedTools rules and the current session’s deny and ask rules still apply, including after Claude Code reloads settings mid-session. They only restrict, so they can’t widen what the managed rules grant. Before v2.1.257, Claude Code dropped those command-line and session rules at the first settings reload.
For what a ! pattern in a --disallowedTools or session rule can carve out, see Read and Edit rules.
When you set this key, Claude Code v2.1.282 or later also ignores the allowed-tools frontmatter in skills and .claude/commands/ files from these sources:
- A repository’s
.claude/directory - Your
~/.claude/skills/and~/.claude/commands/directories, including skills synced from claude.ai - An
--add-dirdirectory - Plugins declared with a
.claude-pluginmanifest inside~/.claude/skills/or the project’s.claude/skills/ - Plugins loaded for one session only, whose ids end in
@inline, when all of these hold:- The session is a Code session or Cowork session, other than a cloud session, for which the Claude Desktop app itself starts Claude Code
- Your managed settings set the key, not only an embedding host’s parent settings
- The session runs Claude Code v2.1.305 or later
allowed-tools. @inline plugins outside those Desktop sessions keep theirs too, except one named anthropic-skills. A skill’s disallowed-tools still applies. For what a developer sees when Claude Code ignores the field, see When only managed permission rules apply.
- Scope:
Managed - Type: Boolean
true: managed settings become the only settings source of permission rulesfalse: Claude Code applies permission rules from user, project, local, and--settingsfiles in addition to the managed ones
- Default: unset, so Claude Code applies permission rules from user, project, and local settings and from
--settings, in addition to the managed ones
managed-settings.json
allowManagedMcpServersOnly. See Managed-only settings.
autoMode
Add your own rules to what the auto mode classifier blocks and allows. Use it to tell the classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations. The classifier ships with built-in allow and deny rules. Include the literal string "$defaults" in an array to keep those built-in rules at that position and add yours around them; leave it out to replace them with yours.
- Scope:
User or managed - Type: object with
environment,allow,soft_deny, andhard_denyarrays of prose rules, plus theclassifyAllShellBoolean - Default: unset, so the classifier uses only its built-in rules
soft_deny rules, through "$defaults", and adds one more that blocks terraform apply:
settings.json
autoMode.classifyAllShell
Send every Bash and PowerShell command through the auto mode classifier while auto mode is active. By default, auto mode suspends only allow rules that could run arbitrary code: tool-wide and wildcard rules such as Bash(*), and interpreter or shell-wrapper prefixes such as Bash(python *). A command that any other allow rule matches, such as Bash(npm test), skips the classifier unless it carries per-command allowed domains. When it skips, a destructive argument the rule’s prefix didn’t anticipate can get through unseen. Setting this key suspends every shell allow rule for the session so the classifier sees every command. Requires Claude Code v2.1.193 or later.
- Scope:
User or managed. Read whereverautoModeis read. - Type: Boolean
true: while auto mode is active, Claude Code sends every Bash and PowerShell command through the classifier and suspends your shell allow rules; outside auto mode the rules still applyfalse: auto mode suspends only allow rules that could run arbitrary code, such asBash(*)andBash(python *); a command that any other allow rule matches skips the classifier unless it carries per-command allowed domains, and every other shell command goes through it
- Default:
false
settings.json
disableAutoMode
Remove auto mode from the Shift+Tab cycle. Any session that would otherwise start in auto mode, whether from --permission-mode auto, a settings file, or the built-in default, starts in default instead. Administrators set it in managed settings to prevent developers in their organization from using auto mode.
- Scope:
Any file. Most useful in managed settings, where users can’t override it. Also accepted underpermissionsaspermissions.disableAutoMode. - Type: the string
"disable" - Default: unset
settings.json
permissions
Control which tools Claude can use without asking, which ones prompt, and which ones are blocked. Also set the default permission mode for new sessions. Every permissions.* key below nests under this object.
- Scope:
Any file - Type: object with
allow,ask,deny,additionalDirectories,blockReadsOutsideWorkingDirectories,blockWritesOutsideWorkingDirectories,defaultMode,denyInsteadOfPrompting,disableBypassPermissionsMode, anddisableAutoMode - Default: unset
npm run commands without asking, prompts before git push, blocks reads of .env, and starts sessions in acceptEdits:
settings.json
permissions.allow. For how permission rules from different files combine, see how permission rules merge across scopes; for how settings keys in general combine, see Settings precedence on the settings guide.
useAutoModeDuringPlan
Choose whether Claude Code uses the auto mode classifier to review shell commands in plan mode. With the default true, the classifier reviews each command during planning when auto mode is available and you see no prompt, except for critical-path removals. Set false to get a permission prompt for every command outside the built-in read-only set. Appears in /config as Use auto mode during plan.
- Scope:
User, local, or managed. A repository can’t turn it off for you.- A
falsein any of these files or in--settingsturns it off, unless you leave that user or local file out with an option such as--setting-sources. Ignoring a left-out file requires Claude Code v2.1.314 or later
- A
- Type: Boolean
true: the same as unset; when auto mode is available, the classifier reviews shell commands during planningfalse: you get a permission prompt for every command outside the built-in read-only set
- Default:
true
settings.json
permissions.allow
List the tool uses Claude Code approves without asking you. In an MCP rule, * can appear only in the tool name after the mcp__<server>__ prefix, such as mcp__github__get_*; it can’t appear in the server name.
- Scope:
Any file - Type: array of permission rule strings
- Default: unset
- Per-session overrides:
--allowedToolsadds allow rules for one session, and a deny rule from any settings file still blocks a tool it names
git diff and lets Claude Code read your .zshrc without asking:
settings.json
allow rules from a project’s .claude/settings.json only after you accept the workspace trust dialog for that folder.
Permission rule syntax
Permission rules follow the formatTool or Tool(specifier). Claude Code evaluates deny rules first, then ask, then allow, and the first match decides regardless of how specific each rule is; see the permission rule evaluation order.
Each row shows one rule shape and what it matches.
For the complete rule syntax, including wildcard behavior, tool-specific patterns for Read, Edit, WebFetch, MCP, and Agent rules, and the security limitations of Bash patterns, see Permission rule syntax.
permissions.ask
List the tool uses that prompt you for confirmation even in a permission mode that would otherwise approve them, such as acceptEdits or bypassPermissions. In dontAsk mode Claude Code denies a matching tool use instead of prompting.
- Scope:
Any file - Type: array of permission rule strings
- Default: unset
settings.json
permissions.deny
List the tool uses Claude Code blocks. Use it for files that hold API keys, secrets, or environment values: Claude Code excludes matching files from file discovery and search results, denies reads of them, and blocks the Edit and Write tools on the matching paths.
Read and Edit deny rules apply to Claude’s built-in file tools, to file commands Claude Code recognizes in Bash, such as cat, head, tail, sed, and tee, and to the targets of Bash redirections such as > file and < file; they don’t apply to a command that reads files without naming them, such as grep -r pattern ., or to arbitrary subprocesses, so for OS-level enforcement enable the sandbox.
- Scope:
Any file - Type: array of permission rule strings
- Default: unset
- Per-session overrides:
--disallowedToolsadds deny rules for one session alongside this key
.env files, the secrets directory, and a credentials file, and blocks curl commands:
settings.json
"*" denies every tool and "mcp__*" denies every MCP tool. Claude Code ignores a deny rule for the EndConversation tool as long as any other tool is still available to Claude. A Bash deny rule matches the command as Claude writes it, so Bash(curl *) doesn’t stop /usr/bin/curl or sh -c 'curl …'; see what a Bash rule doesn’t match. This key replaces the deprecated ignorePatterns configuration.
permissions.additionalDirectories
Give Claude file access to directories outside the one you started in, as additional working directories. Most .claude/ configuration is not discovered from these directories.
- Scope:
Any file, with limits on the sandbox write access that project and local entries give - Type: array of directory paths
- Default: unset
- Per-session overrides:
--add-dirand/add-diradd directories for one session alongside this key
settings.json
allow rules, entries in a project’s .claude/settings.json take effect only after you accept the workspace trust dialog for that folder.
permissions.blockReadsOutsideWorkingDirectories
Make Claude’s file tools refuse reads outside your working directories in every permission mode, including bypassPermissions. Claude Code denies Read, Grep, Glob, and LSP calls on those paths and tells Claude to ask you to add the directory with /add-dir. Files Claude Code itself needs stay readable, such as your skills, plugins, rules, agents, commands, and the CLAUDE.md memory file under ~/.claude/. Requires Claude Code v2.1.257 or later.
Claude Code doesn’t refuse shell commands the same way:
- Actions no mode auto-approves covers when a shell command that reads such a path prompts you
- Sandboxed commands under the block covers what a sandboxed command can read
bypassPermissions mode. The prompt appears even when the command names no path outside the working directories. This prompt doesn’t apply when the command runs in the sandbox and the sandbox enforces the block.
Claude Code also writes true here when you choose to block such reads on auto mode’s prompt before the first read outside the working directories.
- Scope:
Any file. Atruein any file applies, so a repository can turn the block on for itself but can’t lift yours. - Type: Boolean
true: Claude’s file tools refuse reads outside the working directoriesfalse: the same as unset; the block still applies if another file setstrue
- Default: unset, so reads outside the working directories follow your permission mode
settings.json
--add-dir, /add-dir, or additionalDirectories in your user or managed settings count as working directories for the block. Directories added only in repository settings don’t count: those in .claude/settings.json, and those in .claude/settings.local.json unless git reports that file as untracked. In a directory that isn’t a git repository, or when git tracks the file, Claude Code treats .claude/settings.local.json as repository settings, so put directories you want to keep readable in your user settings instead.
When autoMemoryDirectory comes from the project’s .claude/settings.json, or from a .claude/settings.local.json treated as repository-supplied, Claude Code loads no auto memory from that directory and saves none to it.
Sandboxed commands under the block
When sandboxing is on, the block also covers sandboxed commands. Claude Code denies them read access to your home directory and to the other roots that hold user files:/Users, /home, /root, /Volumes, /mnt, /media, /run/media, and /srv. It then re-opens the working directories, worktrees Claude Code creates in the session, the session temp directory, and the parts of ~/.claude that commands need, such as skills and plugins. While the block is in force, allowRead and allowWrite entries from repository settings don’t count.
When the session’s working directory is a linked git worktree, including one Claude Code entered mid-session, the repository’s common .git directory stays readable and writable to sandboxed commands, so git keeps working there.
In these cases the block doesn’t reach sandboxed commands, while Claude’s file tools keep enforcing it:
- Filesystem isolation is off through
sandbox.filesystem.disabled allowManagedReadPathsOnlyis set- The path of the directory you started Claude Code in contains a glob character such as
*,?, or[
git keeps your identity and settings:
~/.gitconfig- The
config,ignore, andattributesfiles under$XDG_CONFIG_HOME/git, which defaults to~/.config/git - Files your global git configuration names through
[include],[includeIf],core.excludesFile, orcore.attributesFile
git then runs without it. ~/.git-credentials and $XDG_CONFIG_HOME/git/credentials stay blocked.
If a re-opened file holds a secret, such as an http.extraHeader token, add its path to sandbox.filesystem.denyRead. A denyRead entry that covers a file always takes precedence over this re-open.
permissions.blockWritesOutsideWorkingDirectories
Make the Write, Edit, and NotebookEdit tools refuse paths outside your working directories in every permission mode, including bypassPermissions, apart from some of Claude Code’s own files. The key doesn’t limit shell commands, MCP tools, or the programs hooks run. To limit where shell commands write, turn on sandboxing. Requires Claude Code v2.1.314 or later.
Once the key is on, Claude Code also removes the EnterWorktree and ExitWorktree tools or refuses calls to them. To keep working in worktrees, follow Claude has no EnterWorktree tool.
- Scope:
Any file. Atruein any file the session loads applies, so a repository can turn the block on for itself but can’t lift yours. In a cloud session, Claude Code might not apply the key, because the file tools run in a container that is itself the boundary. - Type: Boolean
true: turns the block onfalse: the same as unset; the block still applies if another file setstrue
- Default: unset, so writes outside the working directories follow your permission mode. The block is also on while Claude Code can’t read the
permissionsobject in your managed settings.
settings.json
~/block-test.txt if your home directory isn’t one of them. Claude Code refuses the call, and the refusal says the setting blocks writes outside the working directories.
To lift the block, remove the key from every settings file that sets it, then restart Claude Code.
What the write block refuses and what stays writable
Some of Claude Code’s own files stay writable, such as plan files, the scratchpad, a background session’stmp directory, and .md files in this project’s auto memory.
Along with your own files outside the working directories, the block refuses writes to:
- Claude Code settings files: Claude Code refuses these writes inside the working directories too, because a settings file can lift the block. Edit settings files yourself.
- A directory that only repository settings add: one that
additionalDirectorieslists only in.claude/settings.json, or in.claude/settings.local.jsonunless git reports that file as untracked - A subagent’s worktree: an
isolation: worktreesubagent’s file edits are refused when its worktree sits outside the working directories - Auto memory in a directory the repository chose: a directory that
autoMemoryDirectorynames in repository settings
/add-dir needs a directory that exists, so name the .claude/worktrees directory at the repository root for subagent worktrees.
Let one directory through the read or write block
To let Claude reach one directory outside the project whileblockReadsOutsideWorkingDirectories or blockWritesOutsideWorkingDirectories is true, add it as a working directory. Run /add-dir <directory> in the session, pass --add-dir <directory> when you start Claude Code, or list it under additionalDirectories in your user or managed settings. No allow rule lets Claude’s file tools through either block.
permissions.defaultMode
Set the default permission mode for new sessions. When you leave it unset, the built-in default for your surface applies.
- Scope:
Any file.autoandbypassPermissionsdon’t take effect from project or local settings, so set them in~/.claude/settings.jsoninstead. Before v2.1.257,bypassPermissionstook effect from any file. For conversations the VS Code extension starts, Claude Code reads only user, managed, and--settingsvalues. - Type: string, one of:
"default": Claude Code runs only reads without asking"acceptEdits": Claude Code also runs file edits and common filesystem commands such asmkdirandmvwithout asking"plan": Claude Code reads and plans but blocks edits until you approve a plan"auto": Claude Code runs without routine prompts; before actions such as shell commands and network requests run, a background classifier checks that they align with your request"dontAsk": Claude Code auto-denies every call that would otherwise prompt, though a mod you installed can still approve some of those calls. File reads inside your working directories, other actions that need no approval, and pre-approved tools still run, apart from reads from network paths"bypassPermissions": Claude Code runs everything without asking"manual": an alias for"default"
- Default: unset
- Per-session overrides:
--permission-mode, and its equivalent--dangerously-skip-permissionsforbypassPermissions, take precedence over this key for one session
settings.json
deny rules block in every mode, including bypassPermissions. See Permission modes. In cloud sessions, Claude Code honors only acceptEdits, plan, default, and auto from this key. For conversations the VS Code extension starts, see which setting the extension reads for the starting permission mode.
permissions.denyInsteadOfPrompting
Set this to true to keep a session running when nobody is there to answer a permission prompt. Claude Code denies a tool call that would otherwise wait on a prompt, and the turn continues. Requires Claude Code v2.1.319 or later.
A call goes ahead if an allow rule, your permission mode, or auto mode’s classifier approves it. To allow most calls that would otherwise prompt, answer from a PermissionRequest hook.
- Scope:
User or managed, and--settings. A repository can’t set it for you. - Type: Boolean
true: Claude Code denies calls that would otherwise promptfalse: the same as unset; calls are still denied if another of these sources setstrue
- Default: unset, so a call that needs approval prompts you
~/.claude/settings.json, this example starts sessions in auto mode and denies whatever would still fall back to a prompt:
settings.json
-p runs, interactive terminal sessions, the VS Code extension, local sessions in the Desktop app, subagents, and agent teams. To deny what would prompt in a single non-interactive run instead, pass --permission-prompts none with -p.
What else denyInsteadOfPrompting stops
With the setting on, Claude Code also stops these requests for an answer:
- Question and plan tools: Claude Code leaves out
AskUserQuestion,EnterPlanMode, andExitPlanMode, so a session in plan mode can’t leave it on its own. A teammate in an agent team keepsEnterPlanModeandExitPlanMode - MCP elicitation: Claude Code cancels an elicitation request unless an
Elicitationhook answers it - Permission hosts: Claude Code doesn’t ask your
canUseToolcallback or--permission-prompt-tool. To approve calls from code, answer from aPermissionRequesthook. Some calls are denied before any hook is asked, such as a critical-path removal inautomode that no ask rule covers. - Classifier billing notice: where the notice about billed classifier requests would open a dialog, Claude Code doesn’t show it and denies the actions that need those requests
Messages from denyInsteadOfPrompting
These messages report refused calls. They aren’t prompts, so nothing waits for your answer.
The denial Claude reads can open with this text:
stream-json output, the runs that emit a permission_denied message report this decision_reason:
-p run reports that turn as error_during_execution.
permissions.disableBypassPermissionsMode
Prevent anyone from entering bypassPermissions mode. Claude Code then rejects the --dangerously-skip-permissions flag, and ignores an agent definition’s permissionMode: bypassPermissions, so the subagent runs with the parent session’s permission mode.
- Scope:
Any file. Typically set in managed settings to enforce organizational policy. - Type: the string
"disable" - Default: unset
- Per-session overrides: this key takes precedence over
--dangerously-skip-permissions, which Claude Code rejects while the key is set
settings.json
skipAutoPermissionPrompt
Skip the one-time notice describing auto mode that Claude Code shows when you first enter auto mode yourself, for example through your own settings or the mode selector, rather than when the built-in default starts a session in it. Claude Code shows that notice once and then records that it was shown, so this key only matters where the notice hasn’t appeared yet.
- Scope:
User or managed. A repository can’t set it for you. - Type: Boolean
true: Claude Code skips the noticefalse: the same as unset; the notice appears once unless another of these files setstrue
- Default: unset, so the notice appears once
settings.json
skipDangerousModePermissionPrompt
Skip the confirmation dialog Claude Code shows before a session enters bypassPermissions mode, whether from --dangerously-skip-permissions or from defaultMode: "bypassPermissions". Claude Code writes true here in your user settings when you accept that dialog once.
- Scope:
User, local, or managed, and files passed with--settings. Background sessions count only user and managed settings. An untrusted repository can’t skip the dialog for you. - Type: Boolean
true: Claude Code skips the confirmation dialog before a session entersbypassPermissionsmodefalse: the same as unset; the dialog appears unless another of these files setstrue
- Default: unset, so the dialog appears
settings.json
Sandbox settings
Isolate the commands Claude runs from your filesystem, your network, and your credentials. For how sandboxing works and platform requirements, see Sandboxing.sandbox
Isolate the Bash commands Claude runs from your filesystem and network with sandboxing. Turn the sandbox on with enabled, then narrow or widen what sandboxed commands can touch with the filesystem, network, and credentials sub-objects. The sandbox runs on macOS, Linux, and WSL2.
- Scope:
Any file - Type: object with
enabled,failIfUnavailable,autoAllowBashIfSandboxed,excludedCommands,allowUnsandboxedCommands,enableWeakerNestedSandbox,enableWeakerNetworkIsolation,allowAppleEvents,allowNestedUserNamespaces,bwrapPath,socatPath,ignoreViolations, andripgrep, plus thefilesystem,network, andcredentialsobjects - Default: unset, so Claude Code runs commands without a sandbox
docker outside the sandbox, opens two extra write paths, hides your AWS credentials file, and pre-allows GitHub and npm:
settings.json
enabled or failIfUnavailable, that value overrides anything a developer sets. Claude Code merges array keys across the settings scopes the session loads, so a developer can append entries; see Keep developers from widening the policy for the managed-only locks. To require the sandbox for an organization, see Enforce sandboxing with managed settings.
sandbox.enabled
Turn on sandboxing for Bash commands. When you pick a mode in the /sandbox panel, Claude Code writes this key to .claude/settings.local.json for the current project; set it in ~/.claude/settings.json to sandbox every project.
- Scope:
Any file, with limits on project and local settings - Type: Boolean
true: Claude Code sandboxes Bash commandsfalse: Bash commands run unsandboxed
- Default:
false
settings.json
bubblewrap and socat; see Set up Linux and WSL2. When the sandbox can’t start, Claude Code runs commands unsandboxed unless you also set failIfUnavailable.
sandbox.failIfUnavailable
Make Claude Code exit with an error at startup when sandbox.enabled is true but the sandbox can’t start because the platform doesn’t support it or the dependency check fails. Without this key, Claude Code runs commands unsandboxed. Managed deployments that require sandboxing as a security gate can use this setting.
On a platform the sandbox doesn’t support, Claude Code doesn’t start with this key on. See Enforce sandboxing with managed settings.
- Scope:
Any file, with limits on project and local settings - Type: Boolean
true: Claude Code exits with an error at startup whensandbox.enabledistruebut the sandbox can’t start. If the sandbox passes that check and then fails to initialize, the session keeps running and Claude Code refuses each sandboxed commandfalse: Claude Code runs commands unsandboxed when the sandbox can’t start
- Default:
false
failIfUnavailable to true:
managed-settings.json
sandbox.autoAllowBashIfSandboxed
Let Claude Code run sandboxed Bash commands without a permission prompt. Commands that can’t run in the sandbox still go through the regular permission flow, and deny rules and content-scoped ask rules such as Bash(git push *) still apply; a bare Bash ask rule is skipped for sandboxed commands. Set it to false to send sandboxed commands through the regular permission flow too, which the /sandbox Mode tab calls regular permissions mode.
- Scope:
Any file - Type: Boolean
true: Claude Code runs sandboxed Bash commands without a permission prompt, except in the cases that Auto-allow mode describes;CLAUDE_CODE_SUBPROCESS_ENV_SCRUBturns auto-allow offfalse: sandboxed commands go through the regular permission flow, so your allow rules and permission mode decide. The/sandboxMode tab calls this regular permissions mode
- Default:
true
settings.json
sandbox.excludedCommands
Name commands that Claude Code runs outside the sandbox, such as tools that don’t work under it. Each entry uses the same syntax as the content of a Bash(...) permission rule: an exact command, a prefix such as docker *, or a wildcard pattern. A pattern with no wildcard is an exact match, so docker matches only docker with no arguments.
Your entries take a Bash call out of the sandbox only when they cover every command in it, and some call shapes stay sandboxed even then. A docker * entry alone doesn’t take npm ci && docker build . out of the sandbox.
- Scope:
Any file, with limits on project and local settings - Type: array of command patterns
- Default: unset, so no command is excluded
settings.json
- A command starting with
sudo,eval, orxargs - A
cd,pushd, orpopd, wherever it appears in the call - A command substitution, a subshell, or a control-flow block such as
iforfor - A redirection, such as
docker build . > build.logor a<<EOFheredoc, other than one that only duplicates a file descriptor, as2>&1does - A command name that comes from a variable
- A
git clone,git init,git worktree add,git worktree move, orgit bundle createwith a path argument that is absolute, starts with~, or contains a..segment
cd build && docker compose up stays sandboxed under a docker * entry, and adding a cd entry doesn’t change that. Under a git * entry, git clone <url> vendor/lib runs outside the sandbox, but git clone <url> ~/tools stays sandboxed. A clone writes a whole tree of files, possibly executable ones, wherever its destination path points.
Excluded commands still go through the regular permission flow. Exclusion is a convenience, not a security boundary: when a tool only needs to write somewhere specific, filesystem.allowWrite keeps it sandboxed.
Entries from the settings scopes the session loads combine into one list unless the sandbox is admin-required. While it is, Claude Code ignores entries in .claude/settings.json and .claude/settings.local.json, so a cloned repository can’t take commands out of the sandbox. Entries in managed settings, --settings, and your ~/.claude/settings.json still apply, and no managed-only lock covers this list.
sandbox.allowUnsandboxedCommands
Let Claude retry a command outside the sandbox with the dangerouslyDisableSandbox parameter after the sandbox blocks it. When it’s false, Claude Code ignores that parameter. While the sandbox is running, commands Claude runs are then sandboxed unless they match an excludedCommands entry. The /sandbox Overrides tab shows that state as Strict sandbox mode. A false in managed settings turns on strict sandbox mode for the developers it covers.
- Scope:
Any file, with a limit on project and local settings - Type: Boolean
true: Claude can retry a command outside the sandbox with thedangerouslyDisableSandboxparameter after the sandbox blocks itfalse: Claude Code ignores that parameter, so while the sandbox is running, commands Claude runs are sandboxed unless they match anexcludedCommandsentry
- Default:
true
managed-settings.json
false from managed settings or --settings also makes the sandbox admin-required. A false in your user settings holds against a project’s true but doesn’t make the sandbox admin-required. Holding against a project’s value requires Claude Code v2.1.285 or later.
Who approves an unsandboxed retry depends on your permission mode and allow rules. See The unsandboxed retry escape hatch.
To see when commands you type yourself at the ! shell-mode prompt run sandboxed, see strict sandbox mode.
sandbox.filesystem
Control which paths sandboxed commands can read and write. By default they can write to the working directory, the per-user temp directory, and directories you add with --add-dir, /add-dir, or permissions.additionalDirectories, and can read the rest of the filesystem, including credential files. Widen or narrow that with the four path lists, or switch the filesystem layer off with disabled. See Filesystem isolation for the default boundaries.
- Scope:
Any file - Type: object with
allowWrite,denyWrite,denyRead, andallowReadarrays, plus theallowManagedReadPathsOnlyanddisabledBooleans - Default: unset, so the default read and write boundaries apply
settings.json
kubectl, terraform, or npm. Claude Code adds your permission rules to the same lists: Edit allow and deny rules to allowWrite and denyWrite, Read deny rules to denyRead, and WebFetch(domain:...) allow and deny rules to the network domain lists.
Unless a lock applies, Claude Code merges these lists across the settings files the session loads. allowManagedReadPathsOnly limits allowRead to entries from managed settings, and allowManagedDomainsOnly does the same for allowed domains. Repository locks leave out entries from a repository’s settings files.
Configure sandboxing covers sources you exclude with --setting-sources. When you edit a list during a session, Claude Code applies the change to the running session.
Sandbox path prefixes
Paths inallowWrite, denyWrite, denyRead, allowRead, and credentials.files resolve by their prefix:
The
//path prefix for absolute paths also works. If you use single-slash /path expecting project-relative resolution, switch to ./path. This syntax differs from Read and Edit permission rules, which use //path for absolute and /path for project-relative: sandbox filesystem paths use standard conventions, so /tmp/build is an absolute path.
Claude Code strips a trailing slash from a directory path, so ~/.aws and ~/.aws/ match the same directory. Before v2.1.224, Claude Code passed the trailing slash through to the sandbox, and Claude could still read or write paths under a denyRead or denyWrite entry written with one.
Where wildcards work in sandbox paths
The wildcards*, ?, and ** work in all four sandbox.filesystem path lists on macOS and in fewer places on Linux and WSL2:
In
~/keys/*.pem, the wildcard comes after the first directory name, which is home for a home directory of /home/alice:
/sandbox in a session warns about Edit permission rules that contain a wildcard other than a trailing /**. Those wildcards don’t work for sandboxed commands. Add each path the rule should cover, or the directory that holds them, to allowWrite for an allow rule or denyWrite for a deny rule.
Directory names with brackets, braces, or parentheses
To allow or block a directory whose name contains brackets, write the name as it is, such as./app/[slug]. In that entry, [slug] is the directory’s real name, brackets included:
/**. On macOS and on Linux and WSL2, the app/[slug] directory has to exist when the sandboxed command starts.
- Brackets such as
[slug]: in every list on macOS, and indenyReadandallowReadon Linux and WSL2, the brackets in./app/[slug]are also a pattern. The entry then also matches any path underappnamed with one character fromslug, such asapp/sorapp/g. With that entry inallowRead, or inallowWriteon macOS, sandboxed commands can reach those paths as well. Rename any they shouldn’t reach. - Brackets such as
[user-id]or[post-id], where the hyphen’s left character sorts after its right:./app/[user-id]covers only the directory with exactly that name, in every list on every platform. Before v2.1.304, sandboxed commands on Linux and WSL2 failed to start whiledenyReadorallowReadheld such an entry. - Braces and parentheses: these are ordinary characters, so
~/data/{keys,tokens}covers one directory named{keys,tokens}, not two alternatives. To cover~/data/keysand~/data/tokens, add each as its own entry.
sandbox.filesystem.allowWrite
Add paths where sandboxed commands can write, beyond the working directory, the per-user temp directory, and the directories you’ve added with --add-dir, /add-dir, or permissions.additionalDirectories. Use it when a subprocess such as kubectl or a build tool needs to write outside the project.
- Scope:
Any file, with limits on project and local settings - Type: array of path strings, using the sandbox path prefixes
- Default: unset, so sandboxed commands can write to the working directory, the per-user temp directory, directories you’ve added with
--add-diror/add-dir, and directories inpermissions.additionalDirectories
/tmp/build and lets kubectl update your kubeconfig:
settings.json
allowWrite entries and the paths from your Edit(...) allow permission rules across the settings scopes the session loads, leaving out the ones from repository settings while permissions.blockReadsOutsideWorkingDirectories is on. Repository locks can leave out a repository’s entries too. An allowWrite entry can’t lift a protected path.
sandbox.filesystem.denyWrite
Block sandboxed commands from writing to specific paths, including paths inside a directory that is otherwise writable.
- Scope:
Any file - Type: array of path strings, using the sandbox path prefixes
- Default: unset
settings.json
Edit(...) deny permission rules.
sandbox.filesystem.denyRead
Block sandboxed commands from reading specific paths, such as credential files that the default read policy would otherwise expose. To protect a credential file and keep it usable through the sandbox proxy, see sandbox.credentials instead.
- Scope:
Any file - Type: array of path strings, using the sandbox path prefixes
- Default: unset, so sandboxed commands keep the default read access, which includes credential files such as
~/.aws/credentials
settings.json
Read(...) deny permission rules. When filesystem.disabled is true, Claude Code doesn’t enforce these entries.
sandbox.filesystem.allowRead
Re-open reading for specific paths inside a region that denyRead blocks, to build workspace-only read access. An exact or wildcard denyRead entry stays blocked inside