settings.json 버전 관리와 팀 규칙 전파
팀에서 Claude Code를 쓸 때 가장 흔한 실패는 "내 기계에서는 잘 되는데 동료 기계에서는 권한 프롬프트가 계속 뜬다"이다. 원인은 거의 항상 설정을 잘못된 층에 두었기 때문이다. Claude Code의 설정은 하나의 파일이 아니라 여러 층위의 JSON 파일이 정해진 우선순위로 병합되는 시스템이고, 팀 운영의 본질은 "어떤 규칙을 어느 층에 두어 어떻게 전파하느냐"의 설계다. 이 절은 그 설계의 정답을 다룬다.
설정 파일의 네 층위
Claude Code가 읽는 설정 파일은 위치에 따라 역할이 다르다. 네 가지를 구분해야 한다.
사용자(user) 설정은 ~/.claude/settings.json에 있고, 그 사용자가 작업하는 모든 프로젝트에 공통으로 적용된다. 내 개인 취향(테마, 자주 쓰는 모델 등)을 두는 자리다.
프로젝트 공유(project shared) 설정은 저장소 안의 .claude/settings.json에 있다. 이 파일이 팀 규칙 전파의 핵심이다. git으로 추적되어 저장소를 clone한 모든 팀원에게 동일하게 적용된다. 팀 전체가 따라야 할 권한 정책, 공통 환경 변수, 훅, 모델 지정을 여기에 둔다.
프로젝트 로컬(project local) 설정은 .claude/settings.local.json에 있다. 같은 저장소 안에 있지만 개인용이다. Claude Code가 이 파일을 자동으로 .gitignore에 추가하므로 커밋되지 않는다. 내가 이 프로젝트에서만 임시로 허용하고 싶은 권한처럼, 동료에게 강요하면 안 되는 개인 설정을 둔다.
엔터프라이즈 관리(enterprise managed) 설정은 조직 IT가 기기에 배포하는 파일로, 운영체제별 시스템 경로에 놓인다. 개발자가 끄거나 덮어쓸 수 없는 조직 강제 정책의 자리다.
우선순위: 충돌하면 누가 이기는가
같은 설정 키가 여러 층에 동시에 있으면 우선순위가 높은 층이 이긴다. 이 순서를 외워야 한다.
엔터프라이즈 관리 설정 > CLI 인자(세션 한정) > 프로젝트 로컬(settings.local.json) > 프로젝트 공유(settings.json) > 사용자(~/.claude/settings.json).
시험은 이 순서를 직접 묻거나, 시나리오로 비튼다. 예를 들어 "조직 관리 설정이 Bash(rm:*)를 deny로 막았는데, 개발자가 자기 settings.local.json에서 같은 명령을 allow로 풀었다. 결과는?" 정답은 "여전히 막힌다"이다. 관리 설정이 가장 위에 있어 개인 설정으로 뚫을 수 없기 때문이다. 반대로 "팀 공유 settings.json이 어떤 도구를 ask로 두었는데 개인이 local에서 allow로 바꿨다"면, 로컬이 공유보다 우선하므로 그 개발자에게는 프롬프트 없이 실행된다. 우선순위 표를 기계적으로 적용하는 것이 이 유형의 정답 도출법이다.
무엇을 공유에 두고 무엇을 로컬에 두는가
팀 규칙 전파의 실무 원칙은 단순하다. 모두가 따라야 하는 것은 settings.json(공유, git 추적), 나만 쓰는 것은 settings.local.json(로컬, git 무시)이다.
아래는 팀 공유용 .claude/settings.json의 예다. 권한 정책과 공통 환경, 모델을 한곳에 모아 커밋한다.
// .claude/settings.json{ "model": "claude-opus-4-8", "permissions": { "allow": [ "Bash(npm run test:*)", "Bash(npm run lint:*)", "Read(./src/**)" ], "ask": [ "Bash(npm run deploy:*)" ], "deny": [ "Read(./.env)", "Read(./secrets/**)", "Bash(rm -rf:*)" ] }, "env": { "PROJECT_REGION": "ap-northeast-2" }}
이 파일을 커밋하면 저장소를 clone한 모든 팀원이 같은 권한 정책과 같은 모델 설정으로 Claude Code를 쓰게 된다. 테스트·린트는 자동 허용되어 프롬프트가 사라지고, 배포는 매번 확인을 받으며, .env와 시크릿 폴더 읽기는 누구에게나 차단된다. 이것이 "버전 관리되는 파일에 규칙을 넣어 전파한다"의 실체다.
개인 설정은 별도 파일에 둔다.
// .claude/settings.local.json{ "permissions": { "allow": [ "Bash(docker compose up:*)" ] }}
이 파일은 Claude Code가 자동으로 .gitignore에 넣어 커밋되지 않는다. 그래서 내 로컬 도커 명령 허용이 동료의 환경을 오염시키지 않는다.
시험이 노리는 함정
가장 자주 나오는 함정은 settings.local.json을 커밋해 버리는 시나리오다. "팀 규칙을 모두에게 적용하려고 settings.local.json에 권한을 넣고 git에 올렸는데 동료에게 적용되지 않는다. 왜인가?" 정답은 "local 파일은 개인용이며 기본적으로 git에서 무시되기 때문이고, 애초에 잘못된 파일을 골랐다"이다. 팀 전파용 파일은 settings.json이다. 반대로 개인 비밀이나 임시 허용을 settings.json에 넣고 커밋하면 의도치 않게 팀 전체에 강요되거나 민감 정보가 노출된다. 파일 선택 자체가 곧 정답을 가른다.
두 번째 함정은 조직 강제 규칙의 자리다. "보안팀이 특정 명령을 어떤 개발자도 실행하지 못하게 하려 한다. 어디에 두어야 하는가?" 정답은 프로젝트 settings.json이 아니라 엔터프라이즈 관리 설정이다. 공유 settings.json의 deny는 개발자가 자기 로컬 설정으로 풀 수는 없지만, 저장소를 포크하거나 파일을 수정해 우회할 여지가 있다. 끄지 못하게 강제하려면 우선순위 최상단인 관리 설정에 두어야 한다.
세 번째는 전파 대상이 settings.json만이 아니라는 점이다. 팀에 일관된 Claude Code 환경을 주려면 보통 세 가지를 함께 버전 관리한다. 권한·환경·훅은 .claude/settings.json, 프로젝트 규칙과 코딩 컨벤션 같은 메모리는 CLAUDE.md, 팀이 공통으로 쓰는 MCP 서버 정의는 저장소 루트의 .mcp.json이다. 세 파일을 함께 커밋하면 clone 한 번으로 권한·메모리·도구가 동시에 전파된다. 시험에서 "팀원 전체가 같은 MCP 서버를 쓰게 하려면 어디에 정의하는가"를 물으면 개인 설정이 아니라 저장소의 .mcp.json이 정답이다.
정리
- Claude Code 설정은 네 층(user · 프로젝트 shared · 프로젝트 local · enterprise managed)이며, 우선순위는 managed > CLI > local > shared > user이다. 충돌 시 위층이 이긴다.
- 팀 전파용은 git으로 추적되는
.claude/settings.json, 개인용은 자동으로 git에서 무시되는.claude/settings.local.json이다. local을 커밋해 전파하려는 시도가 대표적 오답이다. - 누구도 끄지 못해야 하는 조직 보안 규칙은 공유 settings가 아니라 우선순위 최상단의 enterprise managed settings에 두어야 강제된다.
- 일관된 팀 환경은
settings.json(권한·환경·훅) ·CLAUDE.md(메모리·규칙) ·.mcp.json(공통 MCP 서버)을 함께 버전 관리해 전파한다.