The Claude Code Permission System
How settings.json and settings.local.json control what Claude can do autonomously, and how to build a permission setup that works for your team.
The problem with approving everything
Every time Claude Code wants to run a command or fetch a URL, it asks. That's the safe default. But if you're running the same web fetch to the Anthropic docs every session, approving it manually each time isn't safety, it's friction. And if you never want Claude touching a specific tool at all, a one-time denial doesn't stick.
The permission system is how you move from reactive approvals to a deliberate policy. Once it's configured, Claude operates inside the rules you set without interrupting you to confirm what you already decided.
How the settings files work
Claude Code stores permission rules in JSON files inside the .claude folder of your project, the same folder that holds your custom commands.
Two files control permissions:
| File | Who creates it | What it's for |
|---|---|---|
settings.json | You, manually | Shared rules committed to the project. Applies to everyone working in the repo. |
settings.local.json | Claude, automatically | Your personal rules for this machine. Not committed. Stays local. |
The first time Claude needs to fetch a URL and you choose "Yes, don't ask me again," Claude creates settings.local.json for you and writes the rule there. You don't have to set up the file from scratch. It generates on first use.
Both files have the same structure: an allow array and a deny array. Claude checks both before running any tool.
The allow list
The allow list tells Claude which tools and commands it can run without asking you first.
Here's what that looks like after approving web fetch access for the Anthropic docs domain:
{
"allow": [
"WebFetch(domain:docs.anthropic.com)"
]
}
Claude will fetch from that domain freely. It won't pause to ask permission.
Patterns make the allow list practical. Suppose you're working with shadcn/ui and you want Claude to add any component without prompting you each time. The first approval only allows the specific component you approved, say shadcn add label. That's too narrow. Edit the entry to use a wildcard pattern:
{
"allow": [
"Bash(shadcn add *)"
]
}
Now Claude can add any shadcn component without a prompt.
The same logic applies to documentation sources. If you regularly reference library docs, add those domains once. They're allowed from then on.
You can also ask Claude to build the allow list for you. Because Claude can read and write the settings files directly, you can prompt it to generate the rules: "Add an allow rule so you can always fetch from the Tailwind docs without asking." Claude writes the entry, and that rule is in place for every future session.
> For multi-client operators. Keep settings.json lean and project-specific. Your settings.local.json can hold personal preferences that apply to how you work on your machine, regardless of which client folder you're in.
The deny list
The deny list is the mirror image of the allow list. Tools or commands in the deny array are blocked outright, no prompt, no override.
{
"allow": [],
"deny": [
"WebFetch(domain:docs.anthropic.com)"
]
}
Moving an entry from the allow array to the deny array is all it takes. Claude will refuse to run that tool, in any session, until you remove the rule.
The deny list is where you set hard constraints. If there's a domain you never want Claude fetching from, or a shell command that has no business running in a client engagement, deny it explicitly. This is different from just not approving something when asked. A deny rule is persistent policy.
How the permission system grows with your work
When you start a new project, neither file exists. That's expected. As you work through sessions, you'll approve and deny actions. The files grow to reflect how you actually operate.
This is not a one-time configuration task. It's an ongoing record of decisions you've already made. The practical pattern:
1. Start a session, work normally 2. When Claude requests permission for something you'll always allow, choose "Yes, don't ask again" 3. settings.local.json updates automatically 4. For patterns broader than the specific command, edit the file to use a wildcard 5. For anything you want to block permanently, add it to the deny list manually
Over time, Claude operates more fluidly inside the boundaries you've established. Fewer interruptions on routine tasks, clearer guardrails on anything sensitive.
> You can inspect and edit both files at any time. They're plain JSON. Open them in any text editor or ask Claude to show you the current rules. If a rule is causing unexpected behavior, reading the file usually makes it obvious.
Permission rules in a team context
settings.json is version-controlled. If you commit it to a shared repository, every operator on the project inherits the same rules. That's useful for client engagements where you want consistent behavior across contributors.
Common patterns for shared settings.json in a client engagement:
- Allow fetching from your client's internal documentation host
- Allow the CLI tools the project always uses (package managers, build commands)
- Deny web fetch to domains that have no place in this engagement
settings.local.json stays off the repo. Your personal tool preferences, the documentation domains you reference constantly, the commands you run in every session, those belong in the local file. Shared rules stay in the committed one.
> One rule of thumb: If you'd want a new team member to have the same behavior from day one, it goes in settings.json. If it's specific to how you personally work, it goes in settings.local.json.
What this means for how you work
The permission system is not a formality. It's a workflow tool.
Every operator running Claude Code across multiple client engagements will hit the same friction: approving the same things repeatedly, or discovering that Claude wandered somewhere it shouldn't have. The allow and deny lists solve both problems. You approve once, you deny once, and then you stop thinking about it.
The payoff compounds. The longer you work in Claude Code, the more your settings files reflect a refined version of your working judgment. New sessions start with all of that already in place.