블로그 불러오는 중...
문의 보내기
남겨주면 블로그 주인에게 바로 전달돼요.
이번 글은 Claude Code Deep Dive 4장 Settings에 대한 정리이다.
앞선 3장에서는 조직에서 Claude Code를 어떻게 배포하고 관리할 것인지에 대해 살펴봤다면, 이번 장에서는 조금 더 실제 사용에 가까운 내용이 나온다.
Claude Code의 설정 스코프, 권한 조율, 훅 자동화, 확장 통합 등을 다룬다.
이번 장의 핵심은 다음과 같다.

Claude Code를 사용하다 보면 CLAUDE.md를 많이 사용하게 된다.
CLAUDE.md가 Claude에게 이 프로젝트는 어떤 프로젝트이고, 코드를 작성할 때 어떤 규칙을 지켜야 하는 지 알려주는 파일이다. 앞에 게시물에서 프로젝트에서 /init 명령어로 CLAUDE.md 를 만드는 것을 실습 했었다.
settings.json은 조금 다르다.
특정 명령어 허용, 거부, 훅, 등 여러가지 항목이 settings.json에서 이루어진다.
Claude Code의 Settings는 크게 3단계로 나뉜다. 워크숍 자료에서는 조직 -> 프로젝트 -> 사용자 순으로 관리하고, 별도로 프로젝트 로컬 설정을 둘 수 있도록 설명한다.

| 구분 | 위치 | 용도 |
|---|---|---|
| Managed | 서버 관리, plist, 레지스트리, 시스템 파일 | 회사/조직에서 강제로 적용 |
| Project | .claude/settings.json | 프로젝트 구성원과 공유 |
| User | ~/.claude/settings.json | 개인 설정 |
| Local | .claude/settings.local.json | 해당 프로젝트에서 나만 사용하는 설정 |
조직에서 Claude Code를 사용한다면 Managed Settings가 가장 중요한 설정이라고 볼 수 있다.
예를 들어 회사 정책상 절대 실행하면 안 되는 명령이나 접근하면 안 되는 파일을 중앙에서 차단할 수 있다.
{
"permissions": {
"deny": [
"Bash(rm -rf:*)",
"Read(**/.env*)",
"Read(**/.ssh/**)"
]
}
}프로젝트에서는 팀에서 필요한 설정을 Git으로 관리할 수 있다.
project/
├── .claude/
│ ├── settings.json
│ └── commands/
├── CLAUDE.md
└── src/반면 개인적으로만 사용하고 싶은 설정은
.claude/settings.local.json에 넣을 수 있다.
이 파일은 Git에 올라가지 않도록 처리하는 것이 좋다. 워크숍에서도 프로젝트 공유 설정과 개인 설정을 분리하는 형태를 사용한다.
.claude/settings.local.json우선순위 정리는 다음과 같다.

Claude Code는 단순히 코드를 추천하는 것을 넘어 실제로
rm
git
npm
kubectl
aws등의 명령을 실행할 수 있다. 사실 LLM 의 판단보다는 실제로 정규식으로 검색되는 명령어를 거부하는 게 더 나을 것 같다. 회사에서 로컬에 환경변수를 저장해서 가지고 있는데, LLM 이 이를 읽어버려 전체 키를 로테이트 한 경험들이 있다.
이와 관련된 내용을 배워보는 챕터이다.
Permissions에는 기본적으로 allow, ask, deny 세 가지 개념이 있다.
Claude가 별도의 확인 없이 실행한다.
실행하기 전에 사용자에게 물어본다.
실행 자체를 차단한다.
예를 들어 개인 개발환경에서는 다음 정도로 시작해볼 수 있다.
{
"permissions": {
"allow": [
"Read",
"Grep",
"Bash(npm test:*)",
"Bash(npm run lint)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git status)"
],
"ask": [
"Edit",
"Write",
"Bash(git push:*)"
],
"deny": [
"Bash(rm -rf:*)",
"Read(**/.env*)",
"Read(**/.ssh/**)"
]
}
}아래는 해당 부분의 PPT 내용이다.

워크숍의 첫 번째 Lab도 비슷하게 읽기나 조회 작업은 allow, 파일 수정 및 Push는 ask, 위험 명령과 민감 파일은 deny로 시작한다.
Permission은 단순히 Tool 단위로만 설정하지 않고 Pattern을 사용할 수 있다.
Read
Grep
Glob
Edit
Write이게 내가 겪었던 환경변수를 다 읽어버린 상황이였다. 이런 경우엔, 해당 경로를 읽지 못하게 선제적 설정이 중요할 것 같다.
"Read(./.env)" # 프로젝트 루트의 .env
"Read(./.env.*)" # .env.local 등 변형
"Read(./secrets/**)" # 하위 전체
"Edit(*.ts)" # 확장자 단위
"Read(~/.zshrc)" # 홈 기준 경로
"Read(//etc/passwd)" # 절대 경로는 // 접두
Bash(npm test)
Bash(npm test:*)
Bash(git diff:*)
Bash(git status)
정규식 패턴도 있다. 예를 들어
Bash(git status)는 git status만 허용하지만,
Bash(git diff:*)는
git diff
git diff HEAD
git diff HEAD~3등을 사용할 수 있게 된다.
Claude Code에 파일 읽기 권한을 많이 주다 보면 의도하지 않게 Credential 파일을 읽게 될 수도 있다. 때문에 조직 환경에서는 최소한 다음과 같은 파일들은 막아두는 것이 좋아 보인다. 특정 경로와 연관되는데, 결국은 읽지 못하게 끔 deny 하는 설정이다.
{
"permissions": {
"deny": [
"Read(**/.env*)",
"Read(**/.aws/credentials)",
"Read(**/.ssh/**)",
"Read(**/.gnupg/**)",
"Read(**/.kube/config)",
"Read(**/*private_key*)"
]
}
}Permission이 이 작업을 실행해도 되는지를 설정하는 것이고 Hook은 이 작업이 발생했을 때 무엇을 실행할 것인지 설정하는 것이다.
예를 들어 Claude가 파일을 수정할 때마다 eslint, prettier 를 실행하게 할 수 있다.
아래는 자주 쓰는 이벤트 훅이라고 한다.

아래는 일부를 정리해 보았다. 실제로 쓸만 한 부분을 정리해 보았다.
| Hook | 시점 | 활용 예 |
|---|---|---|
SessionStart | Claude Code 세션 시작 | 정책 안내, 환경 초기화 |
PreToolUse | Tool 실행 전 | 보안 검사, DLP |
PostToolUse | Tool 실행 후 | Format, Lint |
Stop | 작업 종료 | Slack 알림 등 |
Hook의 기본적인 형태는 다음과 같다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Edit|Write",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/security-check.sh",
"timeout": 5000
}
]
}
]
}
}matcher를 통해 어떤 Tool에서 Hook을 실행할 것인지 지정한다.
워크숍에서는 여러 Hook 활용 패턴을 소개한다.
Write/Edit 다음 eslint 를 사용한다.
Write/Edit 다음 prettier 사용해 포매팅 한다.
Tool 실행 -> Audit Log 기록
실행 끝나고, 슬랙 메시지를 보 낼 수 있다.
{ "hooks": {
"Notification": [
{ "matcher": "permission_prompt|agent_needs_input",
"hooks": [{ "type": "command",
"command": "notify-send 'Claude가 입력을 기다립니다'" }] } ],
"Stop": [
{ "hooks": [{ "type": "http",
"url": "https://hooks.slack.com/services/T/B/x",
"timeout": 10 }] } ]
} }
# Notification 매처: permission_prompt, idle_prompt,
# agent_completed 등 유형별 선결국 Hook은 자동화, 그리고 실행 앞뒤에 검증을 할 수 있는 기능이다.
MCP(Model Context Protocol)는 Claude가 외부 시스템과 통신할 수 있게 해주는 표준 인터페이스라고 볼 수 있다.
MCP 는 특정 프로토콜로, 외부 시스템과 AI 가 소통하는 프로토콜이라고 보면 된다. MCP 연결 시 클로드는 원하는 맥락이나 정보를 가지고 오거나 변경할 수 있다.
워크숍에서는 MCP의 기능을 크게 세 가지로 구분한다.

워크숍에서는 MCP 서버와 연결하는 Transport 방식으로 다음 형태를 다룬다.
로컬 프로세스를 직접 실행한다.
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"]
}
}
}개발환경이나 로컬 MCP Server를 사용할 때 적합하다.
원격 MCP Server에 연결한다. 요새 Datadog 이나 Attlasian 등 벤더들이 mcp 를 많이 오픈 하는 것 같다.
{
"mcpServers": {
"company": {
"type": "http",
"url": "https://mcp.example.com"
}
}
}SSE 기반 서버 연결도 워크숍에서 소개한다.
사내 공통 MCP를 운영한다면 각 개발자 PC에서 Server를 띄우는 것보다 원격 서버 형태가 관리하기 편할 것 같다.
MCP에 문제가 있을 때는 Claude Code에서 /mcp 를 사용할 수 있다.
연결된 MCP Server와 상태, 사용 가능한 Tool 등을 확인할 수 있으며 인증 실패 등 연결 문제도 확인할 수 있다.
예를 들어
github connected
jira 401 unauthorized
slack connected처럼 나온다면 Claude 문제인지 Jira 인증 문제인지 구분하기 쉬워진다.
MCP를 여러 개 연결할수록 /mcp를 볼 일이 많아질 것 같다.
MCP는 공개된 Server만 사용하는 것이 아니라 직접 만들 수도 있다. 회사에서는 빌드 이후에 trivy 보안 점검을 하게 해 놓았고, 그 툴에서 나온 정보를 수집하는 프로그램을 만들고 해당 정보를 조회할 수 있는 mcp 를 만든 적이 있다.
해당 업무는 시간을 내서 만들었으며, 실질적으로 여러가지를 붙여보고 싶었지만 다른 업무가 많아 확장하지는 못했다.
해당 MCP 를 이용시 특정 버전의 취약점을 Claude 가 알게 되었다.

Claude Code를 사용하다 보면 반복해서 사용하는 Prompt가 생긴다. 예를 들어 매번
현재 변경된 코드를 확인하고
보안 취약점과 코드 품질을 검토한 뒤
문제점을 정리해줘.라고 입력하는 대신 /code-review 한 번으로 실행할 수 있다.
Custom Slash Command는
.claude/commands/또는
~/.claude/commands/아래 Markdown 파일을 만들어 사용한다.
워크숍에서는 파일명이 그대로 /command가 되는 구조를 설명한다.
예를 들어
.claude/
└── commands/
└── security-review.md를 만들면
/security-review명령을 사용할 수 있다.
AI 를 사용하다 보면 실제로 무엇을 읽었는지, 그냥 Allow 를 눌러 버리는 경우도 많은데, 실제로 해당 부분은 보안적으로 막아야 할 것 같다. 위 Deny Rule 을 잘 가지고 조직 차원에서 컨트롤 하는 게 바람직 할 것 같다.