Skip to content

Claude Code 전역 설정 관리 — '전역'은 단일 파일이 아니라 5층 스택(Managed › Command line › Local › Project › User)이고 `~/.claude/settings.json`은 그 바닥, 두 규율(일반 설정은 높은 층이 덮고 permission 규칙은 모든 층이 쌓이되 deny가 먼저), `Tool(specifier)` 문법과 `Bash(ls *)`의 단어 경계·복합 명령 분해·래퍼 스트리핑, 인자 제한 패턴의 취약성과 curl deny + WebFetch(domain:) 대안, gitignore식 Read/Edit 경로(`//`절대·`~/`홈·`/`설정 기준)와 '한 슬래시는 절대경로가 아니다'는 함정, default(Manual)·acceptEdits·plan·auto·dontAsk·bypassPermissions 6개 모드, 그리고 셸이 아니라 `env` 블록에 넣어야 백그라운드까지 닿는 프록시·CA·mTLS

Published: at 09:25 PM

들어가며

42차시는 클라우드 무대의 법칙 한 줄로 닫혔다 — “저장소에 커밋된 것만 존재한다.” repo의 CLAUDE.md·훅·.mcp.json은 클라우드 세션에 따라왔지만, ~/.claude의 것들과 claude mcp add로 넣은 로컬 설정은 따라오지 않았다. 그 무대에 없던 것, 그게 바로 이번 차시의 주인공 ~/.claudeUser 스코프다.

이제 무대를 다시 내 머신으로 옮긴다. 커리큘럼의 세 목표는 명확하다 — ~/.claude/settings.json의 구조, 권한 설정 최적화, 프록시·네트워크 설정. 세 목표를 관통하는 척추는 하나다. 바로 **우선순위(precedence)**다. Claude Code에서 “이 설정이 먹히나?”라는 질문은 항상 “어느 층이 이기나, 그리고 그 층은 아래층을 덮나 아니면 아래층과 쌓이나?”로 환원된다.

그리고 첫 함정은 ‘전역’이라는 단어 자체에 있다. ~/.claude/settings.json하나의 전역 파일이 아니다. 이 차시로 섹션 10(설정과 고급 기능)이 열린다.

‘전역’은 5층 스택의 바닥이다

Claude Code 설정은 단일 파일이 아니라 다섯 개의 층이다. 같은 키가 여러 층에 나타나면 우선순위대로 적용된다. 공식 문서의 우선순위는 높은 것부터 다음과 같다.

순위범위파일성격
1 (최강)ManagedOS별 시스템 경로(아래)조직 정책, 오버라이드 불가
2Command line--permission-mode 등 플래그임시 세션 오버라이드
3Local.claude/settings.local.json개인 프로젝트 설정(gitignore)
4Project.claude/settings.json팀 공유(커밋)
5 (최약)User~/.claude/settings.json전 프로젝트 개인 기본값

~/.claude/settings.json — 우리가 흔히 ‘전역 설정’이라 부르는 그 파일 — 은 우선순위가 가장 낮다. 전 프로젝트에 걸쳐 적용되는 ‘내 기본값’이지만, 특정 프로젝트가 .claude/settings.json으로 값을 덮으면 프로젝트가 이긴다. ‘전역’은 ‘가장 넓게 퍼지는’이라는 뜻이지 ‘가장 강한’이라는 뜻이 아니다.

Managed 설정의 파일 경로는 OS마다 다르고, 이건 IT 관리자가 MDM으로 배포하는 자리다.

OSManaged 경로
macOS/Library/Application Support/ClaudeCode/managed-settings.json
Linux / WSL/etc/claude-code/managed-settings.json
WindowsC:\Program Files\ClaudeCode\managed-settings.json

관리형은 managed-settings.d/*.json 드롭인 디렉토리도 지원해서, 여러 팀이 정책 조각을 알파벳 순으로 병합해 얹을 수 있다(10-telemetry.json, 20-security.json처럼 숫자 접두로 순서를 준다). 22차시에서 본 CLAUDE.local.md의 ‘개인 오버라이드’ 감각이, 설정 파일 레벨에선 이 5층 구조로 굳어 있는 셈이다.

두 규율 — 설정은 덮어쓰고, 권한은 쌓인다

5층을 알았으면 그다음 질문은 “층이 겹칠 때 정확히 어떻게 되나”다. 여기서 규율이 둘로 갈린다. 이 차시에서 딱 하나만 가져간다면 이 문장이다.

When the same setting appears in multiple scopes, Claude Code applies them in priority order. Permission rules behave differently—they merge across scopes rather than override.

권한이 쌓인다는 게 왜 중요한가? 병합된 규칙 안에서 평가 순서가 deny → ask → allow로 고정돼 있기 때문이다.

Rules are evaluated in order: deny, then ask, then allow. The first match in that order determines the outcome, and rule specificity doesn’t change the order.

어느 층의 deny든, 다른 모든 층의 allow를 이긴다. 사용자 설정이 허용해도 프로젝트 설정이 거부하면 막히고, 그 반대도 성립한다. 규칙이 더 구체적이라고 순서가 바뀌지도 않는다 — Bash(aws s3 ls)를 allow해도 Bash(aws *) deny가 있으면 막힌다. deny 규칙은 예외(allowlist)를 품을 수 없다.

한 문장으로 요약하면 이렇다 — “설정은 덮어쓰고, 권한은 쌓인다. 그리고 어느 층의 NO든 모든 층의 YES를 이긴다.” 이 비대칭이 권한 최적화 전체의 토대다. 그래서 “이건 절대 안 돼”는 deny로 박고(어느 층에서든 전체를 잠근다), “이건 편하게 해줘”는 allow로 넓힌다(단 상위 deny에 언제든 막힐 수 있다).

deny에는 뉘앙스가 하나 더 있다. 툴 이름만 쓰면(Bash) 그 툴이 아예 Claude의 컨텍스트에서 사라진다. 반면 스코프를 붙이면(Bash(rm *)) 툴은 살아 있고 매칭되는 호출만 막힌다.

A bare tool name like Bash removes the tool from Claude’s context entirely, so Claude never sees it … A scoped rule like Bash(rm *) leaves the tool available and blocks matching calls when Claude attempts them.

~/.claude/settings.json 해부

이제 파일 자체를 연다. 최상단에 $schema를 넣으면 에디터가 자동완성·검증을 해준다.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "sonnet",
  "includeCoAuthoredBy": true,
  "cleanupPeriodDays": 30,
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1"
  },
  "permissions": {
    "defaultMode": "default",
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(secrets/**)",
      "Read(**/id_rsa)"
    ]
  }
}

키의 성격은 대략 이렇게 나뉜다.

역할비고
model기본 모델별칭 "sonnet"·"opus"·"haiku" 가능. 자세한 건 44차시
env모든 세션·하위 프로세스에 주입할 환경 변수프록시·CA·mTLS의 자리(뒤에서 다룸)
permissionsallow/ask/deny + defaultMode이 차시의 중심
hooks이벤트별 훅28~31차시. disableAllHooks로 일괄 차단
includeCoAuthoredBy커밋에 Co-Authored-By 트레일러38차시에서 본 그 태그
cleanupPeriodDays세션 파일 보관 일수기본 30, 최소 1
outputStyle출력 스타일44차시
statusLine상태줄 포맷"disabled"로 끔
apiKeyHelper동적 인증 키를 뱉는 스크립트볼트의 단명 토큰용

편집한 값이 언제 먹히나도 알아 둘 값어치가 있다. 대부분(permissions, hooks, env, apiKeyHelper 등)은 핫리로드된다 — 세션 중에 파일을 고치면 즉시 반영되고, ConfigChange 훅이 감지 시점에 발화한다. 예외는 둘이다. model은 시작 시에만 읽으므로 세션 중엔 /model로 바꾸고, outputStyle은 시스템 프롬프트의 일부라 /clear로 재구성해야 한다.

그럼 무엇을 ~/.claude에 두고 무엇을 프로젝트에 둘까? 5층 모델이 답을 준다. 에디터 모드(vim), 개인 상태줄, 내 볼트를 부르는 apiKeyHelper, 회사 프록시 — 이런 ‘나는 어디서 일하든 이렇게’ 값은 User 스코프(~/.claude). 팀 전체가 공유할 훅·권한 화이트리스트·additionalDirectories는 저장소의 .claude/settings.json. 23차시의 협업 원칙(“팀과 공유할 건 저장소에 커밋”)이 여기서도 그대로 적용된다. 그리고 42차시가 왜 ~/.claude를 클라우드에서 못 봤는지도 이제 분명하다 — 그건 User 스코프고, 클라우드 무대엔 저장소만 클론되니까.

권한 최적화 ① — 규칙 문법을 정확히

두 번째 목표, 권한 최적화. 17차시에서 권한 시스템의 뼈대(읽기 전용은 자동, 수정·실행은 승인)를 봤다면, 이번엔 그 규칙을 정밀하게 쓰는 법이다. 규칙은 /permissions로 보고 관리하며, “Yes, don’t ask again”으로 승인한 규칙은 저장소 루트의 .claude/settings.local.json에 쌓인다.

규칙 문법은 Tool 또는 Tool(specifier). 괄호 없이 툴 이름만 쓰면 그 툴의 모든 사용에 매치된다(Bash(*)Bash와 동일).

Bash 패턴이 가장 까다롭고, 여기서 실수가 나온다. 와일드카드 *는 어느 위치에나 올 수 있는데, 끝의 공백이 단어 경계를 만든다.

The space before * matters: Bash(ls *) matches ls -la but not lsof, while Bash(ls*) matches both.

이 차이를 모르면 Bash(ls*)처럼 경계 없는 규칙을 써서 의도보다 넓게 허용하게 된다.

복합 명령은 더 중요하다. Claude Code는 셸 연산자를 안다 — 그래서 Bash(safe-cmd *)safe-cmd && other-cmd를 허용하지 않는다.

The recognized command separators are &&, ||, ;, |, |&, &, and newlines. A rule must match each subcommand independently.

구분자로 쪼갠 하위명령 각각이 규칙에 매치돼야 전체가 허용된다. 이게 없다면 Bash(echo *) 하나로 echo hi && rm -rf /가 통과할 것이다.

래퍼 스트리핑도 알아 둔다. Claude Code는 매칭 전에 고정된 래퍼 집합을 벗겨낸다 — timeout, time, nice, nohup, stdbuf, 셸 빌트인 command·builtin, zsh의 noglob. 그래서 Bash(npm test *)timeout 30 npm test도 매치한다. 그런데 함정은 벗겨지지 않는 것들이다.

Development environment runners such as direnv exec, devbox run, mise exec, npx, and docker exec are not in the list. Because these tools execute their arguments as a command, a rule like Bash(devbox run *) matches whatever comes after run, including devbox run rm -rf ..

Bash(devbox run *)devbox run rm -rf .까지 허용해 버린다. 환경 러너 뒤의 것을 통째로 허용하니까. 그래서 러너는 내부 명령까지 명시해서 Bash(devbox run npm test)처럼 한 줄씩 좁혀 써야 한다.

참고로 프롬프트 없이 도는 읽기 전용 세트가 있다 — ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd, 그리고 읽기 전용 형태의 git. 이 집합은 설정으로 바꿀 수 없고, 특정 명령을 굳이 막고 싶으면 askdeny를 건다.

권한 최적화 ② — 취약한 패턴과 견고한 대안

여기가 최적화의 핵심 교훈이다. 인자를 제한하려는 Bash 패턴은 신뢰할 수 없다. 공식 문서가 직접 경고한다.

Bash permission patterns that try to constrain command arguments are fragile. For example, Bash(curl http://github.com/ *) intends to restrict curl to GitHub URLs, but won’t match variations like…

Bash(curl http://github.com/ *)로 curl을 GitHub URL로 묶으려 해도, 이렇게 새어 나간다.

그래서 URL을 제대로 걸러 내려면 접근을 뒤집는다.

  1. 네트워크 명령을 deny로 막는다curl, wget 등을 deny에 넣고,
  2. WebFetch 툴에 도메인을 화이트리스트한다WebFetch(domain:github.com).
{
  "permissions": {
    "deny": ["Bash(curl *)", "Bash(wget *)"],
    "allow": ["WebFetch(domain:github.com)"]
  }
}

WebFetch 규칙은 domain: 접두로 호스트명을 매치한다 — WebFetch(domain:*.example.com)은 임의 깊이의 서브도메인을 잡되 example.com 자신은 잡지 않는다. 단, 문서가 붙이는 단서가 있다 — Bash가 허용돼 있으면 WebFetch만으로 네트워크를 못 막는다. Claude가 여전히 curl로 아무 URL이나 칠 수 있으니, deny와 짝지어야 실제 경계가 선다.

권한 최적화 ③ — Read/Edit 경로와 ‘한 슬래시’ 함정

파일 접근은 Read·Edit 규칙으로 잡는다(Edit은 파일을 고치는 모든 내장 툴에 적용된다). 경로는 gitignore 문법이고, 앵커가 네 종류다.

패턴앵커
//path파일시스템 루트(절대경로)Read(//Users/alice/secrets/**)
~/path홈 디렉토리Read(~/.zshrc)
/path설정 소스 기준프로젝트 설정의 Edit(/src/**)<프로젝트 루트>/src/**
path / ./path현재 디렉토리 기준Read(*.env)<cwd>/*.env

세 번째 줄이 함정이다. 공식 문서가 못 박는다.

A pattern like /Users/alice/file isn’t an absolute path. The single leading slash anchors at the settings source, not the filesystem root. Use //Users/alice/file for absolute paths.

/Users/alice/file절대경로가 아니다. 슬래시 하나는 설정 소스에 앵커링된다. 절대경로를 원하면 슬래시 둘 — //Users/alice/file. 이 때문에 사용자 설정에 Read(/secrets/**)를 쓰면 프로젝트의 secrets/가 아니라 ~/.claude/secrets/**를 막는다. 매 프로젝트에 걸쳐 적용하려면 //(절대) 또는 ~/(홈)를 써야 한다.

다행히 맨몸 파일명은 gitignore 의미대로 어느 깊이에서나 매치된다 — Read(.env)Read(**/.env)와 동등하다. 그래서 앞의 ~/.claude 예시처럼 denyRead(.env), Read(.env.*), Read(secrets/**)를 넣으면 현재 작업 디렉토리 아래 어디에 있든 시크릿 파일 읽기가 막힌다. 45차시(보안·프라이버시)에서 이 시크릿 보호를 더 파겠지만, 골격은 여기서 선다.

경계도 정직하게 알아 둔다. Read/Edit deny는 Claude의 내장 파일 툴과, Claude Code가 인식하는 bash 파일 명령(cat, head, tail, sed)에는 적용되지만, 파일을 직접 여는 임의 서브프로세스(예: 파이썬·노드 스크립트)에는 적용되지 않는다. 모든 프로세스를 OS 레벨에서 막으려면 샌드박스가 필요하다 — 이건 45차시의 몫이다.

권한 최적화 ④ — 여섯 개의 권한 모드

규칙이 ‘무엇을 허용/차단하나’라면, 모드는 ‘기본적으로 얼마나 물어보나’의 베이스라인이다. 17차시엔 모드가 몇 개뿐이었지만, 지금은 여섯이다.

모드무프롬프트로 도는 것활성화
default (CLI 라벨 Manual)읽기만기본. manual 별칭(v2.1.200+)
acceptEdits읽기 + 파일 편집 + mkdir·touch·rm·mv·cp·sed 등(작업 디렉토리 한정)Shift+Tab
plan읽기 + 탐색(소스 미편집)Shift+Tab, /plan
auto전부(백그라운드 분류기가 안전 검사)계정 요건 충족 시
dontAsk사전 승인된 툴만(나머지 자동 거부)--permission-mode dontAsk
bypassPermissions전부(위험)--dangerously-skip-permissions

Shift+Tab기본 사이클은 default → acceptEdits → plan 셋뿐이다. auto·dontAsk·bypassPermissions는 조건을 갖춰야 사이클에 끼거나 플래그로만 켜진다. 시작 모드는 --permission-mode 플래그로, 또는 설정의 defaultMode로 고정한다.

{ "permissions": { "defaultMode": "acceptEdits" } }

여기 5층 모델과 맞물리는 안전장치가 있다. defaultMode: "auto"는 project/local 설정에서 무시되고 user 설정에서만 먹힌다.

Claude Code v2.1.142 and later ignore auto from those files so a repository cannot grant itself auto mode. Move it to ~/.claude/settings.json.

저장소가 체크인한 설정만으로 스스로 auto 모드를 켜지 못하게 한 것이다 — 낯선 저장소를 클론했을 때의 방어선이다. ~/.claude에 두는 게 auto의 유일한 상시 자리인 이유다.

반대로 조직이 위험 모드를 잠그려면 permissions.disableBypassPermissionsMode(그리고 disableAutoMode)를 "disable"로 둔다. 어느 스코프에서든 동작하지만, 오버라이드 불가한 managed 설정에 두는 게 정석이다. 개인이 자기 발등을 찍지 않으려고 자기 ~/.claude에 걸 수도 있다.

모드와 무관하게 **절대 자동 승인되지 않는 경로(protected paths)**도 있다 — .git, .claude, .vscode, .husky, .cargo, .devcontainer, 셸 dotfile(.zshrc 등), .mcp.json, .claude.json 등. bypassPermissions를 제외한 모든 모드에서 이 경로 쓰기는 프롬프트를 띄우고, allow 규칙으로도 못 뚫는다. 그리고 bypassPermissions에서도 rm -rf /·rm -rf ~는 서킷 브레이커로 프롬프트가 뜨며, 이 모드는 root/sudo로는 아예 시작을 거부한다. “위험 모드는 컨테이너·VM처럼 Claude가 호스트를 망칠 수 없는 격리 환경에서만”이 공식 권고다.

한 가지 더 — 프로젝트 .claude/settings.jsonallowadditionalDirectories워크스페이스 신뢰 다이얼로그를 수락한 뒤에만 적용된다. 낯선 저장소가 클론되자마자 권한을 얻는 걸 막는 장치다. deny·ask는 제약만 하므로 신뢰와 무관하게 즉시 적용된다.

프록시와 네트워크 설정

세 번째 목표. 회사 방화벽 뒤에서 Claude Code를 돌리려면 프록시·인증서 설정이 필요하다. 공식 문서의 첫 문장이 이 절과 앞 절을 잇는다.

All environment variables shown on this page can also be configured in settings.json.

즉 아래 변수들은 셸에 export해도 되고 ~/.claude/settings.jsonenv 블록에 넣어도 된다. 그리고 뒤에서 볼 이유로, 설정에 넣는 쪽이 대개 옳다.

프록시. 표준 프록시 환경 변수를 그대로 존중한다.

export HTTPS_PROXY=https://proxy.example.com:8080   # 권장
export HTTP_PROXY=http://proxy.example.com:8080
export NO_PROXY="localhost,192.168.1.1,.example.com"  # 공백 또는 콤마 구분, "*"=전체 우회

주의 둘 — SOCKS 프록시는 지원하지 않는다. 그리고 프록시가 기본 인증을 요구하면 URL에 http://user:pass@proxy:8080로 넣되, 스크립트에 비밀번호를 하드코딩하지 말라는 경고가 붙는다. NTLM·Kerberos 같은 고급 인증이 필요하면 프록시 대신 LLM 게이트웨이를 쓰라는 게 문서의 권고다.

인증서. 기본적으로 Claude Code는 번들 Mozilla CA와 OS 인증서 저장소를 함께 신뢰한다(CLAUDE_CODE_CERT_STORE의 기본값 bundled,system). 그래서 Zscaler·CrowdStrike Falcon 같은 TLS 검사 프록시도 루트 인증서가 OS 스토어에 있으면 추가 설정 없이 동작한다. 사내 커스텀 CA를 직접 신뢰시키려면 이렇게 한다.

export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem

mTLS(클라이언트 인증서). 상호 TLS가 필요한 환경이면 세 변수를 준다.

export CLAUDE_CODE_CLIENT_CERT=/path/to/client-cert.pem
export CLAUDE_CODE_CLIENT_KEY=/path/to/client-key.pem
export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="암호(암호화된 키일 때)"

이 인증서와 키는 시작 시, 그리고 설정을 적용할 때마다 다시 읽힌다 — 회전하려면 같은 경로에 파일을 교체하면 된다.

왜 셸이 아니라 env 블록인가

‘전역 설정’ 차시에서 이 대목이 실은 가장 실무적이다. 백그라운드 에이전트를 쓰면 이유가 분명해진다. 백그라운드 세션은 이를 띄운 터미널 안에서 돌지 않고, 셸보다 오래 사는 per-user 슈퍼바이저 프로세스가 호스팅한다. 문서의 경고가 날카롭다.

If you export a proxy, CA path, or mTLS variable only in your shell, it reaches background agents when that shell happened to cold-start the supervisor, and silently doesn’t when a different shell did.

셸에만 export한 프록시·CA·mTLS 변수는, 그 셸이 우연히 슈퍼바이저를 콜드스타트했을 때만 백그라운드 에이전트에 닿고 다른 셸이 띄웠으면 소리 없이 안 닿는다. 해법은 하나다 — 같은 변수를 ~/.claude/settings.json(또는 managed)의 env 블록에 넣는다. 문서의 표현대로 “설정만이 모든 머신의 모든 백그라운드 세션에 닿는 유일한 구성”이다. 이게 ‘전역 설정 관리’의 진짜 무게가 실리는 지점이다.

{
  "env": {
    "HTTPS_PROXY": "https://proxy.example.com:8080",
    "NO_PROXY": "localhost,.internal.example.com",
    "NODE_EXTRA_CA_CERTS": "/etc/ssl/corp-ca.pem"
  }
}

마지막으로 방화벽·프록시 allowlist를 짤 때 열어야 할 핵심 호스트 — api.anthropic.com(API 요청, WebFetch 도메인 안전 검사, 텔레메트리), claude.ai·claude.com·platform.claude.com(인증), registry.npmjs.org(npm 설치). Bedrock·Vertex·Foundry나 게이트웨이를 쓰면 모델·인증 트래픽은 그쪽 제공자로 가지만, WebFetch의 도메인 안전 검사만은 여전히 api.anthropic.com을 호출한다(끄려면 설정에 skipWebFetchPreflight: true).

흔한 함정

  1. ~/.claude/settings.json이 ‘가장 강한’ 설정인 줄 안다. 반대다. 5층 중 최약(우선순위 최하)이고, 프로젝트·로컬·관리형이 위에서 덮는다. ‘전역’은 ‘가장 넓게’이지 ‘가장 강하게’가 아니다.
  2. 권한도 일반 설정처럼 덮인다고 생각한다. 권한은 병합된다. 그래서 어느 층의 deny든 전부 살아 있고, 다른 층의 allow를 이긴다. “여기선 허용했는데 왜 막히지?” — 상위·하위 어느 층의 deny를 찾아라.
  3. Bash(ls*)처럼 공백 없이 쓴다. 단어 경계가 없어 lsof까지 매치돼 의도보다 넓게 허용된다. 접두 매칭엔 공백을 넣어 Bash(ls *).
  4. Bash(safe *) 하나로 복합 명령이 다 될 줄 안다. &&·||·;·|로 쪼갠 하위명령마다 매치돼야 한다. 안 그러면 safe && rm -rf /가 새어 나갈 뻔한 걸 Claude Code가 막아 준다.
  5. 환경 러너를 Bash(devbox run *)로 넓게 허용한다. devbox run rm -rf .까지 허용된다. timeout류 래퍼만 벗겨지지 러너는 안 벗겨진다 — 러너+내부 명령을 명시하라.
  6. 인자 제한 Bash 패턴으로 URL을 막으려 한다. Bash(curl github.com *)는 옵션·리다이렉트·변수로 뚫린다. curl·wget deny + WebFetch(domain:)로 뒤집어라.
  7. Read(/secrets/**)를 절대경로로 착각한다. 슬래시 하나는 설정 소스 기준이다(사용자 설정이면 ~/.claude/secrets). 절대경로는 //, 매 프로젝트 적용은 // 또는 ~/.
  8. Write(docs/**)로 편집을 막으려 한다. 파일 권한 검사는 Edit·Read 규칙만 본다. Edit(docs/**)를 써라(경고가 뜬다).
  9. 저장소 .claude/settings.jsondefaultMode: "auto"를 넣는다. project/local에선 무시된다. 저장소가 스스로 auto를 부여하지 못하게 막혀 있다 — user 설정에 둬라.
  10. Read/Edit deny면 모든 접근이 막힌 줄 안다. 내장 툴과 인식된 bash 파일 명령엔 먹히지만, 파이썬·노드 스크립트가 직접 여는 건 못 막는다. OS 레벨 차단은 샌드박스(45차시).
  11. 프록시를 셸에만 export하고 백그라운드 에이전트가 못 붙는다고 당황한다. 슈퍼바이저는 셸 env를 상속하지 않는다. ~/.claude/settings.jsonenv 블록에 넣어야 전부에 닿는다.
  12. SOCKS 프록시를 설정한다. 지원하지 않는다. HTTP(S) 프록시만.

정리

핵심 요점

  1. ‘전역’은 5층 스택의 바닥이다. 우선순위 높은 순 Managed › Command line › Local(.claude/settings.local.json) › Project(.claude/settings.json) › User(~/.claude/settings.json). ~/.claude는 가장 넓게 퍼지되 가장 약한 층이다.
  2. 두 규율 — 설정은 덮어쓰고, 권한은 쌓인다. 일반 설정은 높은 층이 override, 권한 규칙은 모든 층이 merge된 뒤 deny → ask → allow 순으로 평가된다. 어느 층의 NO든 모든 층의 YES를 이긴다. bare 툴명 deny(Bash)는 툴을 컨텍스트에서 제거, scoped(Bash(rm *))는 매칭만 차단.
  3. Bash 문법의 세 급소 — 공백=단어 경계(Bash(ls *)Bash(ls*)), 복합 명령은 &&·;·|로 쪼개 하위명령마다 독립 매치, 래퍼(timeout)는 벗겨지지만 러너(devbox run·npx)는 안 벗겨진다.
  4. 인자 제한 패턴은 취약하다. Bash(curl github.com *)는 뚫린다. curl·wget deny + WebFetch(domain:github.com) allow로 뒤집되, Bash가 열려 있으면 WebFetch만으론 못 막는다.
  5. Read/Edit는 gitignore식, //절대·~/홈·/설정 소스·맨몸 cwd. /Users/alice/file은 절대경로가 아니다(→//). 맨몸 파일명은 어느 깊이나 매치되니 deny: Read(.env)로 시크릿을 넓게 막는다.
  6. 권한 모드는 여섯 — default(Manual)·acceptEdits·plan·auto·dontAsk·bypassPermissions. Shift+Tab 기본 사이클은 앞 셋. defaultMode:"auto"는 user 설정에서만, 위험 모드 잠금은 disableBypassPermissionsMode/disableAutoMode. protected paths·워크스페이스 신뢰가 추가 방어선.
  7. 프록시·CA·mTLS는 env 블록에. HTTPS_PROXY·NO_PROXY(SOCKS 불가), NODE_EXTRA_CA_CERTS, CLAUDE_CODE_CLIENT_CERT. 셸 export는 백그라운드 슈퍼바이저에 우연히만 닿으므로, ~/.claude/settings.json에 넣어야 전부에 닿는다.

다음 단계

이번 차시에서 model·outputStyle을 키로만 스치고 “자세한 건 44차시”라며 미뤘다. **44차시(모델 및 출력 설정)**에서 그 둘을 판다 — Sonnet·Opus·Haiku를 언제 고르고 어떻게 전환하는지, 출력 스타일을 어떻게 커스터마이징하는지, 컨텍스트 윈도우를 어떻게 관리하는지. 이번 차시가 ‘설정이라는 그릇의 구조’였다면, 다음은 ‘그 그릇에 담기는 모델과 출력’이다.

참고 자료


Next Post
Claude Code 원격 세션 활용 — 파이프라인이 아니라 내가 부르는 클라우드, '저장소에 커밋된 것만 존재하는' Anthropic 관리 VM, 준비의 두 층(환경의 Setup script ↔ 저장소의 SessionStart Hook)과 환경 캐싱, `CLAUDE_CODE_REMOTE` 게이트와 환경 변수 세 층, `--cloud`로 보내고 `--teleport`로 끌어오는 왕복, push가 현재 브랜치로 잠기는 GitHub 프록시