퍼미션 설정 최적화 — allow·deny·ask
퍼미션은 Claude Code가 어떤 조작을 자동 실행하고 어떤 조작을 확인·차단할지 정하는 설정입니다. allow·deny·ask 문법과 우선순위, defaultMode 비교, 복붙용 추천 설정을 정리합니다.
퍼미션(permission)은 Claude Code가 어떤 조작을 확인 없이 실행하고, 어떤 조작을 물어보거나 차단할지 정하는 설정입니다. 기본값은 변경을 동반하는 조작마다 확인 창이 뜨는 상태라 매번 승인하기는 번거롭고, 그렇다고 전부 허용하면 AI 에이전트가 rm -rf로 디렉터리를 날린 해외 사례처럼 되돌릴 수 없는 사고를 막을 길이 없습니다. 퍼미션을 제대로 잡으면 "안전한 조작은 자동, 위험한 조작은 차단"이라는 균형을 파일 하나로 고정할 수 있습니다.
핵심 요약
- 규칙은 allow(자동 실행)·deny(차단)·ask(확인 강제) 세 가지입니다
- 우선순위는 Deny > Ask > Allow 입니다
- Bash 패턴은 공백 뒤
*와일드카드로 매치하고, 정규식과**는 쓸 수 없습니다 defaultMode가 규칙에 없는 조작의 기본 동작을 정합니다/permissions로 현재 규칙을,/doctor로 설정 문제를 확인합니다
퍼미션은 어떤 도구를 제어하나
퍼미션은 도구 종류별로 카테고리가 나뉩니다. 자주 손대는 것은 다음 다섯 가지입니다.
| 카테고리 | 제어 대상 | 패턴 예 |
|---|---|---|
| Bash | 셸 명령 실행 | Bash(npm run test *) |
| Read | 파일 읽기 | Read(.env) |
| Edit | 기존 파일 편집 | Edit |
| Write | 새 파일 생성 | Write(**/.env*) |
| WebFetch | 외부 URL 접근 | WebFetch |
이 밖에 PowerShell, MCP, Agent(서브에이전트), Cd 카테고리가 있습니다. 도구 이름만 쓰면(Read) 그 도구 전체가, 괄호 안에 패턴을 쓰면(Read(.env)) 그 패턴에 맞는 조작만 대상이 됩니다.
{
"permissions": {
"allow": ["Read", "Edit", "Write", "Bash(npm run test *)"],
"deny": ["Bash(rm -rf *)", "Read(.env)", "Read(.env.*)", "WebFetch"]
}
}코드 읽기·편집·생성은 열어 두되, API 키가 들어 있기 쉬운 .env 계열은 막고, 외부 통신이 필요 없는 프로젝트라면 WebFetch를 꺼 두는 구성입니다. Bash는 가장 중요한 카테고리이니 "개발에 필요한 명령만 허용"을 원칙으로 삼으세요.
allow·deny·ask 세 규칙은 어떻게 다른가
| 규칙 | 동작 | 넣을 것 |
|---|---|---|
| allow | 매치하면 확인 없이 자동 실행 | 자주 쓰는 안전한 명령 |
| deny | 매치하면 완전히 차단 | 위험 명령, 기밀 파일 |
| ask | allow에 있어도 매번 확인 창 표시 | 평소엔 자동이지만 이것만은 확인하고 싶은 조작 |
ask는 "git은 자동으로 돌리되 push만은 확인하고 싶다" 같은 요구에 씁니다.
{
"permissions": {
"allow": ["Bash(git *)"],
"ask": ["Bash(git push *)"]
}
}우선순위는 Deny > Ask > Allow
같은 조작이 여러 규칙에 매치하면 deny가 가장 세고, 다음이 ask, 마지막이 allow입니다. allow에 Bash(echo *), deny에 Bash(echo secret *)가 있으면 echo hello는 자동 실행되지만 echo secret data는 거부됩니다. allow와 ask가 충돌하면 ask가 이겨서 확인 창이 뜹니다. "기본은 OK, 특정 케이스만 확인"이 이 구조로 가능해집니다.
Bash 패턴은 어떻게 쓰나
Bash 패턴은 * 와일드카드 매칭입니다. 기본은 **공백 뒤에 *** 를 붙이는 것이며, *는 끝뿐 아니라 앞이나 중간에도 둘 수 있습니다.
| 패턴 | 매치하는 예 |
|---|---|
Bash(npm run *) | npm run test, npm run build |
Bash(* --version) | node --version, npm --version |
Bash(git * main) | git checkout main, git merge main |
* 앞의 공백 유무로 매치 범위가 달라집니다.
Bash(ls *)→ls -la에는 매치하지만lsof에는 매치하지 않습니다Bash(ls*)→ls -la와lsof모두 매치합니다
공백이 있으면 단어 경계가 적용돼 엉뚱한 명령에 매치할 위험이 줄어드니, 기본은 공백을 넣는 쪽을 추천합니다.
Bash(npm:*)처럼 콜론+별표로 끝 와일드카드를 쓰는 표기도 지원되며 Bash(npm *)와 동작이 같습니다. 다만 확인 창에서 "Yes, don't ask again"을 골랐을 때 자동 생성되는 것은 공백 표기이므로, 한 파일 안에서는 그쪽으로 맞추면 통일감이 생깁니다.
흔한 실수로 정규 표현식(Bash(echo .*))이나 glob의 **(Bash(rm -rf **))를 쓰는 경우가 있는데, 둘 다 동작하지 않습니다.
Read·Edit 경로는 어떻게 쓰나
Read·Edit·Write의 패턴은 .gitignore와 같은 표기법을 씁니다. 경로 앞머리에 따라 기준 위치가 달라집니다.
| 표기 | 의미 | 예 |
|---|---|---|
//path | 파일 시스템 루트 기준 절대 경로 | Read(//Users/alice/secrets/**) |
~/path | 홈 디렉터리 기준 | Read(~/Documents/*.pdf) |
./path 또는 path | 현재 디렉터리 기준 상대 경로 | Read(.env) |
기밀 파일을 막을 때는 Read(.env), Read(.env.*), Read(**/secrets/**)처럼 변형까지 함께 deny에 넣어 두세요.
defaultMode 세 가지 비교
defaultMode는 어느 규칙에도 매치하지 않은 조작을 어떻게 다룰지 정합니다.
| 모드 | 자동 승인 범위 | 적합한 상황 |
|---|---|---|
default | 읽기 전용 조작만 자동. 편집·Bash는 첫 사용 시 확인 | 기본값. 보안 최우선 |
acceptEdits | 읽기에 더해 파일 편집까지 자동 승인 | 편집 위주 작업을 빠르게 돌릴 때 |
bypassPermissions | 기본 확인 창을 전부 건너뜀 (--dangerously-skip-permissions와 동일) | 샌드박스처럼 망가져도 되는 환경 |
"permissions": { "defaultMode": "acceptEdits" }처럼 permissions 블록 안에 씁니다. bypassPermissions는 위험하니 꼭 필요한 경우에만, 가능하면 샌드박스 환경에서 쓰세요. 퍼미션과 별도로 Hooks로 위험 명령을 차단하는 장치를 겹쳐 두면 더 견고해집니다.
복붙해서 쓰는 균형형 설정
많은 프로젝트에 그대로 쓸 수 있는 범용 설정입니다. rm -rf 사고를 막으면서 개발 효율도 확보하는 구성입니다.
{
"permissions": {
"allow": [
"Bash(ls *)",
"Bash(cat *)",
"Bash(echo *)",
"Bash(touch *)",
"Bash(mkdir *)",
"Bash(cp *)",
"Read",
"Edit",
"Write"
],
"deny": [
"Bash(sudo *)",
"Bash(rm -rf *)",
"Bash(git reset *)",
"Bash(git rebase *)",
"Bash(wget *)",
"Read(**/.env*)",
"Read(id_rsa)",
"Read(id_ed25519)",
"Read(**/*token*)",
"Read(**/*key*)",
"Write(**/.env*)",
"Write(**/secrets/**)"
],
"ask": [
"Bash(rm *)",
"Bash(mv *)",
"Bash(curl *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git push *)",
"Bash(git merge *)"
]
}
}- deny로 절대 막을 것:
sudo(root 권한),rm -rf(되돌릴 수 없는 삭제),git reset·git rebase(히스토리 수정),wget(무단 다운로드),.env·SSH 키·토큰 파일(기밀 접근) - ask로 확인을 끼울 것:
rm·mv(삭제·이동),curl(외부 통신),git add·commit·push·merge(리포지토리 변경) - allow로 자동화할 것:
ls·cat·echo(조회),touch·mkdir·cp(생성·복사), Read·Edit·Write(코드 편집)
이 설정을 베이스로 프로젝트 특성에 맞춰 다듬어 가는 것을 추천합니다. 승인 대기가 답답하다면 git 조작까지 allow로 올리는 스피드형도 가능하지만, 그만큼 실수가 바로 반영된다는 점은 감수해야 합니다.
프로젝트별로 더하는 규칙
위 베이스에 언어별 규칙을 얹습니다. 공통 원칙은 "테스트·빌드·린트는 허용, 패키지 설치·삭제는 확인"입니다.
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(npm test *)",
"Bash(npx tsc *)",
"Bash(npx prettier *)",
"Bash(npx eslint *)"
],
"ask": [
"Bash(npm install *)",
"Bash(npm uninstall *)"
]
}
}Python 프로젝트라면 같은 요령으로 Bash(python *)·Bash(pytest *)·Bash(ruff *)·Bash(mypy *)를 allow에, Bash(pip install *)·Bash(pip uninstall *)·Bash(uv add *)·Bash(uv remove *)를 ask에 둡니다.
기밀성이 높은 프로젝트라면 셸 명령을 전면 금지하고 파일 조작만 허용하는 방법도 있습니다. 개발 효율은 떨어지지만 가장 안심되는 구성이니, 필요할 때 허용 명령을 하나씩 늘려 가세요.
{
"permissions": {
"allow": ["Read", "Edit"],
"deny": ["Bash(*)", "WebFetch"]
}
}설정 파일은 어디에 두나
퍼미션은 세 곳에 둘 수 있고, 위에 있는 것이 우선합니다.
.claude/settings.local.json— 개인 로컬 설정..gitignore에 넣어 Git에서 제외.claude/settings.json— 프로젝트 설정. 커밋해서 팀과 공유~/.claude/settings.json— 사용자 설정. 모든 프로젝트에 공통 적용
팀 공통 규칙(금지 명령, 표준 검증 명령)은 프로젝트 설정에, 각자의 취향이나 추가 허용은 로컬 설정에 두는 구분이 효과적입니다. 파일 구조와 다른 옵션은 settings.json 설정에서 다룹니다.
프로젝트 디렉터리 밖의 파일에 접근해야 한다면 additionalDirectories를 씁니다. 모노레포나 공유 라이브러리가 있을 때 유용하고, /add-dir 커맨드로 세션 중에 추가할 수도 있습니다.
{
"permissions": {
"additionalDirectories": ["../shared-libs/", "~/dotfiles/"]
}
}접근 범위가 넓어지는 만큼 꼭 필요한 디렉터리만 지정하세요.
실제 검증에서 드러난 주의점
아래는 2026년 8월 검증 시점의 동작이며, Claude Code 업데이트에 따라 바뀔 수 있습니다. allow·deny·ask의 기본 동작, 와일드카드 매칭, Deny > Ask > Allow 우선순위, /permissions 표시는 모두 기대대로 동작했습니다. 예상과 달랐던 것은 두 가지입니다.
deny는 도구 단위라 우회될 수 있습니다. Bash(cat *)를 deny해도 Claude가 Read 도구나 echo 명령으로 파일 내용을 가져오는 경우가 있었습니다. 같은 목적을 이루는 도구가 여러 개이기 때문입니다. 완전히 막고 싶다면 Read(.env)처럼 파일 쪽에 deny를 걸고, 관련 도구를 함께 제한해야 합니다.
**--dangerously-skip-permissions도 deny·ask는 지킵니다.** 이름 때문에 deny까지 무시될 것 같지만, 실제로는 permissions 설정이 우선합니다. deny 규칙과 명시적으로 설정한 ask 규칙은 유효하고, 건너뛰는 것은 allow 규칙이 없는 조작에 뜨는 기본 확인 창뿐입니다. 확인을 강제하고 싶은 조작은 ask에 명시해 두는 것이 확실합니다. 조건부로 도구 실행을 막고 싶다면 훅 종료 코드로 제어에서 다루는 종료 코드 2가 더 세밀한 수단입니다.
설정이 안 먹을 때 확인할 것
/doctor— 설치 상태와 설정 파일을 점검하고 문제가 있으면 수정 방법까지 제안합니다. 터미널의claude doctor는 설치·자동 업데이트 쪽 진단에 집중합니다./permissions— 현재 규칙을 Allow·Ask·Deny 탭으로 보여 줍니다. 좌우 방향키로 탭을 옮기고, 아래 방향키로 개별 규칙을 고르거나 "Add a new rule…"로 새 규칙을 추가합니다./status— 설정 파일을 저장하면 자동으로 다시 읽히는데, 반영 여부는 여기서 확인합니다. 세션 전반의 상태 확인은 세션 관리를 참고하세요.
정리
- 카테고리는 Bash·Read·Edit·Write·WebFetch가 중심이고 PowerShell·MCP·Agent·Cd도 있습니다
- 규칙은 allow·deny·ask 세 가지, 우선순위는 Deny > Ask > Allow 입니다
- Bash 패턴은 공백 뒤
*, 경로 패턴은.gitignore표기법을 따릅니다 --dangerously-skip-permissions를 써도 deny·ask는 유지되지만, 도구 단위 deny는 우회될 수 있습니다- 문제가 생기면
/doctor→/permissions→/status순으로 확인합니다
자주 묻는 질문
팀에 Claude Code를 도입하려면 실제 코드베이스에 맞춘 설계가 필요합니다.
무료 상담 신청