이 페이지의 목차
확인 2026-10-21근거 자료 3건갱신 2026-10-26언급 21곳
이 페이지의 목차
확인 날짜 안내

공식 문서 Claude Code 권한 설정(본문 날짜 없음, 서버 Last-Modified 2026-10-20, 수집 2026-10-21) 기준이다. 규칙 예시는 원본 글자 그대로 옮겼다. 버전 조건은 수집일 기준이고 빨리 바뀌므로, 대외 자료에 쓰기 전에 공식 문서를 다시 확인한다.

Claude Code의 permissions.allow·ask·deny(allow·ask·deny 규칙, 용어 사전)에 쓰는 규칙 문자열을 어떻게 쓰고, 무엇에 맞고 무엇에 맞지 않는지 정리한다. 모드와 규칙의 관계는 권한 모드, 조직이 규칙을 강제하는 방법은 Claude Code 관리자 권한 통제, 프로젝트 파일의 allow 규칙이 언제 적용되는지는 작업 공간 신뢰, 규칙을 둘 파일은 Claude Code 설정 파일에 있다.

1. 규칙 세 종류와 평가 순서#

  • allow는 묻지 않고 도구를 쓰게 하고, ask는 쓸 때마다 묻고, deny는 쓰지 못하게 한다. /permissions에서 모든 규칙과 각 규칙이 온 settings.json 파일을 본다. Claude가 일하는 중에 규칙을 더하거나 빼면 같은 턴의 다음 도구 호출부터 적용된다(v2.1.234 전에는 턴이 끝날 때까지 대기). Claude Code 권한 설정
  • 평가는 deny → ask → allow 순이고, 처음 맞는 규칙이 결과를 정한다. 구체성은 순서를 바꾸지 않는다. Bash(aws *) deny는 Bash(aws s3 ls) allow에도 맞는 호출을 막는다. allow로 deny에 예외를 낼 수 없고, 맞는 ask 규칙은 더 구체적인 allow가 있어도 묻는다. Claude Code 권한 설정
  • 도구 이름만 쓴 deny는 도구를 아예 뺀다. Bash deny는 Claude의 컨텍스트에서 도구를 없애 Claude가 보지도 못한다. Bash(rm *)처럼 범위를 둔 deny는 도구를 남기고 맞는 호출만 막는다. 예외: EndConversation은 다른 도구가 하나라도 남아 있으면 deny로 뺄 수 없고, ask 규칙도 묻지 않는다. Claude Code 권한 설정
  • 규칙은 모델이 아니라 Claude Code가 강제한다. 프롬프트나 CLAUDE.md의 지시는 Claude가 하려는 일을 이끌 뿐 Claude Code가 허용하는 범위를 바꾸지 않는다. 접근을 주거나 거두려면 /permissions, 이 규칙, 권한 모드, PreToolUse 훅을 쓴다. Claude Code 권한 설정 → 메모리(CLAUDE.md)
  • 우선순위의 한계(mod): 설치한 mod가 tool.check로 호출을 승인할 때 deny가 유지되는지는 세션 조건에 달렸다. 기기에 managed settings가 있거나 Team·Enterprise /login이 세션 자격 증명이면 deny 거부가 기본으로 유지되고(조직이 바꿀 수 있다고 원본은 적는다), 둘 다 없으면 mod가 deny 규칙이 거부한 호출도 승인할 수 있다. 자세한 조건과 훅 가이드 표현과의 상충 해소(권한 문서 기준)는 훅. Claude Code 권한 설정
  • 설정 파일 사이: 어느 레벨에서든 deny된 도구는 다른 레벨이 allow할 수 없다. managed deny는 --allowedTools로 못 풀고, --disallowedTools는 managed 위에 제한을 더한다. user가 allow하고 project가 deny하면 막히고, 반대로 user deny도 project allow를 막는다. Claude Code 권한 설정 → Claude Code 설정 파일

2. 기본 형식#

규칙은 Tool 또는 Tool(specifier) 형식이다. 지정자 안의 괄호는 문자 그대로라서, 괄호가 든 명령이나 경로도 이스케이프할 필요가 없다. Claude Code 권한 설정

규칙효과
Bash모든 Bash 명령
WebFetch모든 웹 가져오기 요청
Read모든 파일 읽기
Bash(npm run build)정확히 npm run build 명령
Read(./.env)현재 디렉터리의 .env 읽기
WebFetch(domain:example.com)example.com으로 가는 요청

Bash(*)는 Bash와 같고, deny 규칙이면 두 형태 모두 도구를 컨텍스트에서 뺀다. Claude Code 권한 설정

3. 입력 파라미터로 맞추기 (deny·ask 전용)#

deny·ask 규칙은 내장 도구의 최상위 입력 파라미터를 Tool(param:value)로 맞출 수 있다. allow 규칙은 이 형식을 쓰지 않는다. 파라미터 값 하나로는 호출 전체가 안전하다고 할 수 없기 때문이라고 원본은 설명한다. Claude Code 권한 설정

규칙맞는 것
Agent(model:opus)Opus 모델 등급을 요청한 Agent 호출
Agent(isolation:worktree)git worktree를 요청한 Agent 호출
Bash(run_in_background:true)백그라운드로 도는 Bash 호출
  • 파라미터는 도구 입력의 직접 필드여야 한다. 객체·배열 안의 필드는 못 맞춘다.
  • 규칙 하나에 파라미터 하나. model과 isolation을 둘 다 걸려면 Agent(model:opus), Agent(isolation:worktree) 두 규칙을 쓴다.
  • 값에 *를 쓸 수 있다(Agent(isolation:*)는 명시한 모든 isolation 값). *가 없으면 정확히 맞아야 한다.
  • 모델이 생략한 파라미터는 맞지 않는다. Agent(model:*)는 model을 비운 호출에 맞지 않는다.
  • 값은 정규화 전 Claude가 보낸 글자 그대로 비교한다. Agent(model:opus)는 별칭 opus에 맞고 전체 모델 ID에는 맞지 않는다.
  • 예외로 Skill(skill:<name>) deny는 별칭·표시 이름 등 스킬의 어느 이름에도 맞는다. → 스킬
  • 콜론 앞뒤 공백은 무시한다. 각 호출의 정확한 파라미터 이름·값은 --verbose로 본다.
  • 주 내용 필드는 이렇게 못 맞춘다: Bash·PowerShell의 command, Read·Edit·Write의 file_path, Grep·Glob의 path, NotebookEdit의 notebook_path, WebFetch의 url. Bash(command:rm *)는 복합 명령으로 우회될 수 있어 Claude Code가 무시하고 시작 때 경고한다. 대신 Bash(rm *), Read(./path), WebFetch(domain:host)를 쓴다.
  • MCP 도구의 파라미터: --disallowedTools로 deny 규칙을 넘긴다. 설정 파일을 읽을 때는 괄호가 있는 mcp__ 규칙을 건너뛰고, 대화형 세션 시작 때 잘못된 설정 대화상자와 claude doctor 출력에 그 규칙을 보여 준다.

근거: Claude Code 권한 설정

4. Bash 와일드카드#

*는 공백을 포함한 어떤 텍스트에도 맞는다. *가 없는 규칙은 명령 하나에만 맞는다. 원본 경고: *는 하위 명령 뒤에 둔다. Claude Code는 첫 * 앞의 단어를 쓰인 그대로 맞추므로 그 단어가 규칙을 제한한다. Bash(git log *)는 git log 명령만, Bash(git *)는 모든 git 명령을 허용한다. Bash(git * main)처럼 하위 명령 앞에 *가 있는 allow 규칙은 시작 때 경고한다. Claude Code 권한 설정

쓴 규칙맞는 명령맞지 않는 명령
Bash(npm run build)npm run buildnpm run build --watch
Bash(npm run *)npm run build, npm run test --watch, npm runnpm install
Bash(git log * main)git log --oneline main, git log -5 main, git log --output=<file> maingit log main, git push origin main
Bash(git * main)git merge main, git push origin main, git -c core.fsmonitor=<script> diff maingit log
Bash(* --version)node --version, bash -c 'echo hi' --versionnode -v
Bash(ls *)ls -la, lslsof
Bash(ls*)ls -la, lsof
Bash(* --help *)npm --help xnpm --help

근거: Claude Code 권한 설정

표를 만드는 세 규칙:

  • *는 그 자리의 어떤 텍스트든 대신한다. Bash(git * main)의 *는 하위 명령 자리라서 모든 git 하위 명령과 그 앞의 옵션에 맞는다. git이 지정한 프로그램을 실행하게 하는 -c도 포함된다. Bash(* --version)은 프로그램 자리라서 어떤 프로그램이든 맞는다.
  • 공백 뒤 끝의 *는 맨 명령에도 맞는다. Bash(ls *)는 ls에, Bash(git log *)는 git log에 맞는다. 끝의 *가 규칙의 유일한 와일드카드일 때만 그렇다: Bash(* --help *)는 npm --help에 맞지 않는다.
  • 끝 * 앞의 공백도 규칙의 일부다. Bash(ls *)는 ls 뒤 공백이 필요해 lsof에 맞지 않고, Bash(ls*)는 lsof에도 맞는다.

:* 접미사는 끝 와일드카드의 다른 표기다(Bash(ls:*) = Bash(ls *)). 확인 창의 "Yes, and don't ask again"은 공백 형태로 저장한다. :*는 패턴 끝에서만 인식되고, Bash(git:* push)의 콜론은 문자 그대로라 git 명령에 맞지 않는다. Claude Code 권한 설정

원본 설정 예시: npm 스크립트와 git 커밋은 묻지 않고 실행하고, git push로 시작하는 명령은 거부한다. git -C . push처럼 다르게 쓴 push는 맞지 않는다(아래 6절). Claude Code 권한 설정

json
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

5. 도구 이름 와일드카드#

  • deny·ask: 도구 이름 자리에 glob을 쓸 수 있고, 도구 이름 전체에 맞아야 한다. "*"는 모든 도구, "mcp__*"는 모든 서버의 모든 MCP 도구다. 맨 이름 glob deny에 맞은 도구는 맨 도구 이름 deny처럼 컨텍스트에서 빠진다(EndConversation 예외도 같다). 모든 MCP 도구를 거부하는 원본 예시는 "deny": ["mcp__*"]다.
  • allow: 도구 이름 glob은 문자 그대로의 mcp__<server>__ 접두어 뒤에서만 받는다. 서버 부분에는 glob이 없어야 한다. mcp__puppeteer__*는 puppeteer 서버의 모든 도구, mcp__github__get_*는 그 서버의 get_ 도구에 맞는다. "*", "B*", "mcp__*" 같은 고정되지 않은 allow glob은 경고와 함께 건너뛰고 아무것도 자동 승인하지 않는다.
  • 오타 경고: 알려진 도구에 맞지 않는 deny·ask 규칙은 시작 때 경고한다. 이름에 _나 *가 있는 도구와 Claude Code가 없앤 도구(TaskOutput 등)는 검사에서 빠진다.
  • 표시 이름이 아니라 정식 이름: 트랜스크립트·확인 창의 표시(Stop Task)와 정식 이름(TaskStop)이 다를 수 있다. 권한 규칙과 훅 matcher는 표시 이름에 맞지 않는다. 정식 이름은 Tools reference에 있다.

근거: Claude Code 권한 설정

6. Bash 규칙의 세부#

복합 명령. Claude Code는 셸 연산자를 알아서 Bash(safe-cmd *)가 safe-cmd && other-cmd를 허용하지 않는다. 구분자는 &&, ||, ;, |, |&, &, 줄바꿈이고, allow 규칙은 하위 명령마다 따로 맞아야 한다. deny·ask는 하위 명령 하나라도 맞으면 적용되고, 서브셸·명령 치환·for 같은 제어 흐름 안의 명령도 포함한다. ask 규칙 Bash(git clean *)는 cd /tmp && git clean -f나 echo "$(git clean -f)"에도, 자동 모드에서도 묻는다. npm test &&처럼 &&·|| 뒤가 비면 파싱할 수 없는 명령으로 보고 하위 명령으로 나누지 않아 Bash(npm *)가 승인하지 않는다. Claude Code 권한 설정

래퍼. 맞추기 전에 정해진 래퍼를 벗긴다: timeout, time, nice, nohup, stdbuf, 셸 내장 command·builtin, zsh noglob. 그래서 Bash(npm test *)는 timeout 30 npm test에도 맞는다. command -v(조회)와 zsh nocorrect는 벗기지 않는다. 알려진 안전한 환경 변수의 앞 대입도 벗겨 NODE_ENV=test npm test에 맞는다. allow는 다른 변수 대입을 넘어 맞지 않지만, deny·ask는 어떤 앞 대입이든 넘어 맞는다(Bash(rm *) deny는 FOO=bar rm -rf tmp/에도 맞는다). 플래그 없는 맨 xargs도 벗기지만 xargs -n1 grep pattern은 xargs 명령으로 맞춘다. Claude Code 권한 설정

이 목록은 고정이고 바꿀 수 없다. direnv exec, devbox run, mise exec, npx, docker exec 같은 개발 환경 실행기는 목록에 없어서, Bash(devbox run *)는 devbox run rm -rf .까지 맞는다. 실행기 안의 일을 허용하려면 Bash(devbox run npm test)처럼 실행기와 안쪽 명령을 함께 쓴 규칙을 안쪽 명령마다 하나씩 둔다. Claude Code 권한 설정

접두어 규칙이 승인하지 못하는 것. Bash(watch *)나 Bash(find *) 같은 접두어 규칙은 다음을 자동 승인하지 못해 Manual 모드에서 묻는다: watch·setsid·ionice·flock 같은 exec 래퍼, 명령 실행·삭제·쓰기 동작(-exec, -delete, -fprint)이나 -files0-from이 붙은 find. *가 없는 특정 호출은 Bash(find build -type f -delete)처럼 전체 명령을 정확히 맞추는 규칙으로 허용한다. find . -name '*.tmp' -delete처럼 명령에 *가 들어 있으면 규칙이 와일드카드 패턴으로 읽혀 계속 묻는다. 매번 승인하거나 그 명령에 "allow"를 돌려주는 PreToolUse 훅을 쓴다. Claude Code 권한 설정

Bash 규칙이 맞추지 않는 것 (보안 경계가 아니다). Bash 규칙은 복합 명령을 나누고 래퍼를 벗긴 뒤의 명령 텍스트를 맞춘다. 같은 프로그램을 다른 형태로 부르면 맞지 않으므로, deny·ask 규칙은 Claude가 보통 쓰는 호출을 덮을 뿐 프로그램 둘레의 보안 경계가 아니다. Claude Code 권한 설정

deny·ask 규칙막는 것막지 않는 것
Bash(curl *)curl https://example.com/usr/bin/curl https://example.com, sh -c 'curl https://example.com'
Bash(rm *)rm -rf build//bin/rm -rf build/, bash -c 'rm -rf build/'
Bash(git push *)git push origin maingit -C . push origin main, git -c push.default=current push origin main, git 'push' origin main

마지막 열의 명령은 다른 규칙과 권한 모드가 정한다. 명령 텍스트와 무관한 파일 시스템·네트워크 강제는 샌드박스로(세부는 샌드박스, Claude Code 샌드박스 설정하기), 명령 전체를 자기 로직으로 검사하려면 PreToolUse 훅으로 한다. Claude Code 권한 설정 → Claude Code 차단 훅 단단하게 만들기

인자를 제한하려는 규칙은 깨지기 쉽다. 원본 예: Bash(curl http://github.com/ *)는 옵션이 URL 앞에 오거나(curl -X GET http://github.com/...), 프로토콜이 다르거나(https), 리디렉트(curl -L http://short.example.com/xyz)나 변수(URL=http://github.com && curl $URL)를 쓰면 맞지 않는다. 원본이 권하는 대안 세 가지: (1) curl·wget 등을 deny하고 허용 도메인은 WebFetch의 WebFetch(domain:github.com)로 연다. 단 deny는 경로 호출이나 sh -c 안의 같은 프로그램에 맞지 않으므로 제한이 반드시 지켜져야 하면 샌드박스 네트워크 허용 목록과 짝짓는다. (2) Bash 명령의 URL을 검사해 막는 PreToolUse 훅. (3) 허용하는 curl 패턴을 CLAUDE.md에 적기. 이것은 Claude가 하려는 일을 이끌 뿐 경계를 강제하지 않으므로 위 방법과 짝짓는다. 또 WebFetch만으로는 네트워크 접근을 막지 못한다. Bash가 허용돼 있으면 Claude가 curl·wget 등으로 어떤 URL에도 닿을 수 있다. Claude Code 권한 설정

읽기 전용 명령. Claude Code는 내장 Bash 명령 묶음을 읽기 전용으로 알아보고 모든 모드에서 묻지 않고 실행한다(permissions.blockReadsOutsideWorkingDirectories가 작업 디렉터리 밖 경로에 대해 바꾸는 경우는 예외). ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd와 git의 읽기 전용 형태가 들어간다. 이 묶음은 바꿀 수 없고, 묻게 하려면 그 명령에 ask나 deny 규칙을 둔다. 자동 모드에서는 이 명령도 분류기 검토를 기다릴 수 있다. 모든 플래그가 읽기 전용인 명령은 따옴표 없는 glob도 허용된다(ls *.ts, wc -l src/*.py). Claude Code 권한 설정

Manual 모드에서 이 묶음의 명령도 묻는 경우: 쓰기·실행 가능 플래그가 있는 명령(find, sort, sed, git)에 따옴표 없는 glob이 있을 때(glob이 -delete 같은 플래그로 펼쳐질 수 있어서), 다른 데몬을 고르는 플래그(-H, --context, Podman --url·--connection)가 붙은 docker, 경로를 여는 플래그(-m/--magic-file, -f/--files-from)가 붙은 file, 환경 변수를 출력할 수 있는 ps(ps auxe, ps aux -e. 대시 형태 검사는 v2.1.290 이상, ps aux·ps -ef는 묻지 않음), Windows 네트워크(UNC) 경로가 든 명령(PowerShell 도구도 같음), PATH·IFS 같은 특수 셸 변수를 설정·해제·순회하는 명령, 분석이 파싱하지 못하는 명령(10,000자를 넘는 명령은 항상 묻는다). 작업 디렉터리나 추가 디렉터리 안으로 가는 cd도 읽기 전용이지만, cd로 다른 디렉터리에 가서 git을 돌리면(그 디렉터리의 git 훅이 돌 수 있어서), 또는 cd 뒤 리디렉트 대상의 기준 디렉터리를 알 수 없으면 묻는다(/dev/null만 대상이면 묻지 않음). Claude Code 권한 설정

리디렉션과 tee. 리디렉트 대상은 Claude가 그 파일을 직접 쓰거나 읽는 것처럼 파일 규칙으로 검사한다. 출력(> file, >> file, 2> file)은 Edit allow·deny 규칙, 보호 경로, 작업 디렉터리로 검사하고, Bash(git commit *)는 명령을 허용할 뿐 대상은 허용하지 않는다. ~로 시작하거나 glob 문자가 든 대상은 승인이 필요하다. 입력(< file)은 Read 규칙과 작업 디렉터리로 검사한다(v2.1.257 이상). /dev/null, 2>&1·<&3 같은 파일 디스크립터 형태, here-doc·here-string은 검사하지 않는다. make | tee build.log처럼 tee가 쓰는 파일도 같은 방식으로 검사하고, Bash(tee *)는 작업 디렉터리 밖 대상을 덮지 않는다(v2.1.269 이상). Claude Code 권한 설정

7. PowerShell#

Bash와 같은 모양이다. *는 어느 위치에서나 맞고, :*는 끝 *와 같고, 맨 PowerShell이나 PowerShell(*)는 모든 명령에 맞는다. 흔한 별칭은 정규화되므로 PowerShell(Get-ChildItem *)는 gci, ls, dir에도 맞고, 대소문자를 구분하지 않는다. PowerShell AST를 파싱해 파이프라인 |, 문장 구분 ;, PowerShell 7+의 &&·||로 나눈 하위 명령마다 따로 검사하며, 모든 하위 명령이 맞아야 허용된다. Claude Code 권한 설정

json
{
  "permissions": {
    "allow": [
      "PowerShell(Get-ChildItem *)",
      "PowerShell(git commit *)"
    ],
    "deny": [
      "PowerShell(Remove-Item *)"
    ]
  }
}

8. Read·Edit (파일 경로 규칙)#

무엇에 적용되나. 파일이나 디렉터리 읽기를 막으려면 Read(./.env), Read(./secrets/**) 같은 Read deny 규칙을 둔다. .claudeignore 파일은 효과가 없으니 그 항목을 Read deny 규칙으로 옮긴다. Edit 규칙은 파일을 고치는 모든 내장 도구에 적용된다. Read 규칙은 Grep·Glob 같은 읽기 도구, 프롬프트의 @file 참조, 연결된 IDE가 넘기는 선택 영역·열린 파일 맥락에 최선 노력(best-effort)으로 적용된다. Read(path) deny 규칙은 터미널에 붙여 넣은 이미지 경로(맞으면 이미지를 붙이지 않음)와 @로 참조한 디렉터리 목록(맞는 이름을 뺌)에도 적용된다(이 두 검사는 v2.1.290 이상). Read deny는 같은 경로의 Edit·Write(새 파일 만들기 포함)도 막지만(Write는 v2.1.228 이상) NotebookEdit는 덮지 않으므로, 어떤 도구도 바꾸면 안 되는 경로에는 Edit deny도 둔다. Claude Code 권한 설정

경고: 닿지 않는 곳. Read·Edit deny는 내장 파일 도구, Claude Code가 알아보는 Bash 파일 명령(cat, head, tail, sed, tee), 리디렉션 대상에 적용된다. 파일 이름을 대지 않는 명령(파일이 있는 디렉터리에서 돌린 grep -r pattern .)이나 파일을 스스로 여는 Python·Node 스크립트 같은 임의 하위 프로세스에는 적용되지 않는다. 모든 프로세스를 OS 수준에서 막으려면 샌드박스를 켜라고 원본은 말한다. Claude Code 권한 설정

규칙을 걸 도구 이름. 파일 권한은 Edit(path)와 Read(path) 규칙으로만 검사한다. Write, NotebookEdit, Glob, 예전 MultiEdit에 경로 규칙을 쓰면 받아들이지만 참조하지 않고 시작 때 경고한다(--allowedTools로 넘긴 Glob 규칙은 예외). Write(docs/**) 대신 Edit(docs/**), Glob(docs/**) 대신 Read(docs/**)를 쓴다. 도구별 규칙 형식 표와 macOS·Linux·WSL에서 검색이 Glob·Grep 대신 Bash 호출로 규칙에 닿는다는 점(2026-10-26 기준)은 Claude Code 내장 도구. 경로 없는 도구 이름 규칙(예: Write deny)은 경고 없이 도구 단위로 어디서나 맞는다. Claude Code 권한 설정

패턴 네 가지 (gitignore 문법). Claude Code 권한 설정

패턴뜻예맞는 곳
//path파일 시스템 루트부터 절대 경로Read(//Users/alice/secrets/**)/Users/alice/secrets/**
~/path홈 디렉터리부터Read(~/Documents/*.pdf)/Users/alice/Documents/*.pdf
/path설정 출처 기준 상대 경로Edit(/src/**/*.ts)프로젝트 설정이면 <primary working directory>/src/**/*.ts
path 또는 ./path현재 디렉터리 기준 상대 경로Read(*.env)<cwd>/*.env

원본 경고: /Users/alice/file은 절대 경로가 아니다. 앞의 슬래시 하나는 파일 시스템 루트가 아니라 설정 출처에 고정된다. 절대 경로는 //Users/alice/file로 쓴다. Claude Code 권한 설정

/path가 가리키는 곳은 규칙을 둔 파일마다 다르다. Claude Code 권한 설정

규칙을 둔 곳/path의 기준
프로젝트 설정 .claude/settings.json<primary working directory>/path
로컬 설정 .claude/settings.local.json<primary working directory>/path
사용자 설정 ~/.claude/settings.json~/.claude/path
--settings <file>로 넘긴 파일<directory of file>/path
CLI 플래그나 세션 규칙<primary working directory>/path
  • /permissions로 더한 규칙은 저장한 설정 파일의 행을 따른다. 로컬 설정 규칙은 파일이 저장되는 저장소 루트(v2.1.211 이상)가 아니라 세션의 주 작업 디렉터리에 고정된다. worktree 세션에서 Edit(/src/**)는 그 worktree의 src/에 맞는다.
  • 그래서 사용자 설정의 Read(/secrets/**) deny는 프로젝트의 secrets가 아니라 ~/.claude/secrets/**를 막는다. 모든 프로젝트에 걸리는 사용자 규칙은 // 절대 경로나 ~/ 경로로 쓴다.
  • Windows는 맞추기 전에 POSIX 형태로 바꾼다(C:\Users\alice → /c/Users/alice). 그 드라이브의 모든 .env는 //c/**/.env, 모든 드라이브는 //**/.env.
  • 원본 예: Edit(/docs/**)는 <primary working directory>/docs/(/docs/도 <primary working directory>/.claude/docs/도 아님), Read(~/.zshrc)는 홈의 .zshrc, Edit(//tmp/scratch.txt)는 절대 경로 /tmp/scratch.txt, Read(src/**)는 allow면 <current-directory>/src/만, deny·ask면 현재 디렉터리 아래 어느 깊이의 src에도 맞는다.

근거: Claude Code 권한 설정

맞는 깊이. 규칙은 기준 위치 아래 파일에만 맞는다. 맨 파일 이름은 gitignore처럼 어느 깊이에서나 맞아 Read(.env)와 Read(**/.env)는 같다(현재 디렉터리 아래의 모든 .env를 막고, 상위 디렉터리나 다른 프로젝트의 .env는 막지 않는다). Read(//**/.env)는 파일 시스템 어디의 .env든 막는다. 디렉터리 조각이 하나인 상대 패턴(src/**)만 규칙 종류에 따라 깊이가 다르다: allow Edit(src/**)는 <cwd>/src와 그 아래만(어느 깊이든 허용하려면 Edit(**/src/**)), deny·ask Read(secrets/**)는 어느 깊이의 secrets 디렉터리에도 맞는다. 다른 모양(Edit(/src/**), Edit(src/components/**), Edit(**/src/**))은 규칙 종류와 상관없이 같다. gitignore 패턴에서 *는 경로 조각 하나 안에서, **는 디렉터리를 넘어 맞는다. Claude Code 권한 설정

규칙 (최상위 src/와 vendor/pkg/src/가 있는 프로젝트)src/app.ts에 맞나vendor/pkg/src/lib.js에 맞나
allow Edit(src/**)예아니오
deny·ask Edit(src/**)예예
모든 종류 Edit(/src/**)예아니오
모든 종류 Edit(**/src/**)예예

이스케이프와 쓸 수 없는 패턴. "Yes, and don't ask again"으로 승인한 파일 경로는 [, ], * 같은 gitignore 문자를 이스케이프해 그 경로에만 맞게 저장한다. 직접 쓴 규칙은 이스케이프하지 않는다. 경로의 괄호는 이스케이프할 필요가 없다(Edit(./Finance (2024)/**)). gitignore 패턴으로 쓸 수 없는 경로의 deny·ask 규칙은 그 정확한 경로를 지키고, 같은 경우의 allow 규칙은 아무것도 승인하지 않는다. Claude Code 권한 설정

! 예외(부정) 패턴. deny·ask에서 !로 시작하는 패턴은 앞에 나온 path·./path 규칙에서 맞는 경로를 빼 준다. 한 설정 파일의 deny에 Read(*.env) 다음 Read(!sample.env)를 두면 sample.env만 빼고 이름이 .env로 끝나는 모든 파일을 막는다. 먼저 나온 ! 규칙은 아무것도 빼지 않는다. 한계: 같은 출처의 규칙에만 미친다(프로젝트 설정이나 --disallowedTools의 Read(!.env)는 managed의 Read(./.env) deny를 풀지 못한다). ! 뒤에 /·~/·//가 와도 현재 디렉터리 기준으로 읽어 그런 접두어로 고정된 규칙에 닿지 못한다(Read(!~/notes/public/**)는 Read(~/notes/**)에서 아무것도 빼지 않는다). 디렉터리 통째로 막는 규칙 안의 파일은 다시 열 수 없다(Read(secrets/**)와 Read(!secrets/public/**)면 secrets/public도 막힌다). Claude Code 권한 설정

심볼릭 링크. 링크를 거치는 경로는 요청한 경로와 해석된 실제 파일 둘 다 검사한다(macOS·Linux·Windows의 심볼릭 링크, Windows 디렉터리 정션). allow는 둘 다 맞아야 적용되고, deny는 하나만 맞아도 적용된다. 원본 예: Read(./project/**) allow와 Read(~/.ssh/**) deny가 있을 때, ~/.ssh/id_rsa를 가리키는 ./project/key 링크는 막힌다. macOS·Linux에서 //, ~/, / 패턴의 deny·ask는 링크된 디렉터리의 실제 위치에도 적용된다(Read(//etc/**)는 /private/etc/hosts도 막는다, v2.1.268 이상). Edit·Write는 요청 경로 자체가 링크면 거부하고 링크 대상을 쓰라고 안내한다. 경로 중간 디렉터리가 링크이거나 Bash·PowerShell 명령이 쓰는 경우는 통과할 수 있고, 이때 해석된 파일이 작업 디렉터리 밖이면 acceptEdits에서 자동 승인하지 않고 자동 모드에서는(allow 규칙이 없으면) 분류기 대신 사람에게 묻는다. 경로가 루프 등으로 해석되지 않으면 Read·Edit·Write가 거부하고, 승인한 파일을 실제로 열 때 같은 위치로 해석되는지 다시 확인한다. Claude Code 권한 설정

네트워크 경로 (v2.1.292 이상). Read·Grep·Glob이 다른 컴퓨터에 닿을 수 있는 경로(Windows UNC \\server\share\file, macOS·Linux /net 자동 마운트)를 읽으면 따로 묻는다. 경로를 조회하기만 해도 그 호스트에 연락하고, Windows에서는 자격 증명이 보내질 수 있어서다. allow 규칙(도구 전체 Read 포함), "allow"를 돌려주는 PreToolUse 훅, 자동 모드 분류기 어느 것도 이 확인을 없애지 못한다. dontAsk에서는 거부하고, bypassPermissions와 bypass를 쓸 수 있는 대화형 터미널 plan 세션에서는 묻지 않고 읽는다. 확인 없이 읽으려면 공유를 로컬 경로로 먼저 만든다(Windows는 드라이브 문자로 매핑해 --add-dir로, macOS·Linux는 /mnt·/Volumes 아래에 마운트). Claude Code 권한 설정

9. WebFetch#

domain: 접두어로 요청 URL의 호스트 이름을 맞춘다. 대소문자를 구분하지 않고 *를 쓰며, 규칙과 호스트 끝의 .을 지운다(example.com. = example.com). 와일드카드는 v2.1.172 이상에서 맞는다. Claude Code 권한 설정

  • WebFetch(domain:example.com)은 example.com만. 하위 도메인까지 덮으려면 WebFetch(domain:*.example.com)을 더한다.
  • WebFetch(domain:*.example.com)은 어느 깊이의 하위 도메인(api.example.com, a.b.example.com)에도 맞고 example.com 자체에는 맞지 않는다.
  • 앞의 *.나 맨 *가 아닌 자리의 *는 점 사이 텍스트에만 맞는다. WebFetch(domain:example.*)는 example.org에 맞고 example.evil.com에는 맞지 않는다. 공격자가 등록할 수 있는 도메인에 끝 와일드카드가 맞지 않게 하려는 것이라고 원본은 설명한다.

맨 WebFetch와 WebFetch(domain:*)의 차이. 둘 다 모든 URL을 덮지만 적용 방식이 다르고, domain: 형태만 샌드박스의 허용·거부 도메인 목록에도 들어간다. Claude Code 권한 설정

규칙allow에 두면deny에 두면
WebFetch묻지 않고 가져온다. 샌드박스 명령이 닿는 호스트는 바뀌지 않는다WebFetch 도구를 빼서 아예 가져오지 못한다. 샌드박스 명령이 닿는 호스트는 바뀌지 않는다
WebFetch(domain:*)묻지 않고 가져오고, 샌드박스 명령이 어느 호스트에나 닿는다도구는 남기고 가져오기마다 거부하며, 샌드박스 명령이 어느 호스트에도 닿지 못한다
  • Artifact 도구가 claude.ai에 게시한 페이지 읽기: 맨 WebFetch deny·ask는 적용되지 않고, claude.ai나 *.claudeusercontent.com을 덮는 domain: 규칙(WebFetch(domain:claude.ai), WebFetch(domain:*))이나 Artifact 규칙이 읽기마다 거부하거나 묻는다. v2.1.268 전에는 맨 WebFetch deny가 모든 artifact 읽기를 막았다. Claude Code 권한 설정
  • 샌드박스 허용 목록은 그대로 두고 가져오기만 자유롭게 하는 원본 예시는 맨 형태다: "allow": ["WebFetch"]. 이때 허용 목록 밖 호스트에 샌드박스 curl을 돌리게 하면 여전히 묻는다(자동 모드에서는 명령의 허용 도메인에 호스트를 적어 분류기가 검토한다). Claude Code 권한 설정

10. MCP#

  • 서버의 모든 도구: mcp__<server>__*(또는 mcp__puppeteer처럼 서버 이름만). 도구 하나: mcp__<server>__<tool>(예: mcp__puppeteer__puppeteer_navigate).
  • <server>는 그 서버의 도구 이름에 나타나는 형태로 쓴다. .이나 공백은 _가 된다(my.server → mcp__my_server__*). 플러그인 서버는 범위가 붙은 형태다(my-plugin의 database-tools → mcp__plugin_my-plugin_database-tools__*). 이름에 __가 있거나 _로 끝나면 와일드카드 형태를 전체 이름으로 쓴다(reports__v2 → mcp__reports__v2__*). 이때 mcp__reports__v2나 mcp__reports는 reports 서버의 규칙으로 읽혀 allow로 맞지 않는다.
  • 조직이 claude.ai 커넥터 도구를 ask로 정했고 그 설정이 세션에 닿으면 그 도구의 allow 규칙은 효과가 없고, auto·bypassPermissions에서도 매번 묻고 dontAsk에서는 거부한다. Claude Code가 직접 가져오는 커넥터 도구는 mcp__claude_ai_<server>__<tool>로 보인다.
  • Claude Desktop의 Cowork 세션에서 Claude는 내장 Bash 대신 mcp__workspace__bash, 웹 가져오기는 mcp__workspace__web_fetch를 쓴다. 도구 전체를 이름으로 막는 Bash·WebFetch deny는 이 Cowork 도구에도 적용돼 managed Bash deny가 Cowork의 셸 명령을 막는다(메시지: Permission to use mcp__workspace__bash has been denied.). allow는 넘어가지 않는다: Bash allow는 mcp__workspace__bash에 적용되지 않는다. → Claude Cowork

근거: Claude Code 권한 설정 → MCP

11. Agent와 Cd#

  • Agent: Agent(AgentName)로 쓸 서브에이전트를 정한다(Agent(Explore), Agent(Plan), Agent(my-custom-agent)). deny 배열이나 --disallowedTools로 특정 에이전트를 끈다. 원본 예시: "deny": ["Agent(Explore)"]. Claude Code 권한 설정 → 서브에이전트
  • Cd: /cd 명령이 세션을 옮길 수 있는 디렉터리를 정한다. Cd는 Claude가 부르는 도구가 아니라서 사용자가 /cd를 칠 때만 적용된다. 맨 Cd deny는 /cd를 끄고, Cd(<path-pattern>) deny는 맞는 대상을 막는다(링크를 거치는 모든 표기를 검사). Cd allow를 하나라도 두면 허용 목록 모드가 돼 맞지 않는 대상은 거부한다. 규칙이 없으면 낯선 디렉터리에 신뢰를 묻는 기본 동작이다. 경로는 Read·Edit의 //·~/·/ 기준을 쓰지만 gitignore식이 아니라 전체 디렉터리 경로에 고정되고, *는 조각 하나, **는 여러 조각, 끝 /**는 이름 붙은 루트도 맞는다. Claude Code 권한 설정
규칙맞는 것맞지 않는 것
Cd(~/code/*)~/code/app~/code/app/src, ~/code
Cd(~/code/**)~/code와 그 아래 모든 디렉터리~/code 밖
Cd(**/node_modules)현재 디렉터리 아래 어느 깊이의 node_modulesnode_modules/pkg

12. 확인 창에서 저장되는 규칙#

도구 종류예Manual 모드에서 묻나"Yes, and don't ask again"
읽기 전용파일 읽기, Grep아니오(작업 디렉터리·추가 디렉터리 안)해당 없음
Bash 명령셸 실행예(내장 읽기 전용 명령 제외)저장소·명령 단위로 영구
파일 수정파일 편집·쓰기예세션 끝까지
웹 가져오기WebFetch예(미리 승인된 문서 도메인 제외)저장소·도메인 단위로 영구
웹 검색WebSearch예저장소 단위로 영구

근거: Claude Code 권한 설정

  • 영구 승인은 git 저장소 루트의 .claude/settings.local.json에 규칙으로 저장되고(worktree는 메인 체크아웃으로 해석), 하위 디렉터리·worktree에서 시작한 세션을 포함해 그 저장소 전체에 적용된다. v2.1.211 전에는 시작 디렉터리에 저장해 나머지 저장소에 적용되지 않았다. git 저장소 밖이나 Windows처럼 루트를 쓰지 않는 경우는 Settings 문서가 정리한다 → Claude Code 설정 파일. 파일 수정 승인은 파일에 저장되지 않는다.
  • 상시 승인 선택지는 그 선택지가 허용할 모든 것을 확인 창에 보여 줄 수 있을 때만 뜬다. 그래서 일회 승인만 있는 확인 창도 있다. 그때는 한 번 승인하거나 /permissions에서 규칙을 직접 더한다.
  • 복합 명령을 상시 승인하면 전체 문자열이 아니라 승인이 필요한 하위 명령마다 규칙을 저장한다(git status && npm test → npm test 규칙). 작업 디렉터리 밖으로 가는 cd는 그 경로의 Read 규칙을 만든다. 복합 명령 하나에 규칙은 최대 5개까지 저장된다.

근거: Claude Code 권한 설정 확인 창에 메모를 달아 답하는 법은 Claude Code 권한 모드 고르기.

13. 규칙으로 할 일과 샌드박스·훅으로 할 일#

  • 권한 규칙은 Claude Code가 어떤 도구를 쓰고 어떤 파일·도메인에 닿을지 정하고, Bash·Read·Edit·WebFetch·MCP 등 모든 도구에 적용된다(다른 도구가 남아 있는 동안의 EndConversation 예외). 샌드박스는 셸 명령(Bash, PowerShell, Monitor)과 그 하위 프로세스의 파일 시스템·네트워크 접근을 OS 수준에서 제한한다. 원본은 프롬프트 인젝션이 Claude의 판단을 우회해도 샌드박스 제한은 남으므로 둘을 함께 쓰라고 한다. 두 설정의 경로·도메인은 최종 샌드박스 구성으로 합쳐진다. Claude Code 권한 설정
  • 샌드박스를 켜고 autoAllowBashIfSandboxed를 기본값 true로 두면, 맨 Bash(또는 Bash(*)) ask 규칙이 있어도 샌드박스 Bash 명령은 묻지 않고 돈다(샌드박스 경계가 도구 전체 확인을 대신한다). Bash(git push *) 같은 내용 지정 ask 규칙은 여전히 묻는다. plan 모드에서는 이 대체를 건너뛴다. 샌드박스 밖에서 도는 명령(제외 명령 등)은 맨 Bash ask를 따른다. Claude Code 권한 설정
  • (2026-10-21 기준) 공식 Sandboxing 문서가 더하는 규칙과 샌드박스의 접점: Claude Code 샌드박스
    • Edit allow 규칙은 sandbox.filesystem.allowWrite처럼 샌드박스 명령에 쓰기를 주고, Read·Edit deny 규칙은 샌드박스 명령의 접근도 막으며, WebFetch(domain:...) allow·deny 규칙은 샌드박스 허용·거부 도메인에 들어간다. 반대로 sandbox.filesystem.denyRead는 Read 도구를 막지 않고 allowedDomains는 WebFetch를 제한하지 않는다.
    • 경로 표기가 다르다. 샌드박스 경로는 /tmp/build가 절대, ~/.kube가 홈 기준이고, Read·Edit 규칙은 //path가 절대, /path가 프로젝트 기준이다.
    • WebFetch(domain:...) 규칙에서 샌드박스가 받는 와일드카드는 앞의 *.(예: *.example.com)와 맨 * 두 가지다(맨 *는 v2.1.186 이상). WebFetch(domain:example.*)처럼 다른 위치의 와일드카드는 가져오기에는 맞지만 샌드박스 명령에는 효과가 없다.
    • 샌드박스 명령의 새 도메인 확인 창에서 "Yes, and don't ask again"을 고르면 WebFetch(domain:...) allow 규칙이 local 설정에 저장된다(관리자 필수 샌드박스에서는 user 설정에).
    • 명령에 맞는 allow 규칙(예: Bash(curl *))은 그 명령의 샌드박스 밖 재시도도 승인한다. 재시도마다 묻게 하려면 입력 파라미터 ask 규칙 Bash(dangerouslyDisableSandbox:true)를 둔다. 이 규칙은 자동 모드와 bypassPermissions에서도 묻고, 맞는 allow 규칙보다 앞선다.
    • auto-allow에서 FOO=bar npm test, make CC=clang, eval "ls"는 일반 권한 흐름을 탄다. 반복 확인 창을 멈추는 원본 규칙: Bash(make *), Bash(FOO=bar npm *)(변수 대입을 규칙에 포함), Bash(eval "ls")(Bash(eval *)는 이 확인 창을 멈추지 않으므로 명령 전체를 맞춘다).
  • 명령 텍스트로 안 되는 검사는 훅이 맡는다. 종료 코드 2로 막는 PreToolUse 훅은 권한 규칙 평가 전에 호출을 멈추므로 allow 규칙보다 앞선다. 원본 예: 대부분의 Bash 명령을 묻지 않고 돌리되 몇 개만 막으려면 allow에 "Bash"를 넣고 그 명령을 거부하는 PreToolUse 훅을 둔다. Claude Code 권한 설정 → 훅, Claude Code 차단 훅 단단하게 만들기

관련#