settings.local.json이란 무엇인가
Claude Code는 여러 파일에서 설정을 읽습니다. Anthropic의 설정 문서는 프로젝트 로컬 설정을 .claude/settings.local.json으로 정의하며, 이는 "이 프로젝트 하나에서의 사용자 본인"을 위한 것입니다. 주요 용도는 단일 프로젝트에 대한 개인적인 오버라이드 및 공유 전 테스트입니다.
이 파일을 직접 만들 필요는 없습니다. 문서에 따르면 Claude Code는 "권한 프롬프트에서 처음으로 상시 승인(standing approval)을 주었을 때" .claude/settings.local.json을 작성합니다. 권한 관련 문서는 셸 명령어에 대해 이것이 무엇을 의미하는지 명시합니다. Claude Code가 다시 묻지 않도록 옵션을 선택하여 승인이 영구적으로 저장될 때, "Bash 명령어 또는 WebFetch 도메인과 같은 경우, Claude Code는 규칙을 git 리포지토리 루트의 .claude/settings.local.json에 저장합니다."
같은 페이지의 두 가지 세부 사항이 중요합니다. Bash 승인은 "리포지토리 및 명령어당 영구적으로" 유지됩니다. 그리고 이 규칙은 "하위 디렉터리 및 worktrees에서 시작된 세션을 포함하여 해당 리포지토리 어디에서나 향후 세션에 적용됩니다." 한 번 내린 승인은 누군가 제거할 때까지 파일에 남아 계속 작동합니다.
비밀 정보가 파일에 저장되는 이유
Apiiro의 보고서는 그 과정을 단계별로 설명합니다. "Claude Code에 데이터베이스 확인이나 API 호출을 요청하면, 제안된 명령어는 설정 파일의 비밀 정보를 포함하게 됩니다. 실행 전 확인을 거칩니다." 명령어가 작동하려면 비밀 정보가 포함되어야 하기 때문입니다.
그다음 승인 단계가 옵니다. 다시 묻지 않음 옵션을 선택하면, Apiiro는 다음과 같이 기술합니다. "명령어를 실행하고 프로젝트 폴더의 .claude/settings.local.json에 권한 규칙을 추가하여 다시 묻지 않게 합니다. 이때 규칙은 명령어 문자열 그 자체입니다."
권한 규칙은 Claude Code가 실행할 수 있는 작업을 설명하기 위한 것입니다. 승인된 명령어에 비밀번호, 토큰 또는 연결 문자열이 직접 입력되어 있으면, 규칙은 해당 값을 평문으로 저장합니다.
Apiiro는 이것이 특정 모델의 특이점이 아니라 도구 자체의 동작이라고 말합니다. "이것은 모델이 아닌 Claude Code 자체의 동작입니다. Anthropic의 최신 모델에서도 발생하며, Opus 5.5 및 Fable 5.1에서도 재현되었습니다."
Claude Code 자체 보호 기능이 항상 작동하지 않는 이유
Claude Code는 해당 파일을 git에서 제외하려고 시도합니다. 설정 문서에 따르면 "Claude Code가 해당 파일을 아직 무시하지 않는 git 리포지토리에 처음 작성할 때, 전역(global) git excludes 파일에 **/.claude/settings.local.json을 추가하여 모든 리포지토리의 커밋에서 제외되도록 합니다."
핵심 단어는 '전역'입니다. 이 제외 설정은 리포지토리가 아니라 사용자 머신의 git 설정에 존재합니다. Apiiro는 이 간극을 다음과 같이 설명합니다. "이는 일반적인 경우를 커버하지만, 나중에 리포지토리가 된 폴더, 다른 머신에서의 클론, 또는 누군가 이미 커밋한 파일은 커버하지 못합니다." 또한 "규칙이 리포지토리 자체의 .gitignore에 들어가지 않으므로, 프로젝트를 보호하기 위해 함께 이동하는 장치가 없습니다."
사용자가 직접 만든 파일에 대한 문서화된 예외도 있습니다. 설정 표에 따르면 Claude Code는 "파일을 생성할 때 git에서 제외하지만, 직접 만든 경우에는 직접 .gitignore에 추가해야 합니다."
파일이 추적(track)되기 시작하면 Claude Code는 처리 방식을 바꾸지만 계속해서 기록합니다. 권한 문서에 따르면 "파일이 git에서 추적되거나 .claude가 심볼릭 링크인 경우, Claude Code는 이를 리포지토리 제공 파일로 간주하고 폴더를 신뢰할 때까지 규칙을 보류합니다." Apiiro는 사용자에게 이 사실이 고지되지 않으며 "다음 승인 내용이 추적 중인 파일에 추가됩니다"라고 덧붙였습니다.
Apiiro는 또한 누가 파일을 커밋했는지 추적했습니다. "실제 비밀 정보가 포함된 1,105개 리포지토리 중 539개에서 Claude가 공동 작성(co-authored)한 커밋이 파일을 변경했습니다." 그 이유는 Claude Code의 커밋 지침에 .env나 credentials.json 같은 파일은 명시되어 있지만, "자체 설정 파일은 그 목록에 없기 때문"이라는 설명입니다.
Apiiro의 발견 내용
이 수치들은 2026년 11월 1일부터 3일까지 기본 브랜치에서 실행된 읽기 전용 GitHub 코드 및 커밋 검색 결과입니다. Apiiro는 어떤 자격 증명도 테스트하지 않았다고 밝혔습니다. "어떤 자격 증명도 사용되거나 테스트되지 않았으며, 어떤 호스트와도 접촉하지 않았습니다."
주요 통계:
- 파일 자체: "GitHub에 공개된 104,185개의 이 파일 사본 중 1,122개에 실제 비밀 정보가 포함되어 있었습니다."
- 현재 사본 내 고유 비밀 정보: "이들은 총 1,379개의 고유한 비밀 정보를 보유하고 있었습니다: 636개의 제공자 키와 743개의 공개 호스트용 비밀번호 또는 토큰입니다."
- 데이터베이스 액세스: Apiiro는 379개의 데이터베이스 비밀번호와 122개의 Supabase 서비스 역할 키, 그리고 103개의 Supabase 계정 토큰을 확인했습니다.
- 서버 로그인: "공개 서버용 SSH 자격 증명 43개, 그중 일부는 sshpass 명령어 내의 루트 비밀번호였습니다."
- 조직: "63개의 조직이 공개 허용 목록(allowlist)에 실제 비밀 정보를 보유하고 있었습니다." Apiiro는 대부분의 비밀 정보가 개인 개발자의 소유라고 밝혔습니다.
두 가지 발견 사항은 단순히 파일을 삭제하는 것만으로는 부족한 이유를 설명합니다. 첫째, 파일이 오랫동안 방치되는 경향이 있습니다. "실제 비밀 정보가 있는 리포지토리의 중앙값은 파일이 처음 커밋된 지 217일이 지난 시점이었습니다." 둘째, 히스토리에 남아 있습니다. "파일의 이전 버전에는 현재 사본에는 나타나지 않는(주로 파일이 삭제되었기 때문) 734개의 실제 비밀 정보가 509개 리포지토리에 남아 있습니다."
파일 크기가 클수록 더 많은 정보가 들어 있습니다. Apiiro는 "8KB 이상의 파일 10개 중 1개꼴로 실제 비밀 정보가 포함되어 있었으며, 500바이트 미만 파일은 500개 중 1개 미만이었습니다"라고 기록했습니다.
비밀 정보 스캐너가 이를 놓치는 이유
비밀 정보 스캐너가 이를 잡아낼 것이라고 예상할 수 있습니다. Apiiro는 모든 파일에 대해 gitleaks와 TruffleHog를 실행했습니다. "실제 비밀 정보가 포함된 1,122개 파일 중 gitleaks는 564개를, TruffleHog는 643개를 찾아냈으며, 215개는 둘 다 찾아내지 못했습니다."
그 이유는 비밀 정보의 형태 때문입니다. 스캐너는 알려진 키 형식을 찾습니다. PGPASSWORD=, sshpass -p, 또는 mysql -p 뒤에 입력된 비밀번호는 일반적인 명령줄의 일반 단어처럼 보입니다. Apiiro의 요약은 다음과 같습니다. "간극은 명령어 내부의 비밀번호입니다."
하나의 파일만이 아닙니다
이 부분은 권한 설정을 넘어선 연구의 핵심입니다. Apiiro는 다음과 같이 기술합니다. "에이전트가 실행 내용을 기록하는 모든 곳(기록(transcripts), memory 파일, 인수인계 노트 등)에서 동일한 '명령어 내 비밀번호' 패턴이 나타나며, 키 형식에 맞춰진 스캐너는 이 모든 곳에서 이를 놓칩니다."
다른 파일들에 대한 표에는 다음이 포함됩니다:
- 공유된
.claude/settings.json: 확인된 76,011개의 공개 사본 중 298개 파일에 실제 비밀 정보가 있었습니다. 팀 단위에서 이 파일을 의도적으로 커밋하는 경우가 있습니다. - 리포지토리에 저장된 에이전트 채팅 기록: 2,523개 확인, 87개 리포지토리 내 120개 파일.
- 에이전트 memory 파일 (MEMORY.md 등): 1,200개 확인, 9개 리포지토리.
- 인수인계 및 배포 노트: 2,095개 확인, 33개 파일. Apiiro는 "비밀 정보가 포함된 인수인계 노트의 1/3은 에이전트가 직접 작성한 것"이라고 덧붙였습니다.
memory 파일의 수는 적지만 패턴은 동일합니다. 에이전트가 수행한 작업에 대해 기록하는 모든 내용은 명령어에 포함된 무엇이든 담을 수 있습니다. 에이전트가 관리하는 파일에 프로젝트 컨텍스트를 보관한다면, 해당 파일들도 설정 파일과 동일한 주의가 필요합니다.
기본적으로 Claude Code는 세션 기록을 홈 디렉터리의 ~/.claude/projects 아래에 저장합니다. Claude Code 세션 히스토리 찾기 가이드는 이 정보가 어디에 저장되고 얼마나 오래 보관되는지 다룹니다. Apiiro의 기록 수치는 사람들이 리포지토리에 저장한 여러 도구의 내보내기 파일을 포함합니다.
사용자의 머신에서도 마찬가지입니다
대부분의 사본은 GitHub에 도달하지 않지만, Apiiro는 그렇다고 해서 안전한 것은 아니라고 주장합니다. "허용 목록은 모든 프로젝트의 동일한 경로에 있는 평문 JSON이며, 그 안의 대부분의 비밀 정보는 그것이 열어주는 호스트 바로 옆에 위치합니다." 또한 git 없이도 파일이 유출될 수 있음을 지적합니다. "게시된 npm 패키지, copy 명령어로 빌드된 Docker 이미지, zip 압축 파일 또는 동기화된 폴더 등을 통해서입니다."
하나의 리포지토리를 여러 체크아웃에서 작업하는 경우, 파일은 한 곳에 위치합니다. 문서에 따르면 worktree에서 Claude Code는 "메인 체크아웃 루트의 파일을 사용합니다." Claude Code worktrees가 memory를 공유하는지 여부 가이드는 worktrees 간에 공유되는 다른 요소들을 설명합니다.
Anthropic의 입장
Apiiro는 발표 전 Anthropic과 연구 내용을 공유했다고 밝혔습니다. 11월 8일 자 업데이트에서 Apiiro는 Claude Code의 책임자가 11월 7일 Hacker News에서 응답했다고 보고했습니다.
업데이트에 따르면, 그는 팀이 "이를 방지하기 위해 무엇을 할 수 있는지 검토 중"이라며, "auto 모드가 이를 포착하도록 보장하고, 기본적인 비밀 정보 스캐닝 기능을 내장하는 것" 등의 프로토타입 계획을 언급했습니다. 또한 Apiiro는 그의 견해를 인용하여, 노출된 사본들은 수동으로 생성되어 체크인된 것으로 보이며, 권한 규칙보다는 auto 모드와 GitHub 및 기타 호스트가 제공하는 비밀 정보 스캐닝을 권장했다고 전했습니다.
2026년 11월 10일까지 출시된 Claude Code 릴리스 노트에는 승인 저장 방식의 변경 사항이 기술되어 있지 않습니다. 이를 미해결 이슈로 취급하고, 수정 사항에 의존하기 전에 변경 로그를 확인하세요.
사람들이 흔히 시도하는 실수
파일을 삭제하고 삭제를 커밋하기. 현재 사본은 제거되지만, 히스토리, 포크(fork), 또는 클론은 제거되지 않습니다. Apiiro는 현재 사본에는 없는 734개의 비밀 정보를 바로 여기서 발견했습니다.
전역 제외 설정이 모든 머신을 보호한다고 가정하기. Claude Code가 파일을 작성한 머신만 보호합니다. 새로운 클론, CI 러너, 또는 나중에 리포지토리가 된 폴더에는 해당 설정이 없습니다.
비밀 정보 스캐너에만 의존하기. Apiiro가 테스트한 두 스캐너 모두 상당수의 파일을 놓쳤습니다. 명령어 내부의 비밀번호는 키처럼 보이지 않기 때문입니다.
동일한 긴 명령어를 반복해서 승인하기. 상시 승인을 할 때마다 문자 그대로의 규칙이 추가되며, Apiiro는 파일이 클수록 비밀 정보가 포함될 확률이 훨씬 높다는 것을 발견했습니다.
해결책: 점검, 교체, 그리고 정리
1단계: 모든 사본 찾기
GitHub 조직에서 .claude/settings.local.json 및 .claude/settings.json을 검색하세요. 그런 다음 현재 파일이 없더라도 각 리포지토리의 git 히스토리에서 해당 파일을 확인하세요. 본인의 머신에서 모든 사본을 찾아 허용 목록을 읽어보세요. Claude Code 내부에서 /permissions를 입력하면 규칙 목록과 각 규칙이 온 설정 파일을 확인할 수 있습니다.
2단계: 삭제 전 교체(Rotate)
Apiiro가 권장하는 순서는 "교체 우선, 정리 차선"입니다. 어떤 커밋에서든 파일에 포함되었던 모든 자격 증명은 노출된 것으로 간주해야 합니다. 파일을 제거해도 히스토리, 포크, 클론은 지워지지 않습니다.
3단계: 파일 추적 해제 및 리포지토리 보호
파일이 추적 중이라면, Apiiro는 git rm --cached .claude/settings.local.json으로 추적을 해제하고 리포지토리 자체의 .gitignore에 추가할 것을 권장합니다. 이렇게 하면 보호 설정이 사용자 머신뿐만 아니라 프로젝트와 함께 이동하게 됩니다.
4단계: 승인 방식 변경
커밋되지 않은 파일이라 하더라도 비밀 정보가 포함된 모든 규칙을 삭제하세요. 그런 다음 명령어에 비밀 정보를 직접 입력하는 것을 중단하세요. 변수 이름으로 참조하면 규칙에는 값 대신 이름이 기록됩니다. 문자 그대로의 명령어 대신 패턴을 승인하세요. 문서의 예시인 Bash(npm run *)는 npm run build와 npm run test --watch 모두에 매칭됩니다. 패턴의 범위를 주의 깊게 설정하세요. 문서에 따르면 첫 번째 * 이전의 모든 내용이 규칙을 제한하는 기준이 되기 때문입니다.
5단계: 에이전트 파일을 민감 정보로 취급
.claude/, 저장된 기록, 인수인계 노트, 에이전트 memory 파일을 히스토리를 포함하여 프리커밋(pre-commit) 및 CI 비밀 정보 스캐닝 대상에 추가하세요. 스캐너가 키 형식뿐만 아니라 명령어 내부의 비밀번호도 확인하는지 확인하세요.
MemoryLake에서 설정하기
Apiiro의 발견은 결국 하나의 습관으로 귀결됩니다. 에이전트는 자신이 한 일을 기록하고, 당신이 명령어에 입력한 모든 것이 그 기록에 남는다는 것입니다. 설정 파일, 기록, memory 파일 모두 작업을 기록합니다. 이들 각각에서 명령어에 포함된 내용은 작업 내용과 함께 기록될 수 있습니다.
MemoryLake는 서비스가 사용하는 데이터베이스, 스테이징 환경의 위치, 팀이 실행하는 명령어 등 어시스턴트가 알길 원하는 프로젝트 컨텍스트를 위한 memory 계층입니다. ChatGPT, Claude Code, Codex 등 연결된 어시스턴트에서 사용할 수 있습니다.
사용자는 자신의 언어로 직접 항목을 작성합니다. .claude 폴더, 설정 파일, 세션 기록, auto memory, 리포지토리 또는 어떤 벤더의 저장소에서도 정보를 읽거나 쓰거나 삭제하지 않습니다. Claude Code의 권한 규칙은 Anthropic이 설명한 대로 작동하며, 사용자는 여전히 위에서 설명한 대로 설정 파일을 정리해야 합니다.
1단계: API 키 생성
로그인 후 대시보드에서 키를 생성하세요. 다른 자격 증명과 마찬가지로 리포지토리 외부에 보관하세요.

2단계: 첫 번째 memory 업로드
자격 증명이 아닌 컨텍스트를 작성하세요. 스크립트가 기대하는 환경 변수 이름, 서비스가 실행되는 호스트, 팀이 키를 교체할 때 따르는 단계 등입니다. 항목당 하나의 사실만 기록하고, 비밀번호나 토큰은 절대 기록하지 마세요.

3단계: AI 및 에이전트 연결
Claude Code 및 사용하는 다른 어시스턴트를 연결하세요. 비밀 정보는 비밀 관리자(secrets manager)에 안전하게 보관하면서, 동일한 작성된 컨텍스트를 활용할 수 있습니다.

실제 작업에서 바뀌는 점
첫 번째 차이점은 컨텍스트와 자격 증명 사이의 명확한 구분입니다. 프로젝트 지식은 사용자가 작성한 항목에 보관되고, 시스템을 여는 값들은 그 용도로 구축된 곳에 보관됩니다.
두 번째는 세션에 비밀 정보를 붙여넣을 이유가 줄어든다는 점입니다. 어시스턴트가 어떤 변수에 연결 문자열이 있는지 이미 알고 있다면, 명령어는 해당 변수를 참조하기만 하면 됩니다.
Claude Code 권한 설정을 위한 모범 사례
승인 전 명령어를 읽으세요. 특히 데이터베이스나 서버에 연결할 때 주의하세요.
문자 그대로의 명령어가 아닌 패턴을 승인하세요. Bash(npm run *)와 같은 규칙은 한 번 입력한 인수를 포함하지 않습니다.
비밀 정보를 변수에 보관하세요. 그러면 규칙에는 변수 이름이 기록됩니다.
리포지토리 자체의 .gitignore에 파일을 추가하세요. 본인의 머신에만 있는 전역 제외 설정에 의존하지 마세요.
허용 목록을 정기적으로 검토하세요. /permissions는 모든 규칙과 그 출처를 보여줍니다.
에이전트 파일과 히스토리를 스캔하세요. 설정, 기록, 인수인계 노트, memory 파일 모두 명령어를 포함할 수 있습니다.
의심스러우면 교체(Rotate)하세요. 삭제하더라도 히스토리와 포크에는 남습니다.
결론
Claude Code에서 셸 명령어에 대해 다시 묻지 않도록 옵션을 선택하면, Claude Code는 해당 명령어를 .claude/settings.local.json에 허용 규칙으로 저장합니다. 명령어에 비밀번호나 토큰이 포함되어 있었다면 규칙에도 포함됩니다. Claude Code는 파일을 생성할 때 전역 git 제외 설정에 추가하지만, 이 보호 기능은 리포지토리와 함께 이동하지 않습니다. Apiiro는 실제 비밀 정보를 포함한 1,122개의 공개 파일 사본을 발견했으며, 확인한 모든 에이전트 파일에서 2,539개의 고유한 비밀 정보를 찾아냈습니다.
리포지토리와 히스토리에서 해당 파일을 확인하고, 포함되었던 모든 정보를 교체하며, 추적을 해제하고 리포지토리의 .gitignore에 추가한 뒤, 명령어 승인 방식을 바꾸세요. 그리고 memory 파일을 포함하여 에이전트가 작성하는 모든 파일을 비밀 정보가 포함될 수 있는 민감한 것으로 취급하십시오.