Hands-on Lab / Chapter 3

Admin Setup, 통제 가능한 Enterprise 배포

Claude Code Deep Dive Workshop, Chapter 3 - Admin Setup 실습

관리자의 40분입니다. 사내 npm 미러(Verdaccio)로 배포 경로를 통제하고, Bedrock + SSO 자격증명 패턴을 구성하고, managed-settings로 조직 정책을 강제한 뒤 DLP HookOpenTelemetry까지 연결합니다. 전부 로컬 머신에서 검증 가능하게 구성했으며, AWS 콘솔이 필요한 부분은 선택 트랙으로 분리했습니다.

소요 시간 40분 내외 Task 준비 + 5개 기준 버전 Claude Code 2.1.x Update 2026.07
TASK 00

사전 준비 확인

2분

이번 랩은 시스템 경로에 파일을 배포하므로 sudo 권한이 필요합니다(Task 3, 4). 검증에 쓸 작업 폴더와 가짜 시크릿 파일도 만들어 둡니다.

1권한과 도구 확인, 작업 폴더 생성
Terminal, 전체 복사
sudo -v && echo "sudo OK"
node -v && npm -v

mkdir -p ~/claude-lab/ch3/src && cd ~/claude-lab/ch3

cat > .env << 'EOF'
# 실습용 가짜 값입니다. 실제 시크릿을 넣지 마세요.
DB_PASSWORD=lab-fake-password
API_TOKEN=lab-fake-token
EOF

cat > src/app.js << 'EOF'
export function hello() { return "admin lab"; }
EOF
ls -la
sudo가 없는 회사 노트북이라면 Task 3, 4의 managed-settings 경로 대신 ~/.claude/settings.json(User 스코프)에 같은 JSON을 넣으면 정책 동작 자체는 동일하게 체험할 수 있습니다. 차이는 강제성뿐입니다. User 설정은 본인이 언제든 바꿀 수 있지만, Managed는 사용자가 덮어쓸 수 없습니다.
CHECKPOINT
TASK 01

사내 npm 미러, Verdaccio

9분

npmjs를 직접 열 수 없는 사내망을 가정하고, Verdaccio 미러를 띄워 Claude Code를 미러 경유로 설치합니다. 한 번 캐시된 패키지는 npmjs가 두절돼도 배포 가능하다는 것(오프라인/에어갭의 기초)을 확인합니다.

1Verdaccio 설치와 기동
Terminal
npm install -g verdaccio
verdaccio --listen 4873 > /tmp/verdaccio.log 2>&1 &
sleep 3
npm ping --registry http://localhost:4873   # PONG이면 미러 정상
2미러 경유로 Claude Code 설치

전역 registry를 바꾸는 대신 --registry 플래그를 씁니다. 실습 머신의 npm 상태를 건드리지 않으므로 원복이 필요 없습니다.

Terminal
npm install -g @anthropic-ai/claude-code --registry http://localhost:4873
claude --version
3캐시 확인, 오프라인 배포의 핵심
Terminal
ls ~/.config/verdaccio/storage/@anthropic-ai/claude-code/
출력 예시
claude-code-2.1.x.tgz    package.json
이 tgz가 사내 배포의 자산입니다 미러를 한 번 통과한 패키지는 storage에 캐시되어, 이후 npmjs가 차단되거나 두절돼도 사내 클라이언트에 계속 배포할 수 있습니다. 에어갭 환경은 이 storage 디렉토리를 반입하는 방식으로 운영합니다.
4정리
Terminal, 미러 종료
pkill -f verdaccio && echo "미러 종료됨"
프로덕션 운영 참고 실제 조직에서는 Verdaccio 또는 Nexus / JFrog Artifactory에 @anthropic-ai 스코프를 고정하고 (config.yaml에 '@anthropic-ai/*': proxy: npmjs), 클라이언트에는 npm config set registry http://npm.corp.local을 MDM으로 일괄 배포합니다. 버전 통제는 managed-settings의 requiredMinimumVersion / requiredMaximumVersion으로 승인 범위를 강제할 수 있습니다.
CHECKPOINT
TASK 02

Bedrock + SSO 자격증명 패턴

7분

장기 API Key를 뿌리는 대신 IAM Identity Center(SSO)의 단기 자격증명으로 Bedrock을 호출하는 표준 패턴을 구성합니다. 프로파일 작성과 IAM 정책 이해는 전원 진행하고, 실제 로그인 검증은 AWS 계정 보유자용 선택 트랙입니다.

왜 API Key 분배가 위험한가 장기 Key는 회전이 수동이고, 퇴사자 처리(offboarding)가 누락되기 쉬우며, 유출 시 폭발 반경이 큽니다. SSO 경로는 자격증명이 시간 제한부로 자동 발급되고, IdP에서 계정을 끄는 순간 접근이 끊깁니다.
1SSO 프로파일 작성 (격리된 config 파일)

실습에서는 AWS_CONFIG_FILE격리된 설정 파일을 사용해 기존 ~/.aws/config를 건드리지 않습니다. 값은 조직 환경에 맞게 바꾸세요.

Terminal, 전체 복사
export AWS_CONFIG_FILE=~/claude-lab/ch3/aws-config

cat > "$AWS_CONFIG_FILE" << 'EOF'
[sso-session corp]
sso_start_url = https://my-org.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access

[profile claude-workshop]
sso_session = corp
sso_account_id = 111122223333
sso_role_name = ClaudeCodeWorkshop
region = ap-northeast-2
EOF

cat "$AWS_CONFIG_FILE"
2Permission Set에 부여할 IAM 정책 이해

역할(ClaudeCodeWorkshop)에는 최소 권한 원칙으로 아래 정책을 부여합니다. 읽고 각 항목의 목적을 확인하세요.

IAM Policy, 참고용
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream",
      "bedrock:ListFoundationModels"
    ],
    "Resource": [
      "arn:aws:bedrock:*::foundation-model/anthropic.*",
      "arn:aws:bedrock:*:*:inference-profile/*"
    ]
  }]
}

InvokeModelWithResponseStream은 Claude Code가 스트리밍으로 응답을 받는 데 필수입니다. inference-profile 리소스는 교차 리전 추론(CRIS)을 쓸 때 필요합니다. 조직 요건에 맞게 모델 ARN과 리전 범위를 더 좁힐 수 있습니다.

3선택 트랙, 실제 로그인 검증 (AWS 계정 + IAM Identity Center 보유자)
Terminal, 선택
aws sso login --profile claude-workshop

export CLAUDE_CODE_USE_BEDROCK=1
export AWS_PROFILE=claude-workshop
export AWS_REGION=ap-northeast-2

claude doctor   # API Provider: AWS Bedrock 표시 확인
Bedrock 경로의 텔레메트리 주의점 Bedrock 인증에는 Claude 계정이 없으므로 OTel 이벤트에 user.email이 비어 있습니다. 사용자별 비용 추적이 필요하면 OTEL_RESOURCE_ATTRIBUTES="enduser.id=user@corp.com"처럼 신원 속성을 managed-settings로 부착하세요. Task 5에서 이어집니다.
4정리
Terminal
unset AWS_CONFIG_FILE CLAUDE_CODE_USE_BEDROCK AWS_PROFILE AWS_REGION
CHECKPOINT
TASK 03

managed-settings로 조직 정책 강제

10분

사용자가 덮어쓸 수 없는 Managed 스코프에 권한 규칙을 배포하고, 실제로 적용되는지 검증합니다. Settings 우선순위의 최상단(Managed > CLI > Local > Project > User)을 체감하는 것이 목표입니다.

1OS별 managed-settings 경로

아래는 파일 기반 managed-settings의 표준 경로입니다. 본인 OS 탭의 경로를 사용하세요.

OS경로
Linux, WSL/etc/claude-code/managed-settings.json
macOS/Library/Application Support/ClaudeCode/managed-settings.json
WindowsC:\Program Files\ClaudeCode\managed-settings.json
경로 주의 Linux 경로는 /etc/claude-code/입니다(하이픈 포함). Windows 구경로 C:\ProgramData\ClaudeCode\는 v2.1.75부터 미지원이니 C:\Program Files\ClaudeCode\를 쓰세요. 아래 실습은 Linux / WSL 경로 기준이며, macOS는 경로만 바꾸면 됩니다.
2정책 배포, 권한 규칙 + 시작 배너

companyAnnouncements로 시작 배너를 함께 넣어, 관리 설정이 실제로 적용됐는지 눈으로 확인합니다.

Terminal, Linux/WSL 기준 전체 복사
sudo mkdir -p /etc/claude-code
sudo tee /etc/claude-code/managed-settings.json > /dev/null << 'EOF'
{
  "permissions": {
    "allow": ["Read(**)", "Grep", "Glob", "Bash(npm test:*)"],
    "ask": ["Edit(**)", "Write(**)"],
    "deny": ["Bash(rm -rf:*)", "Read(./.env)", "Read(./.env.*)"]
  },
  "companyAnnouncements": [
    "[Corp Policy] Claude Code managed settings 적용됨. .env 읽기는 금지됩니다."
  ]
}
EOF
echo "배포 완료"
3적용 검증 A, 배너와 설정 소스 확인
Terminal
cd ~/claude-lab/ch3
claude

세션이 시작되면 상단에 배너 문구가 뜨는지 보고, 아래로 설정 소스를 확인합니다.

Claude 세션 입력
/status
관찰 포인트
Setting sources:
  - managed  (/etc/claude-code/managed-settings.json)   # 이 줄이 보여야 함
  - user, project ...
4적용 검증 B, deny 규칙이 .env 읽기를 차단
Claude 세션 입력
.env 파일의 내용을 읽어서 보여주세요
관찰 포인트
Read(./.env) 는 관리 정책(deny)에 의해 차단되었습니다.
# 프롬프트 없이 거부됨. Read(**)로 허용돼 있어도 deny가 우선

Read(**)로 전체 읽기를 allow 했더라도 deny 규칙이 우선하여 .env는 차단됩니다. 권한 규칙은 스코프 간 병합되며, deny가 항상 이깁니다. /exit로 세션을 나옵니다.

배포 전 검증 습관 관리 설정은 관대하게 파싱되어 잘못된 항목만 버려지고 나머지는 적용됩니다. 배포 전 테스트 머신에서 claude doctor를 돌리면 무시된 항목을 소스 파일과 필드까지 알려줍니다. fleet 배포 전 필수 습관입니다.
CHECKPOINT
TASK 04

DLP Hook, 시크릿 유출 차단

9분

코드에 AWS 액세스 키가 섞여 들어가는 것을 PreToolUse Hook으로 실시간 차단합니다. 권한 규칙이 도구 단위 통제라면, Hook은 내용 기반 통제(DLP)라는 점이 핵심입니다.

1DLP 검사 스크립트 작성

stdin으로 들어오는 JSON에서 tool_input을 꺼내 AWS 키 패턴을 찾고, 발견 시 exit code 2로 차단합니다. stderr 메시지는 Claude에게 전달되어 차단 사유가 됩니다.

Terminal, 전체 복사
sudo mkdir -p /opt/claude
sudo tee /opt/claude/dlp.sh > /dev/null << 'EOF'
#!/bin/bash
# PreToolUse DLP: AWS Access Key ID 패턴을 도구 입력에서 차단
INPUT=$(cat)
if echo "$INPUT" | grep -qE 'AKIA[0-9A-Z]{16}'; then
  echo "Blocked by DLP: AWS Access Key ID detected in tool input" >&2
  exit 2
fi
exit 0
EOF
sudo chmod +x /opt/claude/dlp.sh
echo "DLP 스크립트 준비 완료"
exit code 2가 핵심입니다 PreToolUse Hook은 exit code 2로 도구 실행을 차단하고 stderr를 Claude에 전달합니다. exit 0은 통과, 그 외 코드는 비차단 오류로 처리됩니다(구 자료의 exit 1 + JSON 방식은 현행과 다릅니다).
2managed-settings에 Hook 추가

Task 3의 managed-settings에 hooks 블록을 더해 재배포합니다. 권한 규칙은 그대로 유지합니다.

Terminal, Linux/WSL 기준 전체 복사
sudo tee /etc/claude-code/managed-settings.json > /dev/null << 'EOF'
{
  "permissions": {
    "allow": ["Read(**)", "Grep", "Glob", "Bash(npm test:*)"],
    "ask": ["Edit(**)", "Write(**)"],
    "deny": ["Bash(rm -rf:*)", "Read(./.env)", "Read(./.env.*)"]
  },
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash|Edit|Write",
      "hooks": [{ "type": "command", "command": "/opt/claude/dlp.sh" }]
    }]
  },
  "companyAnnouncements": [
    "[Corp Policy] DLP Hook 활성화됨. AWS 키는 코드에 쓸 수 없습니다."
  ]
}
EOF
echo "Hook 포함 재배포 완료"
3차단 검증
Terminal
cd ~/claude-lab/ch3
claude

Hook은 설정 핫 리로드로 적용됩니다. 세션에서 AWS 키가 포함된 파일 작성을 요청하세요.

Claude 세션 입력
src/aws.js 파일을 만들고 그 안에 다음 줄을 넣어주세요: const key = "AKIAIOSFODNN7EXAMPLE";
관찰 포인트
[Write 시도] → PreToolUse Hook 실행 (/opt/claude/dlp.sh)
Blocked by DLP: AWS Access Key ID detected in tool input
# exit 2로 Write가 차단됨. Claude는 차단 사유를 전달받음

키 없는 일반 파일 작성은 정상 통과하는지도 확인해 보세요(대조군). 확인 후 /exit.

4전체 원복, 중요
시스템 경로 정리는 반드시 수행 관리 설정과 Hook은 이 머신의 모든 Claude Code 세션에 계속 적용됩니다. 실습이 끝나면 아래로 반드시 제거하세요.
Terminal, 전체 원복
sudo rm -f /etc/claude-code/managed-settings.json
sudo rm -f /opt/claude/dlp.sh
sudo rmdir /etc/claude-code /opt/claude 2>/dev/null
echo "원복 완료"
CHECKPOINT
TASK 05

OpenTelemetry 텔레메트리 맛보기

3분

사용량과 비용, 감사 이벤트를 사내 관측 스택으로 보내는 첫 단계로, console exporter로 텔레메트리가 실제로 흐르는지 눈으로 확인합니다. SIEM 연동은 이 흐름의 목적지만 바꾼 것입니다.

1console exporter로 메트릭 출력

OTLP 수집기 없이도 console exporter로 표준 출력에서 메트릭을 볼 수 있습니다. 수집 간격을 짧게 잡아 바로 확인합니다. 세션 밖 터미널에서 실행하세요.

Terminal, 전체 복사
cd ~/claude-lab/ch3
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=5000

claude -p "src/app.js가 무엇을 하는지 한 줄로 설명해줘"
관찰 포인트
# stdout에 메트릭 스코프가 출력됨
descriptor:
  name: claude_code.token.usage ...
  name: claude_code.cost.usage ...
# session.count, token.usage, cost.usage 등이 흐르는지 확인
SIEM으로 가는 길은 목적지 변경뿐 실제 조직에서는 console 대신 OTEL_LOGS_EXPORTER=otlpOTEL_EXPORTER_OTLP_LOGS_ENDPOINT를 managed-settings의 env로 배포합니다. 감사에는 OTEL_LOG_TOOL_DETAILS=1을 켜서 tool_decision, mcp_server_connection 등 보안 이벤트에 Bash 명령과 MCP 호출 상세를 포함시킵니다.
2정리
Terminal
unset CLAUDE_CODE_ENABLE_TELEMETRY OTEL_METRICS_EXPORTER OTEL_METRIC_EXPORT_INTERVAL
CHECKPOINT

마무리, 학습 목표 체크리스트

Chapter 3의 관리자 학습 목표를 스스로 점검하세요. 미달성 항목은 진행자에게 질문하거나 강의 자료의 해당 Part를 다시 확인합니다.

목표확인 질문관련
Deploy사내 미러로 오프라인 배포의 기초(캐시)를 확인했는가Task 1
CredentialAPI Key 대비 SSO+Bedrock의 이점과 IAM 정책을 설명할 수 있는가Task 2
GovernanceManaged 스코프의 우선순위와 deny 우선 규칙을 체험했는가Task 3
DLPPreToolUse Hook(exit 2)으로 내용 기반 차단을 구현했는가Task 4
Observe텔레메트리 흐름을 확인하고 SIEM 연동 경로를 이해했는가Task 5
Cleanup시스템 경로의 managed-settings와 Hook을 원복했는가Task 4
R실행 로드맵, 분기별 도입
분기목표주요 활동
Q1 / PoC5-10인 시범 도입API Key + 사용 패턴 관찰
Q2 / Foundation클라우드 자격증명 전환Bedrock + SSO 통합
Q3 / Governance권한 정책과 감사 시스템managed-settings + SIEM
Q4 / Scale전 조직 확산교육 + 자동화 + 모니터링

한 번에 모든 것을 하지 말고 점진적으로 도입하세요. 각 분기의 학습을 다음 분기 계획에 반영하는 사이클이 가장 효과적입니다.

NEXT CHAPTER

Chapter 4 - Settings

이번 챕터에서 관리자 관점으로 다룬 설정 계층을, Chapter 4에서는 개발자 관점의 일상 설정으로 심화합니다. settings.json의 주요 키, Hooks 활용 패턴, MCP 서버 연결을 다룹니다.