Claude Code와 Agent SDK는 사용자를 대신하여 코드를 실행하고, 파일에 접근하며, 외부 서비스와 상호작용할 수 있는 강력한 도구입니다. 이러한 기능을 가진 모든 도구와 마찬가지로, 신중하게 배포하면 적절한 제어를 유지하면서 이점을 얻을 수 있습니다.
미리 정해진 코드 경로를 따르는 전통적인 소프트웨어와 달리, 이러한 도구는 컨텍스트와 목표에 기반하여 동적으로 작업을 생성합니다. 이러한 유연성이 유용한 이유이지만, 처리하는 콘텐츠(파일, 웹페이지 또는 사용자 입력)에 의해 동작이 영향을 받을 수 있다는 것을 의미하기도 합니다. 이를 때때로 프롬프트 인젝션이라고 합니다. 예를 들어, 리포지토리의 README에 비정상적인 지시사항이 포함되어 있으면, Claude Code가 운영자가 예상하지 못한 방식으로 이를 작업에 반영할 수 있습니다. 이 가이드는 이러한 위험을 줄이는 실용적인 방법을 다룹니다.
좋은 소식은 에이전트 배포를 보호하는 데 특별한 인프라가 필요하지 않다는 것입니다. 반신뢰 코드를 실행할 때 적용되는 동일한 원칙이 여기에도 적용됩니다: 격리, 최소 권한, 심층 방어. Claude Code에는 일반적인 우려 사항을 해결하는 여러 보안 기능이 포함되어 있으며, 이 가이드에서는 이러한 기능과 함께 추가 강화가 필요한 경우를 위한 옵션을 안내합니다.
모든 배포에 최대 보안이 필요한 것은 아닙니다. 노트북에서 Claude Code를 실행하는 개발자는 멀티 테넌트 환경에서 고객 데이터를 처리하는 기업과는 다른 요구사항을 가집니다. 이 가이드는 Claude Code의 내장 보안 기능부터 강화된 프로덕션 아키텍처까지 다양한 옵션을 제시하므로, 상황에 맞는 것을 선택할 수 있습니다.
에이전트는 프롬프트 인젝션(처리하는 콘텐츠에 포함된 지시사항) 또는 모델 오류로 인해 의도하지 않은 작업을 수행할 수 있습니다. Claude 모델은 이에 저항하도록 설계되었으며, 모델 카드에서 분석한 바와 같이, Claude Opus 4.6이 현재 가장 강력한 프론티어 모델이라고 믿습니다.
그럼에도 심층 방어는 여전히 좋은 관행입니다. 예를 들어, 에이전트가 고객 데이터를 외부 서버로 전송하라고 지시하는 악성 파일을 처리하는 경우, 네트워크 제어가 해당 요청을 완전히 차단할 수 있습니다.
Claude Code에는 일반적인 우려 사항을 해결하는 여러 보안 기능이 포함되어 있습니다. 전체 세부 사항은 보안 문서를 참조하세요.
Claude Code의 기본값 이상의 추가 강화가 필요한 배포의 경우, 이러한 원칙이 사용 가능한 옵션을 안내합니다.
보안 경계는 서로 다른 신뢰 수준을 가진 구성 요소를 분리합니다. 높은 보안 배포의 경우, 민감한 리소스(예: 자격 증명)를 에이전트가 포함된 경계 외부에 배치할 수 있습니다. 에이전트 환경에서 문제가 발생하더라도 해당 경계 외부의 리소스는 보호됩니다.
예를 들어, 에이전트에 API 키에 대한 직접 접근 권한을 부여하는 대신, 에이전트 환경 외부에서 프록시를 실행하여 요청에 키를 주입할 수 있습니다. 에이전트는 API 호출을 할 수 있지만, 자격 증명 자체는 볼 수 없습니다. 이 패턴은 멀티 테넌트 배포 또는 신뢰할 수 없는 콘텐츠를 처리할 때 유용합니다.
필요한 경우, 에이전트를 특정 작업에 필요한 기능만으로 제한할 수 있습니다:
| 리소스 | 제한 옵션 |
|---|---|
| 파일 시스템 | 필요한 디렉토리만 마운트, 읽기 전용 선호 |
| 네트워크 | 프록시를 통해 특정 엔드포인트로 제한 |
| 자격 증명 | 직접 노출 대신 프록시를 통해 주입 |
| 시스템 기능 | 컨테이너에서 Linux 기능 제거 |
높은 보안 환경의 경우, 여러 제어를 계층화하면 추가적인 보호를 제공합니다. 옵션에는 다음이 포함됩니다:
올바른 조합은 위협 모델과 운영 요구사항에 따라 달라집니다.
서로 다른 격리 기술은 보안 강도, 성능 및 운영 복잡성 간에 서로 다른 트레이드오프를 제공합니다.
이러한 모든 구성에서 Claude Code(또는 Agent SDK 애플리케이션)는 격리 경계 내부—샌드박스, 컨테이너 또는 VM—에서 실행됩니다. 아래에 설명된 보안 제어는 해당 경계 내에서 에이전트가 접근할 수 있는 것을 제한합니다.
| 기술 | 격리 강도 | 성능 오버헤드 | 복잡성 |
|---|---|---|---|
| 샌드박스 런타임 | 양호 (안전한 기본값) | 매우 낮음 | 낮음 |
| 컨테이너 (Docker) | 설정에 따라 다름 | 낮음 | 중간 |
| gVisor | 우수 (올바른 설정 시) | 중간/높음 | 중간 |
| VM (Firecracker, QEMU) | 우수 (올바른 설정 시) | 높음 | 중간/높음 |
컨테이너 없이 경량 격리를 위해, sandbox-runtime은 OS 수준에서 파일 시스템 및 네트워크 제한을 적용합니다.
주요 장점은 단순성입니다: Docker 구성, 컨테이너 이미지 또는 네트워킹 설정이 필요하지 않습니다. 프록시와 파일 시스템 제한이 내장되어 있습니다. 허용된 도메인과 경로를 지정하는 설정 파일을 제공하면 됩니다.
작동 방식:
bubblewrap, macOS의 sandbox-exec)를 사용하여 구성된 경로에 대한 읽기/쓰기 접근을 제한합니다설정:
npm install @anthropic-ai/sandbox-runtime그런 다음 허용된 경로와 도메인을 지정하는 구성 파일을 만듭니다.
보안 고려사항:
동일 호스트 커널: VM과 달리 샌드박스된 프로세스는 호스트 커널을 공유합니다. 커널 취약점이 이론적으로 탈출을 가능하게 할 수 있습니다. 일부 위협 모델에서는 이것이 허용 가능하지만, 커널 수준 격리가 필요한 경우 gVisor 또는 별도의 VM을 사용하세요.
TLS 검사 없음: 프록시는 도메인을 허용 목록에 추가하지만 암호화된 트래픽을 검사하지 않습니다. 에이전트가 허용된 도메인에 대한 허용적인 자격 증명을 가지고 있는 경우, 해당 도메인을 사용하여 다른 네트워크 요청을 트리거하거나 데이터를 유출하는 것이 불가능한지 확인하세요.
많은 단일 개발자 및 CI/CD 사용 사례에서 sandbox-runtime은 최소한의 설정으로 보안 수준을 크게 높입니다. 아래 섹션에서는 더 강력한 격리가 필요한 배포를 위한 컨테이너와 VM을 다룹니다.
컨테이너는 Linux 네임스페이스를 통해 격리를 제공합니다. 각 컨테이너는 호스트 커널을 공유하면서 파일 시스템, 프로세스 트리 및 네트워크 스택에 대한 자체 뷰를 가집니다.
보안이 강화된 컨테이너 구성은 다음과 같을 수 있습니다:
docker run \
--cap-drop ALL \
--security-opt no-new-privileges \
--security-opt seccomp=/path/to/seccomp-profile.json \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
--tmpfs /home/agent:rw,noexec,nosuid,size=500m \
--network none \
--memory 2g \
--cpus 2 \
--pids-limit 100 \
--user 1000:1000 \
-v /path/to/code:/workspace:ro \
-v /var/run/proxy.sock:/var/run/proxy.sock:ro \
agent-image각 옵션의 역할은 다음과 같습니다:
| 옵션 | 목적 |
|---|---|
--cap-drop ALL | 권한 상승을 가능하게 할 수 있는 NET_ADMIN 및 SYS_ADMIN과 같은 Linux 기능을 제거합니다 |
--security-opt no-new-privileges | setuid 바이너리를 통해 프로세스가 권한을 얻는 것을 방지합니다 |
--security-opt seccomp=... | 사용 가능한 시스콜을 제한합니다; Docker 기본값은 약 44개를 차단하며, 사용자 정의 프로필은 더 많이 차단할 수 있습니다 |
--read-only | 컨테이너의 루트 파일 시스템을 불변으로 만들어 에이전트가 변경 사항을 지속하는 것을 방지합니다 |
--tmpfs /tmp:... | 컨테이너가 중지되면 지워지는 쓰기 가능한 임시 디렉토리를 제공합니다 |
--network none | 모든 네트워크 인터페이스를 제거합니다; 에이전트는 아래에 마운트된 Unix 소켓을 통해 통신합니다 |
--memory 2g | 리소스 고갈을 방지하기 위해 메모리 사용량을 제한합니다 |
--pids-limit 100 | 포크 폭탄을 방지하기 위해 프로세스 수를 제한합니다 |
--user 1000:1000 | 비루트 사용자로 실행합니다 |
-v ...:/workspace:ro | 에이전트가 분석할 수 있지만 수정할 수 없도록 코드를 읽기 전용으로 마운트합니다. ~/.ssh, ~/.aws 또는 ~/.config와 같은 민감한 호스트 디렉토리를 마운트하지 마세요 |
-v .../proxy.sock:... | 컨테이너 외부에서 실행되는 프록시에 연결된 Unix 소켓을 마운트합니다 (아래 참조) |
Unix 소켓 아키텍처:
--network none을 사용하면 컨테이너에 네트워크 인터페이스가 전혀 없습니다. 에이전트가 외부 세계에 도달할 수 있는 유일한 방법은 마운트된 Unix 소켓을 통하는 것이며, 이 소켓은 호스트에서 실행되는 프록시에 연결됩니다. 이 프록시는 도메인 허용 목록을 적용하고, 자격 증명을 주입하며, 모든 트래픽을 로깅할 수 있습니다.
이것은 sandbox-runtime에서 사용하는 것과 동일한 아키텍처입니다. 에이전트가 프롬프트 인젝션을 통해 손상되더라도 임의의 서버로 데이터를 유출할 수 없습니다—프록시를 통해서만 통신할 수 있으며, 프록시가 도달 가능한 도메인을 제어합니다. 자세한 내용은 Claude Code 샌드박싱 블로그 포스트를 참조하세요.
추가 강화 옵션:
| 옵션 | 목적 |
|---|---|
--userns-remap | 컨테이너 루트를 비권한 호스트 사용자에 매핑합니다; 데몬 구성이 필요하지만 컨테이너 탈출로 인한 피해를 제한합니다 |
--ipc private | 교차 컨테이너 공격을 방지하기 위해 프로세스 간 통신을 격리합니다 |
표준 컨테이너는 호스트 커널을 공유합니다: 컨테이너 내부의 코드가 시스템 호출을 하면 호스트를 실행하는 동일한 커널로 직접 전달됩니다. 이는 커널 취약점이 컨테이너 탈출을 허용할 수 있음을 의미합니다. gVisor는 시스템 호출이 호스트 커널에 도달하기 전에 사용자 공간에서 가로채어 이를 해결하며, 실제 커널을 사용하지 않고 대부분의 시스콜을 처리하는 자체 호환성 레이어를 구현합니다.
에이전트가 악성 코드를 실행하는 경우(아마도 프롬프트 인젝션으로 인해), 해당 코드는 컨테이너에서 실행되며 커널 익스플로잇을 시도할 수 있습니다. gVisor를 사용하면 공격 표면이 훨씬 작아집니다: 악성 코드는 먼저 gVisor의 사용자 공간 구현을 익스플로잇해야 하며 실제 커널에 대한 접근이 제한됩니다.
Docker와 함께 gVisor를 사용하려면 runsc 런타임을 설치하고 데몬을 구성합니다:
// /etc/docker/daemon.json
{
"runtimes": {
"runsc": {
"path": "/usr/local/bin/runsc"
}
}
}그런 다음 다음과 같이 컨테이너를 실행합니다:
docker run --runtime=runsc agent-image성능 고려사항:
| 워크로드 | 오버헤드 |
|---|---|
| CPU 바운드 연산 | ~0% (시스콜 가로채기 없음) |
| 단순 시스콜 | ~2배 느림 |
| 파일 I/O 집약적 | 무거운 open/close 패턴의 경우 최대 10-200배 느림 |
멀티 테넌트 환경이나 신뢰할 수 없는 콘텐츠를 처리할 때, 추가 격리는 종종 오버헤드의 가치가 있습니다.
VM은 CPU 가상화 확장을 통해 하드웨어 수준 격리를 제공합니다. 각 VM은 자체 커널을 실행하여 강력한 경계를 만듭니다—게스트 커널의 취약점이 호스트를 직접 손상시키지 않습니다. 그러나 VM이 gVisor와 같은 대안보다 자동으로 "더 안전한" 것은 아닙니다. VM 보안은 하이퍼바이저와 장치 에뮬레이션 코드에 크게 의존합니다.
Firecracker는 경량 마이크로VM 격리를 위해 설계되었습니다—125ms 미만으로 VM을 부팅할 수 있으며 5 MiB 미만의 메모리 오버헤드로, 불필요한 장치 에뮬레이션을 제거하여 공격 표면을 줄입니다.
이 접근 방식에서 에이전트 VM은 외부 네트워크 인터페이스가 없습니다. 대신 vsock(가상 소켓)을 통해 통신합니다. 모든 트래픽은 vsock을 통해 호스트의 프록시로 라우팅되며, 프록시는 허용 목록을 적용하고 자격 증명을 주입한 후 요청을 전달합니다.
클라우드 배포의 경우, 위의 격리 기술 중 하나를 클라우드 네이티브 네트워크 제어와 결합할 수 있습니다:
credential_injector 필터가 있는 Envoy)를 실행합니다에이전트는 종종 API를 호출하고, 리포지토리에 접근하며, 클라우드 서비스와 상호작용하기 위해 자격 증명이 필요합니다. 과제는 자격 증명 자체를 노출하지 않으면서 이러한 접근을 제공하는 것입니다.
권장 접근 방식은 에이전트의 보안 경계 외부에서 프록시를 실행하여 발신 요청에 자격 증명을 주입하는 것입니다. 에이전트는 자격 증명 없이 요청을 보내고, 프록시가 이를 추가한 후 목적지로 요청을 전달합니다.
이 패턴에는 여러 이점이 있습니다:
Claude Code는 프록시를 통해 샘플링 요청을 라우팅하는 두 가지 방법을 지원합니다:
옵션 1: ANTHROPIC_BASE_URL (간단하지만 샘플링 API 요청에만 해당)
export ANTHROPIC_BASE_URL="http://localhost:8080"이것은 Claude Code와 Agent SDK에 Anthropic API 대신 프록시로 샘플링 요청을 보내도록 지시합니다. 프록시는 평문 HTTP 요청을 수신하고, 이를 검사 및 수정(자격 증명 주입 포함)한 후 실제 API로 전달할 수 있습니다.
옵션 2: HTTP_PROXY / HTTPS_PROXY (시스템 전체)
export HTTP_PROXY="http://localhost:8080"
export HTTPS_PROXY="http://localhost:8080"Claude Code와 Agent SDK는 이러한 표준 환경 변수를 준수하여 모든 HTTP 트래픽을 프록시를 통해 라우팅합니다. HTTPS의 경우, 프록시는 암호화된 CONNECT 터널을 생성합니다: TLS 검사 없이는 요청 내용을 보거나 수정할 수 없습니다.
자체 프록시를 구축하거나 기존 프록시를 사용할 수 있습니다:
credential_injector 필터가 있는 프로덕션급 프록시Anthropic API에서의 샘플링 외에도, 에이전트는 종종 다른 서비스—git 리포지토리, 데이터베이스, 내부 API—에 대한 인증된 접근이 필요합니다. 두 가지 주요 접근 방식이 있습니다:
에이전트의 보안 경계 외부에서 실행되는 서비스로 요청을 라우팅하는 MCP 서버 또는 사용자 정의 도구를 통해 접근을 제공합니다. 에이전트는 도구를 호출하지만, 실제 인증된 요청은 외부에서 발생합니다—도구가 자격 증명을 주입하는 프록시를 호출합니다.
예를 들어, git MCP 서버는 에이전트의 명령을 수락하지만 호스트에서 실행되는 git 프록시로 전달할 수 있으며, 이 프록시는 원격 리포지토리에 연결하기 전에 인증을 추가합니다. 에이전트는 자격 증명을 볼 수 없습니다.
장점:
Anthropic API 호출의 경우, ANTHROPIC_BASE_URL을 사용하면 요청을 평문으로 검사하고 수정할 수 있는 프록시로 라우팅할 수 있습니다. 그러나 다른 HTTPS 서비스(GitHub, npm 레지스트리, 내부 API)의 경우, 트래픽은 종종 엔드투엔드로 암호화됩니다—HTTP_PROXY를 통해 프록시로 라우팅하더라도 프록시는 불투명한 TLS 터널만 볼 수 있으며 자격 증명을 주입할 수 없습니다.
사용자 정의 도구를 사용하지 않고 임의의 서비스에 대한 HTTPS 트래픽을 수정하려면, 트래픽을 복호화하고 검사 또는 수정한 후 전달하기 전에 다시 암호화하는 TLS 종료 프록시가 필요합니다. 이를 위해서는:
HTTP_PROXY/HTTPS_PROXY를 구성하여 트래픽을 프록시를 통해 라우팅합니다이 접근 방식은 사용자 정의 도구를 작성하지 않고도 모든 HTTP 기반 서비스를 처리하지만, 인증서 관리와 관련된 복잡성이 추가됩니다.
모든 프로그램이 HTTP_PROXY/HTTPS_PROXY를 준수하는 것은 아닙니다. 대부분의 도구(curl, pip, npm, git)는 준수하지만, 일부는 이러한 변수를 무시하고 직접 연결할 수 있습니다. 예를 들어, Node.js fetch()는 기본적으로 이러한 변수를 무시합니다; Node 24+에서는 NODE_USE_ENV_PROXY=1을 설정하여 지원을 활성화할 수 있습니다. 포괄적인 적용을 위해 proxychains를 사용하여 네트워크 호출을 가로채거나, iptables를 구성하여 아웃바운드 트래픽을 투명 프록시로 리디렉션할 수 있습니다.
투명 프록시는 네트워크 수준에서 트래픽을 가로채므로 클라이언트가 이를 사용하도록 구성할 필요가 없습니다. 일반 프록시는 클라이언트가 명시적으로 연결하고 HTTP CONNECT 또는 SOCKS를 사용해야 합니다. 투명 프록시(투명 모드의 Squid 또는 mitmproxy 등)는 리디렉션된 원시 TCP 연결을 처리할 수 있습니다.
두 접근 방식 모두 여전히 TLS 종료 프록시와 신뢰할 수 있는 CA 인증서가 필요합니다—단지 트래픽이 실제로 프록시에 도달하도록 보장할 뿐입니다.
파일 시스템 제어는 에이전트가 읽고 쓸 수 있는 파일을 결정합니다.
에이전트가 코드를 분석해야 하지만 수정할 필요가 없는 경우, 디렉토리를 읽기 전용으로 마운트합니다:
docker run -v /path/to/code:/workspace:ro agent-image코드 디렉토리에 대한 읽기 전용 접근도 자격 증명을 노출할 수 있습니다. 마운트하기 전에 제외하거나 정리해야 할 일반적인 파일:
| 파일 | 위험 |
|---|---|
.env, .env.local | API 키, 데이터베이스 비밀번호, 시크릿 |
~/.git-credentials | 평문의 Git 비밀번호/토큰 |
~/.aws/credentials | AWS 접근 키 |
~/.config/gcloud/application_default_credentials.json | Google Cloud ADC 토큰 |
~/.azure/ | Azure CLI 자격 증명 |
~/.docker/config.json | Docker 레지스트리 인증 토큰 |
~/.kube/config | Kubernetes 클러스터 자격 증명 |
.npmrc, .pypirc | 패키지 레지스트리 토큰 |
*-service-account.json | GCP 서비스 계정 키 |
*.pem, *.key | 개인 키 |
필요한 소스 파일만 복사하거나 .dockerignore 스타일 필터링을 사용하는 것을 고려하세요.
에이전트가 파일을 작성해야 하는 경우, 변경 사항을 지속할지 여부에 따라 몇 가지 옵션이 있습니다:
컨테이너의 임시 작업 공간의 경우, 메모리에만 존재하고 컨테이너가 중지되면 지워지는 tmpfs 마운트를 사용합니다:
docker run \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
--tmpfs /workspace:rw,noexec,size=500m \
agent-image변경 사항을 지속하기 전에 검토하려면, 오버레이 파일 시스템을 사용하면 에이전트가 기본 파일을 수정하지 않고 쓸 수 있습니다—변경 사항은 검사, 적용 또는 폐기할 수 있는 별도의 레이어에 저장됩니다. 완전히 영구적인 출력의 경우, 전용 볼륨을 마운트하되 민감한 디렉토리와 분리하여 유지합니다.
Was this page helpful?