Claude Code settings.json: Full Configuration Guide

Claude Code settings.json: Full Configuration Guide

If you have spent more than a few days using Claude Code, you have hit a wall at some point: a command that kept asking for permission, a tool you wanted blocked, or a preference that reset every time you opened a new project. The answer to all of that lives in one file: Claude’s code settings.json. Once I understood how this file actually works, my workflow got a lot cleaner. No more clicking through confirmation dialogs for commands that I run fifty times a day.

This guide walks through everything you need to know about the scope system, the key settings, and how permissions actually behave without burying you in enterprise-only features you will never touch.

[IMAGE: screenshot of claude code settings.json file open in a code editor with permission rules visible]

What Is claude code settings.json and Why Does It Matter

The settings.json file is Claude Code’s official configuration mechanism. It is a plain JSON file that controls how Claude Code behaves, what tools it can use, what commands it can run, which files it can read, and what environment variables it sees in every session.

You do not have to edit this file to use Claude Code. But if you do not, you are leaving a lot of default behaviour in place that might not match how you actually work.

I think of this file the same way I think of a .bashrc or a VS Code settings.json. It is optional until it is not. The moment you find yourself clicking “Allow” on the same command for the fifth time in a row, it becomes essential.

The file lives in a few different places depending on what you want it to control. That is where the scope system comes in.

Understanding Configuration Scopes: Where Your Settings Actually Live

This is the part most people skip, and it causes real confusion. Claude Code does not have one single settings.json. It has several, and they stack on top of each other in a specific order.

ScopeFile LocationWho It AffectsShared With Team?
ManagedSystem-level deploymentAll users on the machineYes (IT deployed)
User~/.claude/settings.jsonYou, across all projectsNo
Project.claude/settings.jsonEveryone on the repoYes (committed to git)
Local.claude/settings.local.jsonYou, in this project onlyNo

The User scope is where I put things like tool preferences and personal permission rules. It applies everywhere I work, so I am not re-configuring the same things project by project.

The Project scope is what you commit to your repo. If you want your whole team to allow a specific npm command without prompting, that goes here. It gets checked into source control, so everyone who clones the project gets the same behaviour.

How Precedence Actually Works

When the same setting appears in multiple scopes, more specific scopes win. Project beats User. Local beats Project. Managed beats everything and cannot be overridden by anyone; that is the enterprise IT version.

So if your user settings allow Bash(npm run *) but the project’s shared settings deny it, the project setting wins. The command gets blocked. This tripped me up early on. I kept wondering why my global permission was being ignored until I checked the project-level file.

[IMAGE: diagram showing claude code settings.json scope hierarchy from managed down to user level]

The Key Settings Inside claude code settings.json

Once you understand scopes, the actual settings are pretty straightforward. Here are the ones I use and actually care about.

permissions: This is the big one. You define which tools Claude can use freely, which ones need confirmation, and which ones are blocked entirely; more on this in the next section.

env: Any environment variables you set here get applied to every Claude Code session. Useful for telemetry flags or custom API configurations you do not want to set each time manually.

model: You can override the default model used for Claude Code. If your team wants everyone on the same model version, put it here in the project scope.

cleanupPeriodDays: Controls how long session transcripts are kept before deletion. Defaults to 30 days. Set it to 0 if you want transcripts deleted immediately and no session persistence at all.

Language: Claude will respond in your preferred language if you set this. Works across all sessions without you having to specify it in each prompt.

One setting I actually use day-to-day is autoUpdatesChannel. Setting it to stable means I get the version that has been out for about a week and has had any major regressions caught. The default latest gives you the freshest release, which is fine, but I have had a couple of weird bugs from jumping on day-one releases.

Setting Up Permissions in claude code settings.json

Permissions are the most practical part of this whole configuration system. If you set these up well, Claude Code gets noticeably less disruptive to use.

The permissions key takes three arrays: allow, ask, and deny. Rules are evaluated in order to deny first, then ask, then allow. The first matching rule wins. That order matters more than most people realize.

Here is what a basic permissions block looks like:

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)"
    ],
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./.env.*)"
    ]
  }
}

The deny rules for .env files are ones I add to every project. Claude does not need to read my API keys to help me write code, and keeping them out of context is just good practice.

Permission Rule Syntax Explained

Rules are written in the format Tool or Tool(specifier), where the specifier can include wildcards using *.

For example, Bash(npm run *) will match any command that starts with npm run, while just Bash on its own applies to every Bash command. You can also narrow things down, for instance, WebFetch(domain:example.com) restricts requests to that specific domain.

One thing that surprised me: Bash permission rules have real limitations when it comes to complex shell syntax. Chained commands with && or pipes do not always match the way you expect. If you are running something like npm install && npm run build, test the permission against both parts of the chain.

The additionalDirectories key under permissions is also worth knowing about. By default, Claude Code can only access your working directory. If your project references files in a sibling folder, you need to add it here explicitly.

How to Configure claude code settings.json for Your Workflow

Learning how to configure Claude’s code settings.json well really comes down to one habit: start with your most common friction points and work from there.

If Claude keeps asking permission for a command you run constantly, add it to allow in your User scope. If you are setting up a new project for a team, create a .claude/settings.json in the repo with shared allow rules for your standard build and test commands, and shared deny rules for anything sensitive.

You can verify what settings are active at any time by running /status inside Claude Code. It shows you every configuration layer and where each setting is coming from. When something is not behaving the way you expect, /status is the first place I look.

To edit settings interactively without touching the file directly, the /config command opens a tabbed settings interface right inside the Claude Code REPL. You can make changes there, and they write back to the appropriate file automatically.

Excluding Sensitive Files From Claude Code Access

This deserves its own section because I see people miss it. By default, Claude Code can read files in your project directory, including .env files, credential configs, and anything else sitting in the root.

You fix this with deny rules in your permissions block:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Put this in your User scope if you want it everywhere. Put it in the project scope if you want it committed to the repo so your whole team gets it. Either way, make this a habit before it becomes a problem.

Conclusion

The Claude code settings.json file is one of those things that looks optional until you realize how much friction it can eliminate. The scope system doesn’t take long to understand. Give it ten minutes, and it starts to click. After that, the configuration model feels a lot more natural; you’re not juggling one global config, just a set of layers that apply in the right places.

I recommend starting with your User scope. Add deny rules for your .env files today. Add allow rules for the three or four commands you run constantly. Then, when you set up your next team project, create a project-scope file with whatever your team’s shared baseline should be.

That is the shift worth making. Stop clicking through permission prompts. Put it in the file once, and move on.

Frequently Asked Questions

What is the difference between the User scope and Project scope in claude code settings.json?

The User scope lives at ~/.claude/settings.json and applies to everything you do in Claude Code across all your projects. Think of it as two layers. The User scope is your personal setup for your global config. The Project scope sits inside the repo at .claude/settings.json, and since it’s checked into source control, everyone on the team ends up using the same settings. If something is defined in both places, the project version takes priority. In practice, I keep personal preferences in the User scope, and anything the team should share, like allowed commands or file restrictions, goes into the Project scope.

How do I stop Claude Code from reading my .env files?

Add a deny rule to your permissions block inside your settings.json. The rule looks like this: "Read(./.env)" and "Read(./.env.*)" to cover variants like .env.local or .env.production. You can put this in your User scope so it applies to every project, or in the Project scope so it is version-controlled with the repo. Either way, Claude Code will refuse to read those files once the rule is in place. It is one of the first things I configure on any new setup.

Can I use environment variables inside claude code settings.json?

Yeah, the env key is basically for setting environment variables across all sessions. You define it as a plain JSON object with key-value pairs. For example, "env": { "MY_VAR": "value" } means that the variable is always set when Claude Code runs. Useful for stuff you don’t want to keep configuring, like telemetry or API-related settings. It saves you from setting them manually in your shell profile and keeps them scoped specifically to Claude Code sessions rather than your whole terminal environment.

What happens if I make a mistake in my settings.json file?

Claude Code automatically creates timestamped backups of your configuration files and keeps the five most recent versions. So if you break something, you can recover a recent working copy. You can also run /status inside the Claude Code REPL to see which settings are currently active and whether there are any errors in your configuration files. The status output will flag parsing errors directly, which makes diagnosing problems much faster than guessing what went wrong.

Do I need to restart Claude Code after editing settings.json?

Generally speaking, changes to settings.json take effect when Claude Code picks up the file again. For session-level changes, starting a new session is the safest way to confirm your edits are active. The /config command inside the REPL also writes changes back to the file in real time, so if you make edits through that interface, they apply without manually restarting anything.

Leave a Comment

Your email address will not be published. Required fields are marked