클로드 코드 샌드박스: OS 레벨 격리로 안전하게 코딩하기
클로드 코드를 써보셨다면 “이 명령어를 실행해도 될까요?”라는 팝업이 익숙하실 겁니다. 처음엔 안전장치니까 반갑지만 반복되면 점점 피로해지죠. 결국 내용을 대충 훑고 승인 버튼을 누르게 되는데 이러면 오히려 보안에 취약해집니다. Claude Code의 샌드박스는 이 문제를 해결합니다. 명령어를 일일이 검사하는 대신 OS 레벨에서 실행 환경 자체를 격리해서 안전한 경계 안에서는 자유롭게, 경계 밖으로는 절대 못 나가게 만드는 거죠.
왜 샌드박스가 필요한가
클로드 코드 권한 설정에서 다뤘던 권한 시스템은 “이 도구를 써도 되는가?”를 판단합니다. 유용하긴 한데 Bash 명령어 하나하나에 대해 승인을 요청하다 보면 개발 흐름이 끊기고 사용자는 승인 피로(approval fatigue)에 빠지게 돼요.
샌드박스는 접근 방식이 다릅니다. “이 경계 안에서는 마음껏 해”라고 울타리를 쳐놓는 겁니다. 울타리 안에서 실행되는 명령어는 승인 없이 자동 실행되고 울타리 밖으로 나가려는 시도는 OS가 차단합니다. 승인 팝업은 줄어들고 보안은 오히려 강화되는 셈이죠.
여기서 중요한 점이 있습니다. 파일 시스템 격리와 네트워크 격리는 반드시 함께 적용해야 해요. 네트워크 격리 없이 파일 시스템만 보호하면 악의적인 코드가 SSH 키 같은 민감한 파일을 외부로 빼돌릴 수 있습니다. 반대로 파일 시스템 격리 없이 네트워크만 차단하면 시스템 파일을 조작해서 네트워크 접근 권한을 확보할 수 있거든요.
파일 시스템 격리
샌드박스가 파일 시스템을 격리하는 방식은 직관적입니다.
현재 작업 디렉토리와 하위 디렉토리에는 읽기/쓰기가 가능합니다.
그 외 경로는 기본적으로 읽기만 허용되고 ~/.bashrc나 /bin/ 같은 민감한 시스템 파일은 아예 접근이 차단돼요.
프롬프트 인젝션 공격으로 Claude의 판단이 흐려지더라도 샌드박스가 시스템 파일 수정을 물리적으로 막아주니까 걱정할 필요가 없습니다.
클로드 코드 설정 가이드에서 다룬 settings.json의 Read와 Edit deny 규칙으로 더 세밀한 파일 접근 제어를 추가할 수도 있어요.
네트워크 격리
네트워크 격리는 샌드박스 외부에서 동작하는 프록시 서버를 통해 구현됩니다. 모든 네트워크 요청이 이 프록시를 거치기 때문에 허용된 도메인만 접근할 수 있죠.
허용되지 않은 도메인으로 요청을 보내면 OS 레벨에서 차단되고 사용자에게 알림이 갑니다. 이때 요청을 거부하거나 한 번만 허용하거나 설정을 업데이트해서 계속 허용할 수 있어요.
이 제한은 Claude가 직접 실행하는 명령어뿐 아니라 그 명령어가 만드는 모든 자식 프로세스에도 적용됩니다.
npm install이 내부적으로 보내는 HTTP 요청도, 빌드 스크립트가 호출하는 API도 모두 같은 도메인 규칙을 따라요.
OS 레벨 강제 적용
샌드박스가 단순한 소프트웨어 제한이 아니라 OS 보안 기능을 활용한다는 점이 핵심입니다.
macOS에서는 Apple이 만든 Seatbelt 프레임워크를 사용합니다. 별도 설치 없이 바로 쓸 수 있어요.
Linux와 WSL2에서는 bubblewrap을 사용합니다. Ubuntu/Debian이라면 다음 명령으로 설치합니다.
sudo apt-get install bubblewrap socat
Fedora 사용자는 dnf로 설치하면 됩니다.
sudo dnf install bubblewrap socat
WSL1은 bubblewrap이 필요로 하는 커널 기능이 없어서 지원되지 않습니다. WSL1을 쓰고 있다면 WSL2로 업그레이드해야 해요.
OS 레벨 보안 프리미티브를 쓰기 때문에 Claude가 실행하는 명령어의 모든 자식 프로세스도 같은 보안 경계를 상속받습니다. 애플리케이션 레벨에서 우회할 방법이 사실상 없어요.
샌드박스 활성화
Claude Code에서 /sandbox 명령을 실행하면 샌드박스 설정 메뉴가 열립니다.
> /sandbox
필요한 패키지가 설치되지 않았으면 플랫폼별 설치 안내가 표시돼요.
샌드박스에는 두 가지 모드가 있습니다.
자동 허용 모드(Auto-allow)에서는 샌드박스 안에서 실행 가능한 Bash 명령어가 권한 확인 없이 자동으로 실행됩니다. 샌드박스 안에서 실행할 수 없는 명령어(허용되지 않은 도메인에 접근하는 경우 등)는 기존 권한 흐름을 따라요.
일반 권한 모드(Regular permissions)에서는 샌드박스 안에서 실행되더라도 모든 Bash 명령어가 기존 권한 확인을 거칩니다. 보안을 최우선으로 하는 환경에 적합하지만 팝업이 더 자주 뜨죠.
두 모드 모두 파일 시스템과 네트워크 격리는 동일하게 적용됩니다. 차이는 승인 과정에만 있어요.
자동 허용 모드는 권한 모드 설정과 독립적으로 동작합니다. “accept edits” 모드가 아니더라도 샌드박스 안의 Bash 명령은 자동 실행되니까 기억해 두세요.
설정 방법
클로드 코드 설정 가이드에서 다룬 settings.json으로 샌드박스 동작을 세밀하게 제어할 수 있습니다.
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"excludedCommands": ["docker", "git"],
"allowUnsandboxedCommands": true,
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"],
"allowLocalBinding": true
}
}
}
enabled는 샌드박스 활성화 여부입니다.
autoAllowBashIfSandboxed를 true로 설정하면 샌드박스 안에서 실행되는 Bash 명령은 권한 확인 없이 자동 허용됩니다.
샌드박스가 시스템을 보호해주니까 팝업 피로를 줄이면서도 안전하죠.
excludedCommands에 넣은 명령어는 샌드박스를 거치지 않고 실행됩니다.
docker는 샌드박스와 호환되지 않아서 여기에 넣어두는 것이 좋고 watchman을 쓰는 jest도 jest --no-watchman으로 실행하거나 제외 목록에 추가해야 합니다.
allowUnsandboxedCommands는 샌드박스 제한으로 명령어가 실패했을 때 샌드박스 밖에서 재시도할 수 있게 해주는 탈출구입니다.
이 경우 기존 권한 흐름을 거치기 때문에 사용자 승인 없이 실행되지는 않아요.
보안이 중요한 환경이라면 false로 설정해서 탈출구를 닫을 수 있습니다.
network.allowedDomains는 Bash 명령어가 접근할 수 있는 도메인 목록입니다.
와일드카드(*.npmjs.org)를 지원해서 하위 도메인을 한 번에 허용할 수 있어요.
network.allowLocalBinding을 true로 하면 로컬 포트 바인딩이 허용됩니다.
개발 서버를 띄울 때 필요하죠.
권한과 샌드박스의 관계
클로드 코드 권한 설정에서 다룬 권한 시스템과 샌드박스는 서로 다른 계층에서 보안을 담당합니다.
권한(Permissions)은 Claude Code가 어떤 도구를 쓸 수 있는지 제어합니다. Bash, Read, Edit, WebFetch, MCP 등 모든 도구에 적용되고 도구가 실행되기 전에 평가돼요.
샌드박스(Sandbox)는 Bash 명령어와 그 자식 프로세스가 접근할 수 있는 파일과 네트워크를 OS 레벨에서 격리합니다. Bash 명령에만 적용되지만 프롬프트 인젝션으로 권한 시스템이 우회되더라도 추가 방어선 역할을 해요.
이 둘을 함께 쓰면 다층 방어(defense-in-depth)가 완성됩니다.
{
"permissions": {
"deny": ["Bash(curl *)", "Bash(wget *)"],
"allow": ["Bash(npm run *)"]
},
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"]
}
}
}
권한 시스템의 deny 규칙이 curl과 wget을 차단하고 샌드박스의 도메인 제한이 그 외 네트워크 접근도 통제합니다.
npm run *은 allow 규칙으로 허용하되 샌드박스가 실행 범위를 제한하니까 안전하게 자동 실행할 수 있죠.
파일 시스템과 네트워크 제한은 권한 규칙을 통해 설정합니다.
Read와 Edit의 deny 규칙으로 특정 파일이나 디렉토리 접근을 차단하고 WebFetch의 allow/deny 규칙으로 도메인 접근을 제어할 수 있어요.
샌드박스의 allowedDomains로 Bash 명령어가 접근할 수 있는 네트워크를 추가로 제한하는 식입니다.
프롬프트 인젝션 방어
샌드박스의 진가는 프롬프트 인젝션 공격을 받았을 때 드러납니다. 공격자가 악의적인 지시를 Claude에게 주입하더라도 샌드박스가 실제 피해를 막아주거든요.
파일 시스템 쪽에서는 ~/.bashrc 같은 설정 파일을 수정할 수 없고 /bin/ 아래의 시스템 바이너리도 건드릴 수 없습니다.
클로드 코드 권한 설정에서 deny로 설정한 파일도 당연히 못 읽어요.
네트워크 쪽에서는 허용 목록에 없는 서버로 데이터를 보낼 수 없습니다. 악성 스크립트 다운로드나 승인되지 않은 API 호출도 차단되죠.
악성 NPM 패키지, 취약한 빌드 스크립트, 소셜 엔지니어링 공격 등 여러 위협에 대해 피해 범위를 줄일 수 있어요.
보안 한계
샌드박스가 만능은 아닙니다. 알고 있어야 할 한계가 몇 가지 있어요.
네트워크 필터링은 도메인 단위로 동작합니다.
프록시를 통과하는 트래픽 내용 자체를 검사하지는 않아요.
github.com처럼 범용 도메인을 허용하면 데이터 유출 경로가 될 수 있고 도메인 프론팅 기법으로 필터링을 우회할 가능성도 있습니다.
신뢰할 수 있는 도메인만 허용 목록에 넣는 것이 중요해요.
allowUnixSockets 옵션으로 유닉스 소켓 접근을 허용하면 의도치 않게 강력한 시스템 서비스에 접근할 수 있습니다.
예를 들어 /var/run/docker.sock에 접근을 허용하면 Docker 소켓을 통해 호스트 시스템에 접근하는 것이 가능해져요.
파일 시스템 쓰기 권한을 너무 넓게 설정하면 권한 상승(privilege escalation) 공격이 가능합니다.
$PATH에 포함된 디렉토리나 .bashrc, .zshrc 같은 셸 설정 파일에 쓰기를 허용하면 다른 보안 컨텍스트에서 코드가 실행될 수 있어요.
Linux에는 Docker 컨테이너 내부처럼 권한이 제한된 환경을 위한 enableWeakerNestedSandbox 옵션이 있습니다.
이름 그대로 보안이 약화되니까 추가 격리가 보장되는 환경에서만 써야 해요.
커스텀 프록시 설정
조직 차원의 네트워크 보안이 필요하다면 커스텀 프록시를 설정할 수 있습니다. HTTPS 트래픽을 복호화해서 검사하거나 커스텀 필터링 규칙을 적용할 수 있고 모든 네트워크 요청을 로깅하거나 기존 보안 인프라와 통합하는 것도 가능해요.
{
"sandbox": {
"network": {
"httpProxyPort": 8080,
"socksProxyPort": 8081
}
}
}
오픈 소스
샌드박스 런타임은 오픈 소스 npm 패키지로 공개되어 있어서 자체 프로젝트에서도 활용할 수 있습니다. MCP 서버를 샌드박스 안에서 실행하고 싶다면 이렇게 쓰면 돼요.
npx @anthropic-ai/sandbox-runtime <실행할-명령어>
AI 에이전트를 개발하는 분이라면 구현 세부사항과 소스 코드를 GitHub 저장소에서 확인해보세요.
마치며
Claude Code의 샌드박스는 “일일이 물어보고 허가받는” 보안에서 “울타리 안에서 자유롭게 뛰노는” 보안으로 전환해줍니다. OS 레벨 격리로 파일 시스템과 네트워크를 동시에 보호하니까 프롬프트 인젝션 같은 공격이 들어와도 피해를 막을 수 있어요.
처음 쓸 때는 /sandbox 명령으로 활성화한 뒤 자동 허용 모드를 켜는 것만으로도 체감이 확 달라집니다.
그 뒤에 도메인 허용 목록과 제외 명령어를 프로젝트에 맞게 조정하면 돼요.
클로드 코드 권한 설정으로 도구별 접근을 제어하고 샌드박스로 Bash 실행 환경을 격리한 뒤 클로드 코드 Hooks로 커스텀 검증 로직까지 더하면 안전하면서도 흐름이 끊기지 않는 AI 코딩 환경을 만들 수 있습니다. 이런 설정을 팀 전체에 배포하고 싶다면 플러그인으로 묶어서 마켓플레이스에 올리는 방법도 살펴보세요. 샌드박스 런타임의 공식 문서와 소스 코드도 참고해보세요.
This work is licensed under
CC BY 4.0