Claude Code 는 프로젝트를 열자마자 .env 파일을 읽어들입니다.
API 키, 데이터베이스 비밀번호, Stripe 토큰 등 .env 파일에 있는 모든 정보가 메모리에 로드되어 Anthropic 서버로 전송되는 대화 로그에 포함될 수 있습니다.
실제로 접근을 차단하는 유일한 방법은 settings.json 파일의 한 줄인데, 대부분의 사람들은 이 설정이 없거나 그 존재조차 모릅니다.
전체 보안 설정은 다음과 같습니다 👇
본격적으로 들어가기 전에, 저는 AI 및 바이브 코딩에 관한 일일 노트를 제 텔레그램 채널에서 공유하고 있습니다: **https://t.me/zodchixquant**🧠

CLAUDE.md 규칙이 당신을 보호하지 못하는 이유
대부분의 사람들은 CLAUDE.md에 ".env 파일을 절대 읽지 마세요"라고 추가하고 안전하다고 생각합니다. (하지만 그렇지 않습니다)
CLAUDE.md 는 권고 사항일 뿐입니다. Claude는 대부분의 경우 이를 따르지만, 압박을 받을 때(복잡한 작업, 긴 컨텍스트, 모호한 명령) 이 권고 규칙을 무시할 수 있고 실제로 무시합니다.
2026년 4월의 GitHub 이슈에서 확인된 바에 따르면, Claude는 CLAUDE.md에서 명시적으로 금지했음에도 .env 내용을 읽어 대화에 포함시킵니다.
유일하게 신뢰할 수 있는 보호 방법은 settings.json 의 거부 규칙입니다. 거부 규칙은 Claude가 파일을 보기도 전에 시스템 수준에서 적용됩니다.
"이거 읽지 말아주세요"와 "이거 물리적으로 읽을 수 없습니다"의 차이입니다.

비밀 정보가 유출되는 3가지 경로
문제는 단순히 Claude가 .env 파일을 직접 읽는 것만이 아닙니다. 세 가지 경로가 있습니다:
1. 직접 파일 읽기. Claude가 프로젝트를 스캔하고 .env 파일을 열면, 그 내용이 대화 컨텍스트의 일부가 됩니다. 이것은 가장 명백한 경로이며 거부 규칙으로 차단하기 가장 쉽습니다.
2. 런타임 출력 캡처. Claude가 테스트를 실행하거나 앱을 시작합니다. 실패한 HTTP 요청은 Authorization: Bearer sk-live-abc123... 헤더 전체를 로그에 남깁니다. 데이터베이스 타임아웃은 비밀번호가 포함된 연결 문자열을 덤프합니다. Claude는 모든 명령 출력을 캡처합니다. Claude가 .env 파일을 직접 열지 않았더라도, 당신의 비밀 정보는 이제 대화에 포함되어 있습니다.
3. Grep 및 검색 도구. Claude는 grep을 사용하여 코드베이스에서 함수 이름을 검색합니다. 검색 결과에 자격 증명이 포함된 설정 파일이 포함됩니다. grep 출력에는 당신의 비밀 정보가 보이는 상태로 일치하는 라인이 포함됩니다.
대부분의 사람들은 경로 1만 보호합니다. 경로 2와 3이 실제 피해가 발생하는 곳입니다.
실제로 작동하는 거부 규칙
모든 프로젝트에 전역적으로 적용하려면 ~/.claude/settings.json 에 다음을 추가하세요:
json
1{2 "permissions": {3 "deny": [4 "Read(**/.env*)",5 "Read(**/.dev.vars*)",6 "Read(**/*.pem)",7 "Read(**/*.key)",8 "Read(**/secrets/**)",9 "Read(**/credentials/**)",10 "Read(**/.aws/**)",11 "Read(**/.ssh/**)",12 "Read(**/config/database.yml)",13 "Read(**/config/credentials.json)",14 "Read(**/.npmrc)",15 "Read(**/.pypirc)",16 "Write(**/.env*)",17 "Write(**/secrets/**)",18 "Write(**/.ssh/**)"19 ]20 }21}
이 설정은 Claude가 .env 파일, PEM 키, SSH 키, AWS 설정, 자격 증명 파일, npm/PyPI 토큰을 읽거나 쓰는 것을 차단합니다. *\* 와일드카드는 프로젝트의 모든 하위 디렉토리에 적용됨을 의미합니다.
런타임 유출 차단하기
거부 규칙은 직접 파일 읽기는 막지만 런타임 출력은 막지 못합니다. 이를 위해 더미 값이 있는 테스트 전용 .env 파일을 사용하세요:
1# .env.test — 읽어도 안전하고, 유출되어도 안전함2STRIPE_SECRET_KEY=sk_test_not_a_real_key3DATABASE_URL=postgres://test:test@localhost:5432/testdb4OPENAI_API_KEY=sk-test-dummy-key-for-mocking5AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE6AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
테스트 프레임워크가 .env 대신 .env.test 를 가리키도록 설정하세요. 이제 Claude가 테스트를 실행하고 출력을 캡처해도 보이는 키는 모두 더미 값뿐입니다.
모든 것을 잡아내는 Pre-commit 훅
거부 규칙이 있어도 실수는 발생합니다. 커밋이 저장소에 도달하기 전에 비밀 정보를 스캔하는 git pre-commit 훅을 추가하세요:
bash
1#!/bin/bash2# .git/hooks/pre-commit — 비밀 정보가 포함된 커밋을 차단합니다34PATTERNS=(5 'sk-ant-' # Anthropic API 키6 'sk-live-' # Stripe 라이브 키7 'sk_live_' # Stripe 라이브 키 (대체 형식)8 'ghp_' # GitHub 개인 토큰9 'gho_' # GitHub OAuth 토큰10 'AKIA' # AWS 액세스 키11 'xox[bpors]-' # Slack 토큰12 'SG\.' # SendGrid 키13 'eyJ' # JWT14 'BEGIN.*PRIVATE KEY' # 개인 키 자료15)1617BLOCKED_FILES=('.env' 'credentials.json' 'id_rsa' '*.pem' '*.key')1819for pattern in "${PATTERNS[@]}"; do20 if git diff --cached --diff-filter=ACM | grep -qE "$pattern"; then21 echo "차단됨: '$pattern' 패턴과 일치하는 잠재적 비밀 정보 발견"22 echo "비밀 정보를 제거하고 다시 시도하세요."23 exit 124 fi25done2627for file in "${BLOCKED_FILES[@]}"; do28 if git diff --cached --name-only | grep -q "$file"; then29 echo "차단됨: 민감한 파일 커밋 시도: $file"30 exit 131 fi32done3334echo "Pre-commit 보안 검사 통과."35exit 0
실행 가능하게 만드세요: chmod +x .git/hooks/pre-commit
이 훅은 Anthropic API 키, Stripe 키, GitHub 토큰, AWS 키, Slack 토큰, SendGrid 키, JWT 및 개인 키 자료를 잡아냅니다. 이 중 어떤 것이든 스테이징된 파일에 나타나면 커밋이 차단됩니다.
컨테이너 격리 (최후의 수단)
최대 보안을 위해, .env 파일이 아예 존재하지 않는 컨테이너 내부에서 Claude Code를 실행하세요:
bash
1# .env 위에 /dev/null을 마운트하여 Claude가 볼 수 없게 함2docker run -v /dev/null:/app/.env:ro your-dev-container
Claude의 관점에서 .env는 빈 파일입니다. 당신의 비밀 정보는 컨테이너 파일 시스템에 절대 들어가지 않습니다. 대부분의 프로젝트에는 과한 조치이지만, 프로덕션 자격 증명을 다루는 클라이언트 작업에는 필수적입니다.
전체 보안 설정 (복사해서 바로 사용 가능)
모든 보안 보호 기능이 포함된 완전한 ~/.claude/settings.json 파일:
json
1{2 "permissions": {3 "allow": [4 "Read",5 "Glob",6 "Grep",7 "LS",8 "Edit",9 "MultiEdit",10 "Write(src/**)",11 "Write(tests/**)",12 "Bash(npm run *)",13 "Bash(npm test *)",14 "Bash(npx tsc *)",15 "Bash(git status)",16 "Bash(git diff *)",17 "Bash(git log *)",18 "Bash(git add *)",19 "Bash(git commit *)"20 ],21 "deny": [22 "Read(**/.env*)",23 "Read(**/.dev.vars*)",24 "Read(**/*.pem)",25 "Read(**/*.key)",26 "Read(**/secrets/**)",27 "Read(**/credentials/**)",28 "Read(**/.aws/**)",29 "Read(**/.ssh/**)",30 "Read(**/config/database.yml)",31 "Read(**/config/credentials.json)",32 "Read(**/.npmrc)",33 "Read(**/.pypirc)",34 "Write(**/.env*)",35 "Write(**/secrets/**)",36 "Write(**/.ssh/**)",37 "Write(.github/workflows/*)",38 "Bash(rm -rf *)",39 "Bash(sudo *)",40 "Bash(git push *)",41 "Bash(npm publish *)",42 "Bash(curl * | sh)",43 "Bash(wget *)",44 "Bash(chmod *)"45 ],46 "defaultMode": "acceptEdits"47 }48}
이것은 제 이전 글의 settings.json 에 이 글의 모든 보안 규칙을 추가한 것입니다. 일상 워크플로우를 위한 허용 규칙, 비밀 정보와 위험한 작업을 위한 거부 규칙. 하나의 파일로 완벽한 보호를 제공합니다.
체크리스트
다음 Claude Code 세션을 시작하기 전에 확인하세요:
- settings.json 에 .env 파일에 대한 거부 규칙이 있습니까?
- 테스트에서 더미 값이 있는 .env.test 를 사용합니까?
- 비밀 정보 패턴을 스캔하는 pre-commit 훅이 있습니까?
- 프로덕션 자격 증명이 일반 텍스트 파일이 아닌 볼트에 저장되어 있습니까?
- .env 가 .gitignore 에 포함되어 있습니까?
- 추가 안전을 위해 .env 파일이 프로젝트 디렉토리 외부에 있습니까?
6개 모두 확인했다면, 당신의 비밀 정보는 가능한 한 최대로 보호되고 있는 것입니다. 0개를 확인했다면, 모호한 Claude 프롬프트 하나만으로 API 키가 Anthropic 서버의 대화 로그에 나타날 수 있습니다.
저는 AI, 금융 및 바이브 코딩에 관한 일일 노트를 제 텔레그램 채널에서 공유하고 있습니다: **https://t.me/zodchixquant**
읽어주셔서 감사합니다🙏🏼






