AI 도서관 · Claude · 하네스 설정 · 실전 셋업

권한 규칙 — deny가 먼저 이깁니다

allow에 넣었는데 왜 막히지? 평가 순서를 알면 풀립니다

내용

📌 규칙은 세 가지
allow — 묻지 않고 실행
ask  — 매번 물어봄 (기본)
deny — 절대 실행 안 함

⚠️ 평가 순서가 핵심입니다
공식 문서 그대로 — **deny → ask → allow 순으로 평가하고,
먼저 매치되는 것이 결과를 정합니다. 규칙이 얼마나 구체적인지는 순서를 바꾸지 않습니다.**

이게 뜻하는 것
• 넓은 deny 하나가 좁은 allow 를 전부 막습니다
  Bash(aws *) 를 deny 하면 Bash(aws s3 ls) 를 allow 해도 막힙니다
• **deny 규칙은 예외를 담을 수 없습니다.** 예외를 두려면 deny 를 좁게 쓰세요
• ask 도 같습니다. 더 구체적인 allow 가 있어도 ask 가 이깁니다

[ 복붙용 기본 세트 ]
{
  "permissions": {
    "allow": [
      "Bash(npm test:*)",
      "Bash(npm run lint:*)",
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Read", "Edit"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)",
      "Read(.env*)",
      "Read(**/secrets/**)"
    ]
  }
}

[ 문법 ]
Bash(명령어:*)  그 명령으로 시작하는 것 전부
Read(.env*)     파일 경로는 gitignore 식 패턴
Read / Edit     괄호 없이 쓰면 그 도구 전체

📌 훅과 권한의 관계 (문서에 명시된 것)
• 훅이 allow 를 반환해도 deny·ask 규칙은 그대로 적용됩니다
• 반대로 **exit 2 로 차단하는 훅은 allow 보다 앞섭니다** — 권한 평가 전에 멈춥니다

💡 그래서 이런 조합이 가능합니다
Bash 전체를 allow 에 넣어 매번 묻지 않게 하고,
막고 싶은 몇 개만 PreToolUse 훅으로 거부하는 방식.
deny 로는 예외를 못 만들지만 이 조합은 됩니다.

⚠️ 권한을 통째로 건너뛰는 옵션을 쓰고 싶어진다면,
   그건 allow 목록을 제대로 안 짰다는 신호입니다.

궁금한 점: {{INPUT}}

{{INPUT}} 자리에 내 내용을 넣어 쓰는 프롬프트입니다. 아래 버튼으로 열면 넣는 칸이 나옵니다.

근거

유형
설정 가이드 — 지정된 파일이나 설정에 적용합니다
사용 환경
Claude Code — .claude/settings.json
주의
deny 규칙은 예외를 담을 수 없습니다. 넓게 쓰면 필요한 것까지 막힙니다.
공식 출처
https://code.claude.com/docs/en/permissions
확인일
2026-09-09 — 이후 바뀌었을 수 있습니다
도서관에서 열기 — 내 내용 넣고 복사하기