In the last lesson you picked a mode — an overall level of trust. Permission rules are finer: they say which specific actions Claude may take without asking, and which are always off-limits.
What a rule looks like
Rules live in the permissions block of a settings file:
{
"permissions": {
"allow": ["Bash(npm test)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
allow— what is fine without asking: here, runningnpm test;deny— what is never allowed: here, reading.envfiles, where secrets live.
Inside a session, /permissions shows the rules currently in force, and /status shows which settings files were picked up.
Which file applies to whom
This is the key point. The same rule means different things in different files:
| File | Applies to | What goes here |
|---|---|---|
~/.claude/settings.json | you, in every project | your personal habits |
.claude/settings.json (committed) | the whole team in the project | shared rules: what must not be read, which commands are allowed |
.claude/settings.local.json (not in git) | you, in this project | your exceptions |
| managed settings | the whole organization | policy that cannot be overridden |
When you answer “Yes, and don’t ask again” to a command, the permission is saved in settings.local.json — your personal exception, not a team rule.
Who wins
If one key is set in several files, the higher level wins: managed settings, then the command line, then local, then the shared project file, then user. But rule lists — allow, deny — do not overwrite each other; they add up.
Within the rules, the order is fixed: first deny, then ask, then allow, and the first match decides. That is why a deny cannot be accidentally overridden by an allow in another file.
Quick check
You want nobody on the team to be able to have Claude read .env. Where does the deny rule go?
Careful
The Read(./.env) rule stops Claude’s read tools and familiar commands like cat, but not a script that opens the file itself. Closing that gap fully is what the sandbox is for — the next lesson. And none of this makes secrets in the repository safe: .env still does not get committed.
Practice in the terminal
Build your own file
In the settings builder, tick what Claude may do without asking and what it may never do, and you get a ready settings.json with a note on every line.