Claude Code 권한 설정 가이드: 안전한 settings.json 작성법
allow, ask, deny의 차이부터 안전한 settings.json과 점검 스크립트까지 초보자 눈높이로 설명합니다.
Claude Code에 테스트만 맡기고 싶은데 명령을 실행할 때마다 확인 창이 뜰 수 있습니다. 그렇다고 Bash 전체를 허용하면 파일 삭제, hard reset, force push까지 확인 없이 실행될 가능성이 생깁니다.
해결책은 모든 작업을 막거나 모두 허용하는 양자택일이 아닙니다. 읽기와 테스트는 자동 허용하고, 수정은 실행 전에 묻고, 비밀 정보와 파괴적 명령은 항상 거부하면 됩니다. 이 세 단계를 .claude/settings.json에 작성합니다.
이 글의 핵심
- 규칙은 deny → ask → allow 순서로 평가됩니다. 거부, 확인, 자동 허용 순입니다.
- 프로젝트 내부 읽기는 기본적으로 확인이 필요 없습니다. 검토한 테스트만 allow, 편집·외부 접근·push는 ask, 비밀 정보와 파괴적 작업은 deny로 둡니다.
Bash(git *)는 범위가 너무 넓습니다.git reset --hard와git push --force도 포함될 수 있으므로 안전한 명령을 개별 지정합니다.Read(.env)만으로 자식 프로세스의 파일 접근까지 완전히 막을 수 없습니다. 강한 격리가 필요하면 sandbox와 OS 권한도 함께 사용합니다.- 저장한 뒤
/permissions와/status에서 어떤 설정 파일의 규칙이 적용됐는지 확인합니다.
Claude Code에 맡길 범위와 사람이 판단할 범위
| Claude Code에 맡기기 | 사람이 확인하기 | 항상 차단하기 |
|---|---|---|
| 파일 검색, diff 확인, 테스트 | 파일 편집, commit, push, 의존성 추가 | 비밀 정보 읽기, force push, hard reset, 대량 삭제 |
Read, Grep, git diff | Edit, git commit, npm install | .env, git push --force, git reset --hard, rm -rf |
되돌리기 어렵거나 외부로 데이터를 보내거나 인증 정보에 접근하는 작업은 ask 또는 deny에 둡니다.
먼저 적용할 settings.json
프로젝트 루트에 .claude/settings.json을 만들고 아래 설정으로 시작합니다. 팀에서 공유하기 좋은 보수적인 기본값입니다.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm test *)",
"Bash(npm run lint *)"
],
"ask": [
"Edit",
"WebFetch",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git push *)",
"Bash(git clean *)",
"Bash(git restore *)",
"Bash(npm install *)",
"Bash(npm uninstall *)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(**/secrets/**)",
"Edit(.env)",
"Edit(.env.*)",
"Edit(**/secrets/**)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(rm -rf *)",
"Bash(rm *)",
"PowerShell(Remove-Item *)"
]
}
}
이 기준은 package.json scripts를 이미 확인한 저장소용입니다. 처음 보는 저장소라면 allow를 비워 두고 테스트 명령이 실제로 무엇을 실행하는지 읽은 뒤 추가하세요. Bash(npm test *)는 npm test와 인수가 붙은 형태 모두에 일치합니다.
settings.json을 둘 위치
| 종류 | 경로 | 용도 |
|---|---|---|
| User | ~/.claude/settings.json | 내 모든 프로젝트에 공통으로 적용할 설정 |
| Project | .claude/settings.json | Git으로 공유하는 팀 표준 |
| Local | .claude/settings.local.json | 이 컴퓨터에서만 쓰는 개인 설정. Git에 넣지 않음 |
| Managed | 관리자가 배포하는 설정 | 조직에서 프로젝트가 덮어쓸 수 없게 하는 규칙 |
우선순위는 Managed, 명령줄, Local, Project, User 순입니다. 다만 permissions.allow 같은 배열은 scope 사이에서 합쳐지며 통째로 교체되지 않습니다. deny는 어느 범위에 있더라도 ask와 allow보다 먼저 평가됩니다. 팀 공통 규칙은 Project에, 구성원이 바꾸면 안 되는 조직 정책은 Managed에 둡니다.
allow, ask, deny 규칙 읽는 법
| 규칙 | 의미 |
|---|---|
Read | 모든 내장 읽기와 일치. 프로젝트 내부 파일에는 보통 bare allow가 필요 없음 |
Bash(npm test) | npm test와 정확히 일치 |
Bash(npm test *) | npm test 뒤에 인수가 있는 형태와 일치 |
Bash(ls*) | ls -la뿐 아니라 lsof와도 일치할 수 있어 범위가 넓음 |
Read(//Users/me/secrets/**) | 파일 시스템의 절대 경로와 일치 |
Edit(/src/**/*.ts) | Project 설정이라면 프로젝트 src 아래의 TypeScript 파일과 일치 |
WebFetch(domain:docs.anthropic.com) | 지정한 도메인으로 보내는 WebFetch와 일치 |
Bash(git *)에는 git push origin main과 git reset --hard가 모두 포함될 수 있습니다. 안전한 명령은 각각 따로 허용해야 합니다.
Read와 Edit만으로 비밀 정보를 완전히 지킬 수 없는 이유
Read와 Edit의 경로 패턴은 gitignore와 비슷한 형식을 사용합니다.
| 표기 | 기준 | 예시 |
|---|---|---|
//path | 파일 시스템 루트 | Read(//Users/me/secrets/**) |
~/path | 홈 디렉터리 | Read(~/.ssh/**) |
/path | 설정 파일의 기준 위치 | Project 설정의 Edit(/src/**) |
path 또는 ./path | 현재 작업 디렉터리 | Read(.env) |
맨 앞의 슬래시 한 개는 파일 시스템 절대 경로를 뜻하지 않습니다. Read(.env)는 Claude Code가 인식하는 내장 파일 도구를 제한하지만, Node.js나 Python 같은 자식 프로세스가 파일을 간접적으로 읽는 경로는 별개입니다.
인증 정보를 다루는 프로젝트라면 Claude Code sandbox 가이드도 적용하고 OS 수준에서 접근을 제한하세요. sandbox는 macOS, Linux, WSL2에서 동작하며 native Windows에서는 동작하지 않습니다. Windows에서는 WSL2나 격리 컨테이너를 쓰고 PowerShell deny도 유지하세요.
3가지 Use case
Use case 1: 개인 개발에서 테스트만 자동화하기
입력: 소스, 테스트, Git diff. 출력: 수정 제안과 테스트 결과. 사람의 확인: 편집, 의존성 설치, commit, push.
위의 최소 설정을 적용하고 편집은 ask에 남겨 둡니다. 반복해서 사용해도 안전하다고 확인된 읽기 또는 테스트 명령만 나중에 allow로 옮깁니다.
Use case 2: 팀 전체에서 위험한 명령 거부하기
입력: 허용 명령과 금지 작업 목록. 출력: Git으로 관리되는 팀 설정. 사람의 확인: deny 추가와 임시 예외 처리.
Project 설정에 .env, force push, hard reset을 막는 deny를 작성합니다. 프로젝트 구성원이 변경할 수 없어야 하는 규칙은 Managed 설정으로 옮깁니다.
Use case 3: 운영 저장소를 읽기 전용으로 조사하기
입력: 장애 로그와 Git 이력. 출력: 원인 후보와 수정 계획. 사람의 확인: 편집, 배포, 외부 전송.
시작할 때 Plan Mode를 선택합니다.
claude --permission-mode plan
쓰기가 필요해지면 작업 브랜치나 격리 환경으로 옮긴 뒤에 승인합니다.
구체적인 실패 사례 4가지
| 실수 | 원인 | 수정 방법 |
|---|---|---|
Bash(git *)를 allow | push와 hard reset까지 같은 패턴에 포함 | 부작용을 확인한 명령만 개별 allow |
deny Bash(aws *) 아래 allow Bash(aws s3 ls) 추가 | deny → ask → allow 순서라 더 구체적인 allow도 예외가 되지 않음 | deny 범위를 줄이거나 안전 작업을 별도 명령 경계로 분리 |
Read(.env)를 OS 경계로 오해 | 임의 Node.js·Python 자식 프로세스는 내장 Read/Edit 규칙으로 완전히 막지 못함 | sandbox denyRead 또는 credentials 설정 병행 |
| Local allow를 지웠는데 계속 실행 | User·Project·Local의 권한 배열이 합쳐짐 | /permissions에서 출처, /status에서 로드된 scope 확인 |
사고 패턴은Claude Code 보안 실패 사례, 전체 도입 점검은보안 모범 사례에서 이어서 확인할 수 있습니다.
permission mode 선택 기준
| 모드 | 알맞은 상황 | 주의점 |
|---|---|---|
default | 처음 보는 저장소 | 필요한 작업에서 확인 창이 나타남 |
acceptEdits | 변경 범위를 이해한 개발 작업 | 편집과 일반 파일 작업이 자동 승인될 수 있음 |
plan | 조사, 설계, 운영 장애의 읽기 전용 분석 | 소스 코드를 변경하지 않음 |
auto | 백그라운드 안전 판단을 쓰는 작업 | 분류기가 요청과의 일치 여부를 판단하므로 명시 deny를 함께 사용 |
dontAsk | 미리 허용한 작업만 무인 실행할 때 | 허용되지 않은 작업은 묻지 않고 거부됨 |
bypassPermissions | 폐기 가능한 컨테이너나 VM | 일반 PC나 운영 환경에서는 사용하지 않음 |
sandbox.autoAllowBashIfSandboxed의 기본값은 true입니다. sandbox 내부에서는 bare Bash ask가 생략될 수 있지만, Bash(git push *) 같은 내용 지정 ask, 명시 deny, Plan Mode 제한은 유지됩니다.
Pitfall: 넓은 allow를 Hook 하나로 보완하기
Bash 전체를 allow로 열고 위험한 명령만 PreToolUse hook으로 막으면, hook의 배치 오류나 실행 실패, 패턴 누락이 유일한 안전 경계를 무너뜨릴 수 있습니다.
원인: 허용 범위가 지나치게 넓고 hook 하나가 모든 차단 책임을 맡고 있습니다.
수정 방법: deny와 범위가 좁은 allow를 먼저 작성하고, hook은 동적 판단을 위한 추가 계층으로만 사용합니다. deny와 ask는 hook이 반환한 allow 결과보다 우선합니다.
복사해서 쓰는 설정 점검 스크립트
아래 스크립트는 .claude/settings.json을 JSON으로 읽을 수 있는지와 최소한의 위험 작업이 deny에 들어 있는지 확인합니다.
// scripts/check-claude-permissions.mjs
import { readFileSync } from "node:fs";
const path = ".claude/settings.json";
const settings = JSON.parse(readFileSync(path, "utf8"));
const deny = new Set(settings.permissions?.deny ?? []);
const required = [
"Read(.env)",
"Edit(.env)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(rm *)",
"PowerShell(Remove-Item *)",
];
const missing = required.filter((rule) => !deny.has(rule));
if (missing.length > 0) {
console.error(`누락된 deny 규칙: ${missing.join(", ")}`);
process.exit(1);
}
console.log("Claude Code 권한 최소 점검: OK");
node scripts/check-claude-permissions.mjs
이 검사는 안전을 완전히 증명하지 않습니다. 최소 deny가 실수로 사라진 상황을 CI에서 찾기 위한 검사입니다.
설정이 적용되지 않을 때 확인할 순서
/permissions에서 현재 규칙과 각 규칙의 출처 파일을 확인합니다./status에서 불러온 설정 계층을 확인합니다.Bash(ls *)와Bash(ls*),/path와//path처럼 공백과 경로 앵커가 다른 부분을 살핍니다.- Sandbox 자동 허용과 상위 범위의 deny 또는 ask를 확인합니다.
- 공유할 규칙을 임시 CLI 옵션에만 두지 말고
.claude/settings.json으로 되돌립니다.
정리
먼저 .claude/settings.json에 최소 설정을 넣고 /permissions에서 적용 여부를 확인하세요.
검토한 테스트만 allow, 편집과 외부 작업은 ask, 비밀 정보와 파괴적 작업은 deny에 둡니다. 실제 프로젝트에서 안전하다고 확인한 명령만 하나씩 추가합니다.
권한 템플릿을 다른 개발 규칙과 함께 도입하려면 Claude Code 학습 자료에서 설정 예시와 체크리스트를 확인할 수 있습니다.
공식 문서
- Configure permissions (Claude Code 공식)
- Claude Code settings (공식)
- Choose a permission mode (공식)
- Configure the sandboxed Bash tool (공식)
- Debug your configuration (공식)
- Security (공식)
- Hooks reference (공식)
실제로 테스트한 결과
2026년 7월 22일, 10개 언어의 JSON을 JSON.parse로 읽고 임시 프로젝트에서 Node.js 점검 스크립트를 실행했습니다. 필수 deny 6개가 있을 때 종료 코드 0, Bash(git reset --hard *)를 지웠을 때 코드 1과 누락 규칙을 확인했습니다. 이는 설정 변화를 찾는 검사일 뿐 안전성을 증명하지 않습니다. 자신의 환경에서도 /permissions와 /status를 확인하세요.
관련 글
Claude Code 권한 거절에서 복구하기: guardrail 을 약하게 만들지 않는 법
거절된 Claude Code 명령을 이유, 안전한 대안, 증거 명령, 재시도 조건으로 나누는 복구 workflow.
Claude Code 권한 세이프티 래더: 통제력을 잃지 않고 allow 넓히기
read-only에서 제한 편집, 검증 명령, deploy 확인까지 권한을 단계적으로 넓히는 방법.
Claude Code Permission Budget Loop: 권한, 비용, 로그를 5분에 점검하기
Claude Code의 allow/deny 규칙, 비용 한도, 실행 로그, 팀 인수인계를 점검하는 실전 루프.
무료 PDF: Claude Code 치트시트
이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.
개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.
작성자 소개
Masa
Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.