Field Log · Entry
Claude Code 권한 설정 — allow/ask/deny와 permission mode, hooks 조합으로 안전한 자동화 (5/8)
Claude Code에 권한 설정 한 줄을 빠뜨려서 사고를 본 사람들이 점점 늘고 있습니다. 그렇다고 모든 작업을 매번 물어보게 하면 자동화의 의미가 사라집니다. 얼마나 풀고 얼마나 묶을 것인가. 이 균형이 권한 설계의 전부입니다.
결론부터 말하면, “읽기만 allow → Write는 PostToolUse 훅으로 린트 → 위험 패턴은 deny”의 최소 권한(Least Privilege) 파이프라인이 가장 안정적이었습니다. 이 글은 allow/ask/deny 3단계, permission mode 3종, hooks 조합을 실제 settings.json 예시와 함께 정리합니다.
이 글이 답하는 질문
- Claude Code의 allow, ask, deny는 각각 뭘 의미하고, settings.json에 어떻게 쓰나?
- permission mode(default/plan/auto)는 언제 어떤 걸 써야 하나?
- 권한과 hooks를 조합하면 어떤 자동화가 가능한가?
왜 권한이 필수인가
실제 사고 시나리오를 떠올리면 더 명확합니다. 에이전트에게 “테이블 스키마가 꼬였어, 깨끗하게 정리해줘”라고 했더니 DROP TABLE users; CREATE TABLE users(...)를 자신 있게 제안하는 식입니다. 권한 설정이 없으면 이런 판단은 막을 방법이 없습니다.
에이전트가 강력해질수록 권한 없는 에이전트는 위험합니다. allow / ask / deny 3단계는 “신뢰하지만 검증한다”의 가장 단순한 구현입니다.
핵심: allow / ask / deny 3단계
모든 권한 설정은 이 3단계로 귀결됩니다 (Claude Code Permissions 공식 문서의 settings.json 스키마 기반).
| 레벨 | 동작 | 적합한 행동 |
|---|---|---|
| allow | 확인 없이 자동 실행 | 파일 읽기, grep, find, git status |
| ask | 매번 사용자에게 물어봄 | 파일 수정, 셸 명령, npm install |
| deny | 완전 차단 | rm -rf, DROP TABLE, sudo, 프로덕션 배포 |
allow에도 deny에도 없는 행동은 자동으로 ask가 됩니다.
핵심 원칙: 최소 권한(Least Privilege). 처음에는 읽기만 allow에 넣고, 안전하다고 확인된 것만 점진적으로 올립니다.
Permission Mode — 전체 엄격도 조절
Claude Code는 3가지 permission mode를 제공합니다.
claude # default: 위험한 것만 물어봄
claude --permission-mode plan # plan: 모든 쓰기를 물어봄 (학습용 추천)
claude --permission-mode auto # auto: 거의 다 자동 (신뢰 환경에서만)
| 모드 | 동작 | 권장 시점 |
|---|---|---|
default | 위험한 것만 물어봄 | allow/deny 규칙이 어느 정도 정착한 뒤 |
plan | 모든 쓰기를 물어봄 | 첫 3일 - 학습용 |
auto | 거의 다 자동 | CI/CD, 완전 신뢰 환경 |
처음 배울 때는 plan 모드를 추천합니다. 에이전트가 뭘 하려는지 매번 물어보니까, “아 이런 판단을 하는구나”를 관찰하면서 배울 수 있습니다.
실제 settings.json 예시
개인 사이드 프로젝트 (위험 낮음)
- 적합: 실험용 코드, 개인 블로그, 토이 프로젝트
- 핵심 패턴: Write를 allow에 두고,
rm -rf·sudo만 deny.
{
"permissions": {
"allow": ["Read(*)", "Write(*)", "Bash(npm test:*)"],
"deny": ["Bash(rm -rf:*)", "Bash(sudo:*)"]
}
}
주의
실제 데이터베이스가 연결된 순간 바로 ‘팀 프로젝트’ 단계로 업그레이드하세요.
팀 프로젝트 (위험 중간)
- 적합: 공동 개발 중인 서비스 레포, 스테이징 환경 포함
- 핵심 패턴: Write는 ask, PostToolUse 훅으로 자동 린트.
{
"permissions": {
"allow": ["Read(*)", "Bash(grep:*)", "Bash(find:*)"],
"deny": ["Bash(rm -rf:*)", "Bash(git push --force:*)", "Bash(DROP:*)"]
},
"hooks": {
"PostToolUse": [{
"matcher": "Write",
"command": "npx eslint --fix $CLAUDE_FILE_PATH 2>&1 | tail -3"
}]
}
}
주의
프로덕션 DB URL이 .env에 있다면 Bash(psql:*)을 deny에 추가하세요.
프로덕션 서비스 (위험 높음)
- 적합: 실제 사용자 트래픽이 도는 레포, CI/CD 연결
- 핵심 패턴: 쓰기 자체를 금지, 읽기·조회만 허용.
{
"permissions": {
"allow": ["Read(*)", "Bash(grep:*)", "Bash(cat:*)"],
"deny": ["Bash(rm:*)", "Bash(git push:*)", "Bash(DROP:*)",
"Bash(DELETE:*)", "Bash(curl -X DELETE:*)"]
}
}
주의
운영 변경은 PR + 사람 리뷰를 강제하고, 에이전트는 진단·조사만 담당하게 합니다.
위험도가 올라갈수록 allow는 줄어들고 deny는 늘어나는 패턴이 보이시죠?
권한 파이프라인 — 도구 실행 전 검사 순서
에이전트가 도구를 쓰겠다고 결정하면, 실행 전에 이 순서로 검사됩니다:
AI가 도구 호출 결정
↓
1. 입력값 검증 — 도구 이름, 인자가 올바른가?
↓
2. allow/deny 규칙 매칭 — settings.json 패턴 대조
→ allow 매칭 → 바로 실행
→ deny 매칭 → 거부
→ 매칭 안 됨 ↓
↓
3. PreToolUse 훅 실행 — 차단? 수정? 추가 로깅?
↓
4. Permission mode 적용 — plan이면 물어봄, auto면 통과
↓
도구 실행 → PostToolUse 훅 → 결과 반환
Hooks와 권한의 조합
allow/ask/deny가 “실행할지 말지”를 정한다면, hooks는 “실행 전후에 뭔가를 추가”합니다.
{
"hooks": {
"PostToolUse": [{
"matcher": "Write",
"command": "npx eslint --fix $CLAUDE_FILE_PATH 2>&1 | tail -3"
}],
"PreToolUse": [{
"matcher": "Bash",
"command": "echo \"$(date): $CLAUDE_TOOL_INPUT\" >> .claude/audit.log"
}]
}
}
첫 번째 훅은 파일 수정 후 자동 린트, 두 번째는 모든 셸 명령을 감사 로그에 기록합니다. hooks의 전체 활용법은 (8/8) 검증 루프 편에서 더 자세히 다룹니다.
점진적 개방 순서
1일차: allow에 읽기만. plan 모드로 관찰.
3일차: grep, find, cat을 allow에 추가.
1주차: Write를 allow + PostToolUse 린트 훅 추가. default 모드로.
2주차+: npm test, git commit 등을 개별적으로 allow/ask 설정.
흔한 실수
- 처음부터 auto 모드 → plan으로 최소 3일은 관찰하고 시작
- deny를 너무 넓게 →
Bash(*)전체 차단하면 아무것도 못 함 - subagent에 같은 권한 → 리뷰어는 읽기만, 코더와 같은 권한이면 안 됨 ((7/8) 역할 분리 편 참고)
내가 실제로 부딪힌 문제와 해결 (1인칭 경험)
권한 설정의 중요성은 이 블로그처럼 git push가 곧 배포로 이어지는 레포에서 더 크게 느꼈습니다. 읽기와 쓰기, 로컬 수정과 배포 명령 사이의 경계가 흐리면 작은 실수도 바로 공개 상태로 번질 수 있기 때문입니다. 실제로 자동화가 편하다는 이유만으로 쓰기 범위를 넓게 열어두면, 나중에는 검증보다 속도가 먼저 되는 순간이 온다는 걸 여러 번 봤습니다.
그래서 지금은 읽기는 최대한 부드럽게 열어두되, 공개 상태를 바꾸는 명령은 반드시 의식적으로 통과하게 만드는 쪽을 더 신뢰합니다. 제 기준에서 allow/ask/deny는 보안 기능이기 전에, 에이전트가 어느 지점에서 멈춰서 사람 판단을 받아야 하는지 선명하게 만드는 장치입니다. 자동화가 오래 버티려면 속도보다 경계선이 먼저여야 했습니다.
자주 묻는 질문 (FAQ)
Q1. allow/ask/deny 패턴 문법은 어떻게 되나요?
도구이름(패턴) 형식입니다. Read(*)는 모든 파일 읽기를 허용하고, Bash(npm test:*)는 npm test로 시작하는 셸 명령을 허용합니다. 와일드카드 *로 범위를 조절합니다.
Q2. permission mode와 allow/deny는 뭐가 다른가요? allow/deny는 개별 도구 단위의 규칙이고, permission mode는 전체 기본 엄격도입니다. allow/deny에 매칭되지 않는 행동이 permission mode에 따라 “물어볼지(plan), 자동 실행할지(auto)” 결정됩니다.
Q3. plan 모드에서 auto로 전환하는 적절한 시점은? 최소 3일 이상 plan 모드로 에이전트의 판단 패턴을 관찰한 뒤, “이 도구는 안전하다”고 확인된 것들을 allow에 추가하면서 default 모드로 전환하세요. auto는 CI/CD 같은 완전 신뢰 환경에서만 권장합니다.
Q4. 팀 프로젝트에서 settings.json은 어디에 두나요?
프로젝트 루트의 .claude/settings.json에 둡니다. 이 파일을 git에 커밋하면 팀원 모두 같은 권한 규칙을 공유할 수 있습니다. 개인 설정은 ~/.claude/settings.json에 따로 둡니다.
Q5. Hooks를 깨면 에이전트 실행이 멈추나요? PostToolUse 훅이 non-zero exit code로 종료하면 에이전트는 실패 결과를 받아 다음 루프에서 고려합니다(강제 중단은 아님). PreToolUse 훅이 차단(exit 2)하면 해당 도구 호출이 취소됩니다. 훅이 너무 엄격하면 에이전트가 막히므로 처음에는 로깅만 하고, 점진적으로 차단 조건을 추가하세요. 훅 설계 전반은 (8/8) 검증과 반복 편에서 더 자세히 다룹니다.
마무리
- 권한의 기본은 allow / ask / deny 3단계 + permission mode 3단입니다.
- 실무에서는 “읽기는 allow, 쓰기는 ask + 훅, 위험 패턴은 deny”의 최소 권한 파이프라인이 가장 안정적입니다.
- 처음에는 plan 모드로 관찰 → 안전한 것만 점진적으로 allow로 올리는 순서를 지키세요.
다음에 읽으면 좋은 글
- (4/8) 도구 설계 — 어떤 도구를 노출할지 결정한 뒤에야 권한을 설계합니다
- (7/8) 역할 분리 — subagent별 권한 분리
- (8/8) 검증과 반복 — Hooks 활용 심화