
Claude Code의 허가 프롬프트를 90% 줄이는 settings.json 최적화 레시피 — allow / deny 우선순위와 Bash
요약
Claude Code 사용 시 발생하는 도구 허가 프롬프트를 settings.json 설정을 통해 90% 이상 줄이는 최적화 방법을 소개합니다. allow/deny 우선순위와 와일드카드 활용법을 통해 개발 흐름을 개선할 수 있습니다.
핵심 포인트
- Bash 명령어 매칭 시 '콜론(:) + 와일드카드(*)' 형식이 필수임
- deny 설정은 allow 설정보다 우선순위가 높음
- 읽기 전용 도구(Read, Grep 등)는 allowlist에 포함하여 프롬프트 감소 가능
- 글로벌 설정과 프로젝트별 설정을 분리하여 관리하는 것이 효율적임
- /fewer-permission-prompts 명령어로 빈번한 프롬프트 내역 확인 가능
Claude Code로 작업하다 보면, npm install이나 git status를 실행할 때마다 "이 도구를 허가하시겠습니까?"라는 프롬프트가 나타나 흐름이 끊길 때가 있다. 매번 엔터를 누르는 것이 은근히 스트레스이며, 긴 세션에서는 체감상 10% 정도의 시간을 빼앗기는 기분이 들었다.
이 기사는 그 프롬프트를 90% 줄이기 위한 settings.json 작성법을 정리한 메모이다. 같은 부분에서 어려움을 겪은 사람들을 위해, 내가 시도했던 allowlist 패턴과 실수했던 포인트들을 남겨둔다.
-
Claude Code를 일상적으로 사용하는 엔지니어
-
도구 허가 프롬프트에 지친 사람
-
.claude/settings.json의 동작을 제대로 정리하고 싶은 사람 -
macOS 14.x(Darwin 24.6.0)
-
Claude Code(
/permissions명령어를 사용할 수 있는 버전) - Node.js 22.x / Python 3.13 -
셸: zsh
-
~/.claude/settings.json의permissions.allow에 Bash·MCP의 안전한 정형 패턴을 열거 -
프로젝트 고유의 것은
.claude/settings.json에 나누어 작성 -
Bash는
Bash(npm install:*)와 같이 **콜론(:) + 와일드카드(*)**가 필수(이를 모르면 매칭되지 않음) -
deny는allow보다 우선순위가 높음(이 부분에서 실수하기 쉬움) -
위험한 계열(
rm -rf,git push --force)은 명시적으로deny에 넣어 사고 방지
이렇게 하면 npm / git status / gh pr / Read / Grep 등의 프롬프트는 거의 사라진다.
먼저 현재 나오고 있는 프롬프트의 내역을 보고 싶다. 최근 세션의 로그를 집계하여 빈번하게 발생하는 도구를 나열해 주는 /fewer-permission-prompts라는 스킬이 동봉되어 있다.
/fewer-permission-prompts
출력 이미지(내 환경의 예):
[summary] 최근 200 세션 동안 허가 프롬프트가 발생한 도구 상위
- Bash(npm install:*) 42 회
- Bash(git status:*) 35 회
...
이를 바탕으로 settings.json에 추가할 후보를 결정한다. 자신이 일상적으로 여러 번 허가하고 있는 것을 우선하여 allowlist에 넣어가는 것이 정답이다. 처음부터 전부 작성하려고 하면 입도(granularity)가 어긋나게 된다.
~/.claude/settings.json(모든 프로젝트 공통)을 편집한다. 읽기 계열·조사 계열은 기본적으로 allow에 넣어도 문제없다.
{
"permissions": {
"allow": [
...
]
}
}
Read · Grep · Glob과 같은 읽기 전용 도구는 통째로 allow에 넣어도 문제없다. 이것만으로도 프롬프트 수는 대폭 줄어든다.
리포지토리 직하의 .claude/settings.json에 프로젝트 고유의 명령어를 작성한다. 예를 들어 Next.js 프로젝트라면:
{
"permissions": {
"allow": [
...
]
}
}
pnpm과 npm 같은 패키지 매니저(Package Manager)의 차이는 프로젝트 측으로 분리하는 것이 운영상 깔끔하다. 글로벌하게 pnpm을 작성해 버리면 npm 프로젝트에 불필요한 허가가 섞여 들어간다.
Claude Code를 한 번 종료하고 재시작하거나, /config reload로 설정을 재로드한다. 그 후 평소처럼 작업하여 npm install이나 git status에서 프롬프트가 나오지 않는다면 성공이다.
확인용으로 일부러 deny에 넣은 명령어를 실행해 본다:
> git push --force origin main
여기서 "허가하시겠습니까?" 프롬프트가 뜨는지 확인한다. 이것이 뜨지 않는다면 deny가 작동하지 않는 것이다(후술할 주의점 참조).
처음에 이 부분을 깨닫지 못해서 1시간을 허비했다.
NG 예시:
"allow": ["Bash(npm install)"]
이렇게 작성하면 **완전 일치 (Exact Match)**로 취급되어, npm install --save react와 같이 인자(argument)가 포함되어 있으면 매칭되지 않는다. 프롬프트가 계속 나타나며 "allow에 적었는데 왜 안 되지?"라는 상황이 발생한다.
OK 예시:
"allow": ["Bash(npm install:*)"]
:*가 "이후의 인자는 무엇이든 상관없음"을 의미하는 와일드카드(wildcard)이다. Bash 도구 특유의 표기법으로, 콜론(:)이 경계 기호(boundary symbol)로 사용된다는 점에 주의해야 한다. Bash(npm install*)와 같이 아스테리스크(*)만 붙여서는 작동하지 않는다.
서브 커맨드(subcommand)가 가변적인 경우에는 Bash(npm run *:*)와 같이 커맨드 쪽에도 *를 넣는다. 이렇게 하면 npm run dev, npm run build, npm run test 모두에 적용된다. allow에 Bash(git push:*)라고 쓰고, deny에 Bash(git push --force*)라고 쓰면, git push --force는 deny가 우선하므로 정상적으로 프롬프트가 나타난다.
여기서 "allow에 적었으니 그냥 통과되어야 한다"라고 착각하면 보안 사고로 이어질 수 있다. 금지하고 싶은 작업은 명시적으로 deny에 작성한다. allow와 deny에서 동일한 패턴이 충돌하면 deny가 승리한다는 점을 기억해 두자.
우선순위는 ~/.claude/settings.local.json (로컬 개인) → .claude/settings.json (프로젝트) → ~/.claude/settings.json (사용자) 순이며, 더 구체적인 계층이 나중에 적용되어 덮어쓴다(last-one-wins).
단, deny는 어느 레이어(layer)에서도 유효하다 (사용자 계층에서 deny한 것을 프로젝트 계층의 allow로 덮어쓸 수 없다). 이를 통해 보안을 담보한다.
"프로젝트에서 일시적으로 허용하고 싶다"면, 글로벌 설정을 완화하는 것이 아니라 .claude/settings.local.json에 개인용 allow를 추가하는 것이 정답이다.
MCP 서버의 도구를 허용할 때는 mcp__<server>__<tool> 형식을 사용한다.
"allow": ["mcp__notion__notion-fetch"]
포인트는 다음과 같다:
- 서버 이름과 "mcp" 사이의 구분자는 **언더스코어 두 개(
__)**이다. - 도구 이름 쪽은 실제 등록된 이름을 그대로 사용한다 (하이픈(
-) 구분인 경우 그대로 유지).
이를 모르면, Notion 공식 MCP와 같이 notion-fetch라는 이름의 도구를 허용할 때, mcp__notion__notion_fetch라고 잘못 입력하여 영원히 매칭되지 않는 사고가 발생할 수 있다.
설정 후 /permissions를 입력하면 실제로 매칭되고 있는 규칙 목록을 볼 수 있으므로, 작성 직후 반드시 확인한다.
.claude/settings.local.json은 개인의 추가 allowlist용이다. .gitignore에 넣어두지 않으면 팀 멤버의 설정을 덮어쓰거나, 자신의 개인 허용 설정이 유출될 수 있다.
확인 방법:
grep settings.local.json .gitignore
검색 결과가 없다면 추가한다:
echo ".claude/settings.local.json" >> .gitignore
Claude Code는 첫 init 시 .gitignore에 자동으로 추가해 주는 경우가 많지만, 오래된 리포지토리(repository)에는 포함되어 있지 않을 수 있으므로 한 번 확인해 두는 것이 좋다.
왜 프롬프트가 뜨도록 설계되었는가? Claude Code는 **에이전트 (Agent)**이므로, 인간이 감시하고 있지 않아도 명령을 실행하도록 설계되어 있다. 이를 무제한으로 허용하면 rm -rf /와 같은 사고가 발생할 수 있다. 따라서 "읽기 계열은 기본 허용, 쓰기·실행 계열은 확인"이라는 기본 노선을 취하고 있다.
allowlist는 "자신이 안전하다고 판단한 것만 자동으로 허용한다"는 권한 관리 메커니즘으로, OS의 sudoers와 유사한 발상이다. 자동으로 허용한다는 것은, 스스로 그 안전성에 책임을 진다는 의미이기도 하다.
실운용에서는 "읽기 계열은 통째로 allow, 쓰기 계열은 개별 allow, 파괴 계열은 명시적 deny"라는 3단계 전략을 취하면 편의성과 안전성의 균형을 맞출 수 있다.
/fewer-permission-prompts에서 자주 발생하는 도구들을 집계하여 위에서부터 해결한다.- 글로벌 (
~/.claude/settings.json) 설정과 프로젝트 (.claude/settings.json) 설정을 구분하여 사용한다. - Bash 패턴은
Bash(명령어:*)형태로 와일드카드 (Wildcard)를 붙인다. deny는allow보다 우선순위가 높으므로, 위험한 작업은 명시적으로deny한다..claude/settings.local.json은.gitignore에 추가한다.
이것만으로도 프롬프트 피로 (Prompt fatigue)의 90%를 없앨 수 있다. 작업 흐름 (Flow)이 끊기지 않고 계속 이어질 수 있다는 점은 작업 시간이 길어질수록 더욱 큰 효과를 발휘한다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기