/Part 3: 안전성/다계층 권한 시스템
🛡️
Part 3고급⏱ 약 60분 · 3개 섹션

다계층 권한 시스템

신뢰의 아키텍처

다계층 권한 시스템 대표 이미지
이 챕터에서 배울 것
  • 권한 시스템은 validateInput → checkPermissions → rules → canUseTool 4단계
  • 8가지 소스에서 규칙을 로드하며 First-Source-Wins 정책 적용
  • ML 분류기(yoloClassifier, 52KB)로 자동 권한 결정 가능
전체 아키텍처에서 현재 위치
⚙️코어 엔진
🔧도구 시스템
🛡️보안
🧠컨텍스트
🤝멀티 에이전트
🌐생태계
인프라
1

권한 모드와 결정 흐름

default, plan, auto, bypass 모드와 4단계 결정 과정

권한 모드규칙 평가결정 흐름사용자 프롬프트|utils/permissions/permissions.tsutils/permissions/PermissionMode.ts

Claude Code의 권한 시스템은 26개 모듈로 구성된 다계층 보안 시스템입니다. 핵심은 src/utils/permissions/permissions.ts로, 피처 게이트를 통해 ML 분류기까지 통합합니다.

src/utils/permissions/ — 모드와 분류기
1// src/utils/permissions/permissions.ts — 핵심 권한 엔진
2
3// 피처 게이트로 ML 분류기 조건부 로드
4const classifierDecisionModule = feature('TRANSCRIPT_CLASSIFIER')💡
5 ? require('./classifierDecision.js')
6 : null
7const autoModeStateModule = feature('TRANSCRIPT_CLASSIFIER')
8 ? require('./autoModeState.js')
9 : null
10
11// src/utils/permissions/PermissionMode.ts — 권한 모드 정의
12const PERMISSION_MODE_CONFIG = {
13 default: {
14 title: 'Default', symbol: '', color: 'text',
15 // → 사용자에게 확인 요청
16 },
17 plan: {
18 title: 'Plan Mode', symbol: PAUSE_ICON, color: 'planMode',
19 // → 실행 전 계획 승인 필요
20 },
21 acceptEdits: {
22 title: 'Accept edits', color: 'autoAccept',
23 // → 파일 편집 자동 허용
24 },
25 bypassPermissions: {💡
26 title: 'YOLO Mode', color: 'error',
27 // → 모든 권한 확인 건너뛰기 (위험!)
28 },
29 auto: {
30 title: 'Auto', color: 'autoAccept',
31 // → ML 분류기가 자동 결정 (내부 전용)
32 },
33}
🛡️

권한 결정 시뮬레이터

빠른 선택:
적용된 규칙:
allowBash(git *)User Settings
allowBash(npm test)User Settings
allowGlobToolUser Settings
allowGrepToolUser Settings
denyBash(rm -rf *)Project Settings
denyFileEdit(.env*)Project Settings
askBash(docker *)Project Settings
2

규칙 시스템과 소스 우선순위

8가지 규칙 소스와 매칭 패턴

규칙 소스패턴 매칭파일 시스템 권한경로 해석|utils/permissions/permissionsLoader.tsutils/permissions/filesystem.ts

권한 규칙은 8가지 소스에서 로드되며, 명확한 우선순위를 따릅니다. 규칙은 PermissionRule 타입으로 통일됩니다.

권한 규칙 소스와 매칭
1// 규칙 소스 우선순위 (높은 → 낮은)💡
2// 1. Remote Managed Settings ← 원격 동기화 (최우선)
3// 2. MDM/Registry ← macOS plist / Windows 레지스트리
4// 3. Managed File ← managed-settings.json + drop-ins
5// 4. Flag Settings ← --flag-settings CLI 인자
6// 5. Policy Settings ← 최우선 소스에서 병합
7// 6. User Settings ← ~/.claude/settings.json
8// 7. Project Settings ← .claude/settings.json
9// 8. Local Settings ← .claude/settings.local.json
10
11// src/utils/settings/settings.ts — 설정 로드
12export function loadManagedFileSettings() {
13 // managed-settings.json이 기본 (lowest precedence)
14 // managed-settings.d/*.json이 알파벳순으로 위에 병합💡
15 // → systemd/sudoers drop-in 컨벤션과 동일
16 let merged: SettingsJson = {}
17 // base file
18 const base = readFileSync(getManagedSettingsFilePath())
19 merged = mergeWith(merged, base, settingsMergeCustomizer)
20 // drop-in files (10-otel.json, 20-security.json, ...)
21 for (const dropIn of sortedDropIns) {
22 merged = mergeWith(merged, dropIn, settingsMergeCustomizer)
23 }
24 return merged
25}
26
27// 규칙 매칭 예시
28type PermissionRule = {💡
29 source: 'userSettings' | 'projectSettings' | 'policySettings' | ...
30 ruleBehavior: 'allow' | 'deny' | 'ask'
31 ruleValue: {
32 toolName: string // "Bash", "FileEdit" 등
33 ruleContent?: string // "git *", "src/**/*.ts" 등
34 }
35}
3

자동 분류기 시스템

ML 기반 자동 권한 결정과 YOLO 분류기

분류기위험도 점수거부 추적피처 게이트|utils/permissions/classifierDecision.tsutils/permissions/yoloClassifier.ts

자동 모드에서는 ML 분류기가 도구 실행 허용 여부를 결정합니다. yoloClassifier.ts(52KB)는 규칙 기반 + 휴리스틱을 결합한 폴백 분류기입니다.

자동 분류기 시스템
1// 자동 분류기 흐름
2// 1. 도구가 toAutoClassifierInput(input)으로 분류 입력 생성
3// 2. 분류기가 위험도 점수 산출
4// 3. 거부 횟수 추적으로 "무한 거부 루프" 방지
5
6// src/utils/permissions/classifierDecision.ts
7async function getClassifierDecision(tool, input, context) {
8 const classifierInput = tool.toAutoClassifierInput(input)
9 if (!classifierInput) return { decision: 'allow' } // 분류 건너뛰기💡
10
11 const score = await classify(classifierInput, context)
12
13 // 거부가 연속되면 임계값 완화 (무한 거부 방지)
14 const denialState = getDenialTracking(context)💡
15 if (denialState.consecutiveDenials > MAX_CONSECUTIVE_DENIALS) {
16 return { decision: 'allow', reason: 'denial_limit_reached' }
17 }
18
19 return score > THRESHOLD
20 ? { decision: 'deny', reason: score }
21 : { decision: 'allow' }
22}