본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 19. 04:10

우리 엔지니어링 팀 전체에서 Claude Code를 실제로 거버넌스하기 위해 필요했던 것들

요약

Claude Code 사용 시 발생할 수 있는 보안 취약점과 엔지니어링 팀 차원의 거버넌스 구축 필요성을 다룹니다. 최근 발견된 CVE 사례를 통해 API 키 관리, 트래픽 가시성, 파일 시스템 제어 및 MCP 서버 관리의 중요성을 강조합니다.

핵심 포인트

  • Claude Code는 터미널 기반 도구로 웹 앱과는 다른 보안 사고 모델이 필요함
  • 저장소 클로닝만으로 RCE가 가능한 CVE-2025-59536 취약점 주의
  • 환경 변수 조작을 통한 API 키 탈취 위험(CVE-2026-21852) 인지 필요
  • API 키 관리, 트래픽 가시성, 파일 시스템 제어 등 4가지 핵심 격차 해결 필요

요약 (TL;DR)

  • Claude Code의 공격 표면(attack surface)은 대부분의 팀이 인식하는 것보다 더 넓습니다. 2026년 초에 발견된 두 건의 CVE는 저장소(repo)를 클로닝하는 것만으로도 API 키를 도난당하거나 개발자의 머신에서 임의의 코드를 실행하기에 충분하다는 것을 보여주었습니다.
  • 우리가 발견한 네 가지 격차: 관리되지 않는 API 키, 중앙 집중식 트래픽 가시성 부재, 파일 시스템 제어 부재, 그리고 완전히 거버넌스되지 않은 채 실행되는 MCP 서버입니다.
  • 이 네 가지를 모두 해결하는 것은 단순히 패치를 적용하는 것 이상이 필요했습니다. 터미널 기반의 AI 도구를 어떻게 취급해야 하는지에 대한 다른 사고 모델(mental model)이 필요했습니다.

몇 달 전, 우리 보안 팀은 감사(audit) 과정에서 한 가지 사항을 지적했습니다. 60명 이상의 엔지니어가 Claude Code를 사용하고 있었지만, 이에 대한 우리의 "거버넌스(governance)"는 사실상 전무했습니다. API 키는 .bash_profile 파일에 들어 있었습니다. 사람들이 어떤 모델을 호출하고 있는지, 비용이 얼마나 발생하는지, 또는 누가 무엇에 접근할 수 있는지 확인할 방법이 없었습니다. 누군가 회사를 떠날 때, 그들이 어떤 머신에 키를 설정했는지 찾아내지 않고서는 Claude Code 접근 권한을 깔끔하게 취소할 방법이 없었습니다.

우리는 Claude.ai를 위해 SSO, 도메인 캡처, 관리 콘솔 등 모든 올바른 조치를 취했습니다. 하지만 Claude Code는 다른 종류의 문제입니다. 이것은 웹 앱이 아닙니다. 개발자의 전체 파일 시스템 권한을 가진 터미널에서 실행되며, 브라우저 세션이 아닌 API 키로 인증합니다. 우리의 웹 계층 제어 중 그 어떤 것도 Claude Code에 영향을 미치지 못했습니다.

감사 결과는 불편했습니다. 그러다 CVE가 발생하면서 상황은 긴급해졌습니다.

경종을 울린 사건: Claude Code에 대한 생각을 바꿔놓은 두 건의 CVE

2026년 초, Check Point Research는 Claude Code의 두 가지 취약점에 대한 조사 결과를 발표했습니다 — CVE-2025-59536CVE-2026-21852 — 이 결과는 우리가 이 문제를 잘못 생각하고 있었다는 것을 깨닫게 해주었습니다.

CVE-2025-59536 (CVSS 8.7): 저장소 내의 악의적인 .claude/settings.json 파일은 Claude Code가 신뢰 대화창(trust dialog)을 표시하기도 전에 임의의 셸 명령(shell commands)을 실행할 수 있었습니다. 이전 버전에서는 해당 파일에 정의된 훅(hooks)이 사용자의 확인 절차를 거치기 전, 시작 시점에 바로 실행되었습니다. 공격자의 저장소를 클론(cloning)하고 그 안에서 claude를 실행하는 것만으로도 개발자의 머신에서 원격 코드 실행(RCE)을 일으키기에 충분했습니다.

CVE-2026-21852 (CVSS 5.3): 이 취약점은 성격이 달랐습니다. Claude Code는 API 요청을 어디로 보낼지 결정하기 위해 ANTHROPIC_BASE_URL이라는 환경 변수(environment variable)를 사용합니다. 악의적인 저장소는 설정 파일을 통해 이를 덮어씌워, 개발자의 API 키가 포함된 인증 헤더(authentication header)를 포함한 모든 트래픽을 공격자가 제어하는 서버로 리다이렉트(redirecting)할 수 있었습니다. 공격자는 아무런 이상이 없어 보이도록 요청을 실제 Anthropic API로 프록시(proxies) 처리합니다. 개발자는 아무것도 눈치채지 못하며, 공격자는 당신의 키를 손에 넣게 됩니다.

두 취약점 모두 현재 패치되었습니다 (CVE-2025-59536은 v1.0.111에서, CVE-2026-21852는 v2.0.65에서 패치됨). 하지만 제 머릿속에 남은 것은 특정 취약점 그 자체가 아니라, 그 취약점들이 드러낸 근본적인 가정이었습니다. 우리 모두 .claude/settings.json을 수동적인 설정(passive config)으로 취급해 왔습니다. 하지만 그렇지 않습니다. 셸 명령을 실행하고 외부 API를 호출할 수 있는 에이전트형 도구(agentic tool)에서, 저장소 수준의 설정은 실행 계층(execution layer)의 일부입니다. 이는 악의적인 package.json의 postinstall 스크립트와 동일한 위협 모델(threat model)입니다. 우리는 단지 아직 그 방식으로 생각하지 못했을 뿐입니다.

CVE 공개 이후, 저희 팀은 저장소 전체를 전수 조사하였고, 표준이 아닌 ANTHROPIC_BASE_URL 재정의(overrides)가 포함된 .claude/settings.json 파일이 있는 저장소 3개를 발견했습니다. 악의적인 것은 없었습니다. 개발자들이 정당한 로컬 테스트를 위해 설정해 둔 것이었습니다. 하지만 이 설정들은 해당 저장소를 클론하는 다른 누구에게라도 트래픽을 리다이렉트했을 것입니다. 저희는 이를 제거하고 CI 체크(CI check)를 추가했습니다. 그러고 나서 실제 거버넌스(governance) 문제에 대한 작업을 시작했습니다.

격차 1: API 키가 완전히 관리되지 않음

이 부분은 인정하기 가장 민망한 점이었습니다. Claude Code를 사용하는 모든 개발자는 다음 중 하나에 해당했습니다:

a) 개인용 Anthropic 키 사용 (이는 개인 결제 방식, 감사 추적(audit trail) 불가, 퇴사 시 권한 회수 불가 등을 의미함)
b) 어딘가 공유된 .env 파일에 저장된 팀 공용 키 사용 (이것이 더 심각함)

지나고 보니 해결책은 명확해 보였습니다. Anthropic Admin Console을 통해 명시적인 만료 기간이 설정된 키를 발급하고, 이를 AWS Secrets Manager 또는 HashiCorp Vault에 저장하며, .bash_profile이나 셸 히스토리(shell history)에 절대 남지 않도록 하는 것입니다. 분기별로 키를 교체(rotate)하고, 퇴사 시 즉시 회수(revoke)해야 합니다.

하지만 더 근본적인 해결책은 Claude Code를 게이트웨이(gateway)를 통해 라우팅하여, Anthropic 키가 개발자의 로컬 머신에 아예 존재하지 않도록 만드는 것이었습니다. AI Gateway를 사용하면, 개발자는 권한이 제한된 가상 키(scoped virtual key)로 게이트웨이에 인증합니다. 실제 Anthropic 자격 증명(credential)은 게이트웨이의 시크릿 매니저(secrets manager)에 머무릅니다. 만약 개발자의 컴퓨터가 해킹당하더라도, 공격자가 얻는 것은 대시보드에서 즉시 회수할 수 있는 게이트웨이 키일 뿐입니다. 워크스페이스(workspace) 수준의 권한을 가진 가공되지 않은 Anthropic API 키가 아닙니다.

이 차이는 생각보다 훨씬 중요합니다. 탈취된 Anthropic 키는 워크스페이스의 모든 파일에 접근하고, 공유 데이터를 수정하며, 당신이 알아차리기도 전에 API 비용을 폭증시킬 수 있습니다. 반면 탈취된 게이트웨이 키는 모델 수준 및 예산 수준의 제한 사항이 내장된, 회수 가능한 토큰(token)을 얻게 됩니다.

격차 2: 실제로 어떤 일이 일어나고 있는지에 대한 가시성 부재

게이트웨이를 설정하기 전, Claude Code에 대한 우리의 "관측 가능성 (observability)"은 한 달에 한 번 Anthropic 결제 대시보드를 확인하며 움찔하는 것이 전부였습니다.

우리는 다음 사항들을 전혀 알 수 없었습니다:

  • 개발자들이 어떤 모델을 호출하고 있는지
  • 각 팀이 다른 팀에 비해 얼마나 지출하고 있는지
  • 누군가가 Claude Code를 통해 운영(production) 데이터를 전송하고 있는지
  • 모델을 사용할 수 없을 때 어떤 일이 발생하는지 (보통은 개발자가 상황을 모른 채 모호한 버그 리포트를 제출하는 것으로 끝남)

ANTHROPIC_BASE_URL을 게이트웨이(gateway)를 가리키도록 설정하는 것은 Claude Code 배포 시 수행할 수 있는 가장 영향력이 큰(highest-leverage) 단일 변경 사항입니다. 단 한 줄의 설정만으로 관측성 (observability)뿐만 아니라 모델 화이트리스트 (model allowlisting), 개발자별 속도 제한 (rate limits), 폴백 라우팅 (fallback routing), 그리고 예산 상한선 (budget caps) 등 모든 것에 대한 중앙 집중식 강제 적용 지점을 확보할 수 있습니다.

export ANTHROPIC_BASE_URL=https://<your-gateway-url>/api/inference/

이렇게 설정한 후, 우리는 개발자 귀속 정보가 포함된 요청 레벨의 트레이스 (traces), 팀별 모델당 토큰 지출 내역, 그리고 자동으로 탐지되는 비용 이상 징후를 확인할 수 있었습니다. 우리는 한 엔지니어가 Claude Code를 통해 배치 작업 (batch job)을 실행하여 단 한 오후 동안 평균 일일 지출의 약 3배를 생성하고 있는 것을 발견했습니다. 악의적인 의도는 없었습니다. 단지 방법을 몰랐을 뿐입니다. 우리는 개발자별 일일 제한을 설정했고, 별도의 정책 논의 없이도 문제가 해결되었습니다.

우리가 고생하며 배운 한 가지는 다음과 같습니다: 만약 Claude Admin Console의 서버 관리형 설정을 사용하여 Claude Code를 제어하고 있다면, ANTHROPIC_BASE_URL이 설정될 때 해당 설정들은 우회됩니다. 따라서 게이트웨이를 통해 라우팅하는 경우, 개발자가 덮어쓸 수 없도록 시스템 레벨의 관리형 설정 파일에 ANTHROPIC_BASE_URL 설정을 배포하기 위한 MDM (macOS의 Jamf, Linux의 Puppet/Ansible)이 필요합니다:

  • macOS: /Library/Application Support/ClaudeCode/managed-settings.json
  • Linux: /etc/claude-code/managed-settings.json

이는 또한 CVE-2026-21852에 대한 직접적인 완화책이기도 합니다. MDM을 통해 ANTHROPIC_BASE_URL이 OS 레벨에서 설정되고 잠겨 있다면, 악성 저장소 (malicious repo)의 .claude/settings.json이 이를 덮어쓸 수 없습니다.

간극 3: 로컬 머신은 완전히 개방되어 있었다

게이트웨이를 구축하더라도, 게이트웨이는 네트워크 레벨의 트래픽만 제어합니다. 개발자의 머신에서 실행되는 Claude Code는 여전히 .env 파일, .ssh 키, ~/.aws/credentials, 그리고 로컬 사용자가 접근할 수 있는 그 어떤 것이든 읽을 수 있으며, 해당 콘텐츠는 네트워크에 도달하기 전에 프롬프트 (prompt)에 포함될 수 있습니다.

우리는 오후 시간을 할애하여 기본 managed-settings.json을 구성했습니다. 우리가 최종적으로 결정한 버전은 다음과 같습니다:

{
  "permissions": {
    "disableBypassPermissionsMode": "disable",
...

여기 몇 가지 설정이 가장 핵심적인 역할을 합니다:

allowManagedPermissionRulesOnly: true — 이것은 CVE-2025-59536 완화 조치입니다. 이는 프로젝트 수준의 .claude/settings.json 파일이 새로운 권한을 추가할 수 없으며, 오직 시스템 수준의 관리형 설정(managed config)만 적용됨을 의미합니다. 악성 저장소(repo)가 해당 머신에서 Claude Code가 수행할 수 있는 권한을 확장할 수 없습니다.

allowManagedHooksOnly: true — 훅 주입(hook injection)을 차단합니다. 훅(Hooks)은 세션 사이에 임의의 코드를 실행할 수 있는데, 이 설정은 클론된 저장소가 새로운 훅을 등록하는 것을 방지합니다.

disableBypassPermissionsMode: "disable" — 스크립트나 CI에서 --dangerously-skip-permissions 플래그가 사용되는 것을 방지합니다. 우리는 이 플래그를 사용 중이던 두 개의 CI 워크플로우를 발견했으며, 두 곳 모두 리팩터링(refactored)을 진행했습니다.

거부(deny) 목록.env, .ssh, 그리고 자격 증명(credentials) 디렉토리에 대한 읽기 권한을 차단합니다. 이에 대해 논의가 있었는데, 일부 개발자들은 이것이 정당한 워크플로우를 방해한다고 불만을 제기했습니다. 우리는 기본적으로 문을 열어두는 대신, 명시적인 허용(allow)을 통해 사례별로 예외를 적용했습니다.

샌드박싱(Sandboxing)은 그 위에 OS 수준의 격리를 추가합니다. macOS에서는 Seatbelt를 사용하고, Linux에서는 bubblewrap을 사용합니다. 이는 Claude Code 자체의 권한 시스템보다 낮은 계층에서 파일 시스템 및 네트워크 경계를 강제합니다.

격차 4: MCP가 완전히 통제되지 않은 상태로 실행됨

이것은 우리가 깨닫는 데 가장 오랜 시간이 걸린 격차였습니다. 왜냐하면 MCP는 그것이 실제로 무엇인지 깨닫기 전까지는 단순한 개발자 경험(developer experience) 기능처럼 보이기 때문입니다. MCP의 실체는 Claude Code가 내부 시스템에 직접 프로그래밍 방식으로 접근하는 것입니다.

우리 개발자들은 Claude Code를 GitHub(코드 검색용), Jira(티켓 컨텍스트용), 그리고 몇 개의 내부 API에 연결해 두었습니다. 이 모든 연결은 개발자 머신에 로컬로 구성되었으며, 각기 다른 곳에 자체 자격 증명이 저장되어 있었습니다. 승인 프로세스도, 감사 추적(audit trail)도 없었으며, 세션 중에 Claude가 어떤 도구들을 호출했는지 확인할 방법도 없었습니다.

여기서 프롬프트 인젝션 (prompt injection) 위험은 과소평가되어 있습니다. Claude가 MCP 도구를 통해 외부 시스템(GitHub 이슈, Jira 티켓, 웹 페이지 등)에서 콘텐츠를 가져올 때, 해당 콘텐츠는 Claude의 컨텍스트 (context)로 들어옵니다. 만약 그 콘텐츠에 주입된 지침 (injected instructions)이 포함되어 있다면, Claude는 이를 조용히 실행할 수 있습니다. 저희는 외부 벤더로부터 온 Jira 티켓에 서식 지정 지침처럼 보이는 내용이 포함되어 있었고, Claude Code가 이를 명령어로 해석했던 사례가 있었습니다. 다행히 나쁜 일은 일어나지 않았지만, 이 사건은 문제를 매우 구체적으로 체감하게 만든 아찔한 순간이었습니다.

해결책은 허용 목록 (allowlist)을 가진 게이트웨이 (gateway)를 통해 MCP 액세스를 중앙 집중화하는 것이었습니다. 저희는 모든 MCP 서버 액세스를 위한 단일 엔드포인트 (endpoint)로 TrueFoundry의 MCP Gateway를 배포했습니다. managed-settings.json 설정은 다음과 같습니다:

{
  "allowedMcpServers": [
    { "serverUrl": "https://<your-mcp-gateway-url>/*" }
...

strictKnownMarketplaces를 빈 배열로 설정하면 마켓플레이스에서 소싱된 MCP 서버 설치를 차단할 수 있습니다. 이제 개발자들은 Claude 마켓플레이스에서 무작위로 MCP 서버를 추가할 수 없습니다. 모든 새로운 서버는 저희의 검토 프로세스를 거쳐 게이트웨이에 등록되어야 합니다.

게이트웨이 자체를 통해 얻은 이점은 다음과 같습니다. 각 개발자는 한 번만 인증하면 되며, 게이트웨이가 GitHub, Jira 및 기타 모든 서비스에 대한 다운스트림 인증 (downstream auth)을 처리합니다. RBAC (역할 기반 액세스 제어)를 통해 어떤 팀이 어떤 도구에 액세스할 수 있는지 제어합니다. 모든 도구 호출은 개발자의 신원, 도구 이름, 요청 및 응답, 그리고 지연 시간 (latency)을 포함하는 감사 추적 (audit trace)을 생성합니다. 저희는 Claude가 어떤 모델을 호출했는지뿐만 아니라, 세션 중에 정확히 무엇을 건드렸는지 확인할 수 있습니다.

가상 MCP 서버 (Virtual MCP Servers) 기능은 보안 팀의 액세스 권한 관리에 진정으로 유용하다는 것이 밝혀졌습니다. 저희는 제품 엔지니어들이 사용할 수 있는 광범위한 도구 세트와 분리하여, 보안 워크플로우와 관련된 Sentry 및 Datadog 도구만 노출하는 "보안 도구" 엔드포인트를 설정했습니다. 에이전트 (Agents)는 오직 허용된 것만 볼 수 있습니다.

최종 상태의 모습

감사 이후 6개월이 지난 현재, 저희의 설정은 다음과 같습니다:

Identity (ID/신원): SSO + Claude.ai를 위한 도메인 캡처 (domain capture). 모든 Claude Code 키는 TrueFoundry를 통해 발급되는 게이트웨이 가상 키(gateway virtual keys)이며, 자동으로 교체(rotated)되고, 단일 대시보드 작업을 통해 퇴사 시 즉시 취소(revoked)됩니다.

Routing (라우팅): 모든 개발자 머신에 MDM을 통해 TrueFoundry AI Gateway를 가리키는 ANTHROPIC_BASE_URL을 배포합니다. 개발자별 일일 토큰 제한(daily token limits) 및 팀별 예산 상한(budget caps)을 설정합니다. 모델 허용 목록(model allowlist)을 운영합니다 (비용이 많이 드는 특정 모델은 정당한 필요성이 있는 특정 팀으로 제한했습니다).

Sandboxing (샌드박싱): 권한 거부 목록(permission deny-list)과 샌드박스(sandbox)가 활성화된 managed-settings.json을 MDM을 통해 배포합니다. allowManagedPermissionRulesOnlyallowManagedHooksOnly는 모두 true로 설정합니다.

MCP: 단일 MCP 엔드포인트로서 TrueFoundry MCP Gateway를 사용합니다. 모든 다운스트림 서버(downstream servers)는 등록 및 승인된 상태여야 합니다. 도구 수준의 RBAC (Role-Based Access Control, 역할 기반 액세스 제어)를 적용합니다. 전체 감사 추적(audit trail)은 Datadog으로 내보내집니다.

Audit logging (감사 로깅): 모든 데이터는 OpenTelemetry를 통해 게이트웨이를 거쳐 Datadog으로 흐릅니다. 90일간 보관됩니다. 팀, 모델 및 애플리케이션별 지출 요약 보고서를 매주 받으며, 특정 개발자의 사용량이 7일 평균보다 3배 이상 급증할 경우 알림을 받습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0