CC-201a · Module 2

settings.json vs settings.local.json

3 min read

Claude Code uses two settings files that serve complementary purposes. settings.json lives in .claude/ and should be committed to version control. It contains the shared team configuration: permission allowlists, denylists, hook definitions, and environment settings that every developer needs. settings.local.json lives alongside it but is gitignored. It contains personal overrides: your specific permission tightening, local paths, API keys for personal tools, and any settings you do not want to impose on the team.

The merge behavior is additive for deny rules and override for accept rules. If settings.json denies rm -rf and settings.local.json tries to accept it, the deny wins. If settings.json accepts tsc and settings.local.json adds a gate for tsc, the local gate takes effect. This asymmetry is intentional — the team can set floors that individuals cannot breach, while individuals can add restrictions the team did not mandate. The security model is: shared settings define the minimum, local settings refine on top.

Do This

  • Commit settings.json with team-agreed permission profiles and hook definitions
  • Add settings.local.json to .gitignore so personal configs stay local
  • Put API keys and personal paths in settings.local.json only
  • Document what goes where in your project CLAUDE.md

Avoid This

  • Commit settings.local.json — it contains personal overrides that break for other developers
  • Put team permissions in settings.local.json — no one else will see them
  • Put API keys in settings.json — they will be committed to version control
  • Rely on verbal agreements about permissions — encode them in settings.json