Claude Code 서버 실행 시 보안 및 격리 방법
Claude Code가 사용자 권한으로 shell 명령어를 실행할 때 발생하는 위험을 방지하는 방법을 설명합니다. skip permissions flag의 역할과 sandbox, container, 일회용 VPS를 활용한 단계별 격리 전략을 확인하십시오.
서버에서 Claude Code를 안전하게 실행한다는 의미
서버에서 Claude Code를 안전하게 실행하려면, 권한 승인 프롬프트를 켜두고, 전용 비특권 사용자(unprivileged user)로 실행하며, 무인 실행(unattended runs) 시 신뢰 대신 실제 경계(boundary)를 제공해야 합니다. 그 경계는 내장된 sandbox, container, 또는 중요한 데이터가 없는 일회용 VPS입니다. --dangerously-skip-permissions flag를 사용하면 모델과 shell 사이의 승인 단계가 제거됩니다. 이 방식은 무인 작업 시 합리적일 수 있으나, 단 하나의 잘못된 명령어가 도달할 수 있는 범위를 제한하는 경계 내부에서만 유효합니다. 이 가이드는 해당 flag가 실제로 무엇을 변경하는지, 그리고 단계별 격리(rungs of increasing isolation)를 통해 어떻게 경계를 구축하는지 설명합니다.
Claude Code가 시스템에서 수행할 수 있는 작업
Claude Code는 terminal에서 실행되는 coding agent입니다. 이 도구는 실행한 사용자의 권한으로 파일을 읽고, 파일을 쓰고, shell 명령어를 실행합니다. 이것이 이 도구의 핵심 가치입니다. 사용자가 명령어를 일일이 입력하지 않아도 repository를 clone하고, 코드를 수정하고, 테스트를 실행하고, 실패 원인을 읽고, 코드를 수정하는 루프를 수행할 수 있습니다. 아직 서버에 설정하지 않았다면, tmux를 사용하여 VPS에서 Claude Code 실행하기에서 설치 및 세션 관리 방법을 확인할 수 있습니다. 이 페이지에서는 설치 후 부여하게 될 권한에 대해 다룹니다.
위험 요소는 동일한 문장을 두 번 읽는 것과 같습니다. 사용자의 권한으로 shell 명령어를 실행하는 프로세스는 사용자가 할 수 있는 모든 일을 할 수 있습니다. ~/.ssh/id_ed25519, ~/.aws/credentials, 그리고 사용자가 열 수 있는 모든 .env 파일을 읽을 수 있습니다. curl를 실행하고 서버가 도달할 수 있는 모든 host로 데이터를 보낼 수 있습니다. git push --force를 실행할 수도 있습니다. agent 자체에는 의도가 없습니다. 위험은 작업이 잘못되거나, 작업 중 읽은 텍스트에 다른 사람이 작성한 명령어가 포함되어 있을 때 발생합니다. 예를 들어, 가져온 웹 페이지나 수정 요청받은 issue의 comment가 해당됩니다. 후자는 prompt injection이라고 하며, 이것이 "모델은 보통 합리적이다"라는 말이 보안 계획이 될 수 없는 이유입니다. 보안은 평균적인 상황이 아니라 잘못된 실행 상황에 대비해야 합니다.
권한 시스템의 개념 설명
기본적으로 Claude Code는 행동하기 전에 확인을 요청합니다. 프로젝트 내부의 파일을 읽는 것은 조용히 진행되지만, 파일을 수정하거나 shell 명령어를 실행할 때는 정확한 수정 내용이나 명령어를 먼저 보여주고 승인을 기다립니다. 하나의 동작만 승인하거나, 해당 세션 동안 해당 종류의 동작을 모두 승인할 수 있습니다. 이러한 승인은 세션 범위(session-scoped)입니다. CLI를 종료하면 다음 세션은 다시 주의 깊은 상태로 시작됩니다. 유지하고 싶은 규칙이 있다면, settings file에 영구적인 allow, ask, deny 리스트를 저장할 수 있습니다. 예를 들어: git status 허용, git push 시 확인, .env 읽기 거부. Deny 규칙은 항상 우선합니다.
이 설계는 사람이 terminal을 지켜보고 있음을 가정하며, laptop 환경에서는 이것이 사실입니다. 서버에서는 대개 아무도 지켜보고 있지 않습니다. tmux 안에서 긴 작업을 시작하고 잠자리에 들면, 새벽 2시에 질문을 하기 위해 멈추는 agent는 아침까지 진전을 보이지 못합니다. 대기 시간은 시간뿐만 아니라 비용도 발생시킵니다. Claude Code 세션이 유휴 상태일 때 warm prompt cache를 잃기 때문에 다음 턴에서 이를 재구축하는 데 비용이 들기 때문입니다. 이것이 사람들이 서버에서 skip flag를 찾는 솔직한 이유이며, 그 문제가 실재한다는 뜻입니다. 이 가이드의 나머지 내용은 모든 보호 장치를 포기하지 않고 이 문제를 해결하는 방법에 관한 것입니다.
--dangerously-skip-permissions가 변경하는 사항
claude --dangerously-skip-permissions는 승인 단계를 끕니다. 수정 작업이 프롬프트 없이 수행됩니다. shell 명령어 또한 프롬프트 없이 실행됩니다. 일반적으로 민감한 위치를 보호하는 protected-path 체크도 건너뜁니다. 명시적인 deny 규칙은 여전히 적용되며, 극히 일부의 작업은 여전히 확인을 요청하지만, 요약하자면 모델이 실행하기로 결정한 모든 것이 실행됩니다.
서버에서 이 flag와 관련하여 중요한 두 가지 사실이 있습니다. 첫째, Linux 및 macOS에서 Claude Code가 root 또는 sudo로 실행될 경우 이 flag는 차단됩니다. 프롬프트가 없는 root는 시스템의 모든 파일이나 서비스를 변경할 수 있기 때문입니다. agent는 어차피 별도의 unprivileged account가 필요하며, 이 flag는 이를 강제합니다. 둘째, 이 flag는 모델의 동작을 어떤 방식으로도 변경하지 않습니다. 단지 루프에서 인간을 제거할 뿐이며 다른 것은 바꾸지 않으므로, 프롬프트가 잡아냈을 모든 실수가 이제 그대로 실행됩니다.
따라서 솔직한 계산은 다음과 같습니다. 권한을 건너뛰면 보안 질문은 "agent가 나쁜 짓을 할 것인가"에서 "한 번의 잘못된 행동이 얼마나 많은 피해를 줄 수 있는가"로 바뀝니다. 모든 결정을 통제하려 노력하는 대신, blast radius(폭발 반경)를 통제하기 시작해야 합니다. 정답은 격리(containment)이며, 이는 단계별로 이루어집니다.
내장된 Claude Code sandbox
단계별 격리에 앞서, Claude Code는 이제 실행하는 명령어에 대해 OS 레벨의 sandbox를 제공하며, 이는 사람들이 skip flag를 찾게 만들었던 대부분의 이유를 제거했음을 알아두십시오. Linux에서는 filesystem 격리를 위해 bubblewrap을 사용하며, network traffic을 proxy를 통해 라우팅하기 위해 socat을 사용합니다. sandbox 내부에서 명령어는 프로젝트 디렉토리와 세션 temp 디렉토리에만 파일을 쓸 수 있으며, network에는 allow list를 통해 검증된 domain을 통해서만 접속할 수 있습니다. 명령어가 새로운 domain에 접속하려 하면 Claude Code가 처음 한 번은 사용자에게 확인을 요청합니다.
세션 내에서 /sandbox 명령어로 이를 켤 수 있습니다. Ubuntu 및 Debian에서는 필요한 두 패키지를 먼저 설치하십시오.
sudo apt install bubblewrap socatUbuntu 24.04 이상에서는 기본 AppArmor policy가 bubblewrap의 user namespaces 생성을 차단합니다. sandbox panel에서 누락된 항목을 알려주며, Claude Code sandboxing documentation에 이를 해결하는 짧은 AppArmor profile이 포함되어 있습니다.
sandbox에는 auto-allow 모드가 있습니다. 격리된 명령어는 프롬프트 없이 실행되는데, 이는 강제된 경계가 기존의 프롬프트 역할을 대신하기 때문입니다. sandbox 내부에서 실행할 수 없는 명령어는 일반 권한 흐름으로 돌아가므로, 정말 특이한 동작은 여전히 확인을 요청합니다. 대부분의 서버 워크플로우에서 이것이 skip flag의 올바른 대체제입니다. 프롬프트가 아예 없는 대신, OS가 강제하는 경계가 있기 때문에 질문 횟수가 훨씬 줄어듭니다.
한계점을 명확히 인지하십시오. 기본적으로 sandboxed command는 사용자가 경로를 deny하지 않는 한 credential files를 포함한 filesystem의 대부분을 여전히 읽을 수 있습니다. sandbox.credentials 설정이 바로 이 용도로 존재합니다. network proxy는 domain name을 확인하며 traffic 자체를 검사하지 않으므로, github.com와 같은 광범위한 허용은 여전히 데이터 유출의 여지를 남깁니다. Docker는 sandbox 내부에서 작동하지 않습니다. sandbox는 보안 수준을 크게 높여주지만, 완전한 격리 경계는 아니므로 아래의 단계들이 여전히 중요합니다.
격리 단계 (The containment ladder)
격리 수준이 높아지는 순서대로 세 단계가 있습니다. 시스템에 설치된 다른 요소들에 맞춰 가장 낮은 단계를 선택하십시오.
Rung 1: 전용 비특권 사용자(dedicated unprivileged user). agent에게 자체 account, 자체 home directory, 자체 project directory를 부여하고 sudo 권한을 주지 않습니다.
sudo adduser --disabled-password --gecos "" agent이 account 경계는 agent가 사용자의 파일(SSH keys 및 시스템의 다른 모든 프로젝트)에 접근하는 것을 막아줍니다. 또한 flag가 root 실행을 거부하므로 skip flag를 사용할 수 있게 해줍니다. 이는 모든 서비스를 비특권 사용자로 실행하기와 동일한 원리를 agent에 적용한 것입니다. Rung 1이 제한하지 못하는 것은 network와 시스템의 world-readable 파일들입니다.
Rung 2: container. Anthropic은 Claude Code를 non-root 사용자로 실행하고, agent가 도달할 수 있는 host를 제한하는 firewall rules를 가진 reference devcontainer를 공개했습니다. 직접 구축한 container도 동일한 역할을 수행합니다. filesystem은 마운트한 volumes로 축소되며, egress는 container의 rules가 허용하는 범위로 축소됩니다. 서버에 중요한 다른 서비스들이 호스팅되고 있을 때 적합한 중간 단계입니다. 한계는 container가 host kernel을 공유하며, 잘못된 mount 하나가 경계를 무너뜨릴 수 있다는 점입니다. container에 /var/run/docker.sock를 부여하면 host 전체에 접근할 수 있습니다.
Rung 3: 전용 VPS. 가장 강력한 단계는 가장 단순합니다. agent에게 중요한 데이터가 없는 완전히 새로운 머신을 주는 것입니다. 작은 VPS는 한 달에 몇 달러면 충분합니다. 새 VPS에서의 첫 10분 runbook을 사용하여 설정하고, 깨끗한 상태를 snapshot한 뒤 agent에게 맡기십시오. 그곳에는 다른 것이 없습니다. 개인 SSH key도 없고, 오직 해당 repository에만 국한된 deploy key만 있습니다. 클라우드 credentials도, production data도 없습니다. 작업이 잘못되거나 깨끗한 상태가 필요하면 snapshot을 복원하거나 몇 분 만에 서버를 새로 구축하면 됩니다. blast radius는 임대료가 전부입니다. 이 설정에서는 --dangerously-skip-permissions가 더 이상 두렵지 않습니다. 최악의 결과가 서버 재구축과 토큰 하나를 무효화하는 것이기 때문입니다.
단계들은 중첩됩니다. sandbox를 사용하고, unprivileged user로 실행하며, 일회용 VPS 위에서 작동하는 agent는 추가 비용이 거의 들지 않으며 사고 발생 시의 시나리오를 단순하게 만듭니다. 단순함이 목표입니다.
자격 증명(Credentials) 보호
다른 모든 것보다 중요한 규칙: agent의 user는 다른 요소에 속한 secrets를 읽을 수 없어야 합니다.
API key는 agent에게만 부여하십시오. mode 600인 파일을 agent의 user 소유로 생성하고, shell이 시작될 때 로드하십시오.
install -m 600 /dev/null /home/agent/claude.env
echo 'export ANTHROPIC_API_KEY=your-key-here' >> /home/agent/claude.env
echo 'source ~/claude.env' >> /home/agent/.bashrc그다음 반대 방향도 차단하십시오. Debian 및 Ubuntu에서 home directories는 종종 모든 사용자가 읽을 수 있게 생성되므로, 본인의 디렉토리를 chmod 750 /home/youruser로 강화하십시오. ls -ld /home/*로 확인하고 agent account가 목록을 나열할 수 있는 항목을 수정하십시오.
모든 token에 범위를 제한(scope)하십시오. 하나의 repository로 제한된 세밀한 GitHub token이나 repository별 deploy key를 사용하면, 자격 증명이 유출되어도 전체 account가 아닌 하나의 project만 위험해집니다. sandbox를 사용한다면 credential settings를 추가하여 ~/.ssh 및 ~/.aws가 읽기조차 거부되도록 하십시오. 그리고 production credentials은 서버에 아예 두지 마십시오. 존재하지 않는 secret은 유출될 수 없습니다.
Git은 안전망입니다
agent가 수행하는 모든 변경 사항은 검토 및 되돌리기가 가능해야 합니다. agent가 branch에서 작업한다면 git이 이 두 가지를 무료로 제공합니다.
git switch -c agent/refactor-auth작업 후 git diff main...agent/refactor-auth로 검토하고, 좋은 결과물은 merge하며, 작업이 성과가 없다면 branch를 삭제하십시오. Forge 측에서 main branch를 보호하여 agent의 token이 push를 하거나 force-push를 할 수 없게 하십시오. commit history는 당신이 잠든 동안 발생한 일에 대한 audit log 역할을 하며, 이는 terminal scrollback보다 훨씬 가치가 큽니다.
Network는 blast radius의 일부입니다
agent는 curl를 실행할 수 있습니다. 이 문장이 egress 문제의 핵심입니다. agent가 읽을 수 있는 것은 어디든 보낼 수 있으며, prompt-injected agent는 그럴 가능성이 있습니다. 일반적인 unprivileged user는 이를 전혀 제한하지 못합니다. 모든 사용자가 서버가 도달할 수 있는 모든 곳에 도달할 수 있기 때문입니다. sandbox는 proxy를 통해 domain 단위로 이를 제한합니다. container는 자체 firewall rules로 이를 제한할 수 있습니다. 전용 VPS는 애초에 유출될 데이터 자체를 제한하며, 이는 세 가지 중 가장 강력한 방법입니다.
ufw만으로 egress를 해결하려 하지 마십시오. ufw는 기본적으로 모든 outgoing traffic을 허용하며, apt, npm, git, Claude API를 허용하면서도 나머지를 막는 outbound rules를 작성하는 것은 매우 까다롭고 조용히 깨질 수 있는 작업입니다. 대신 sandbox, container, 또는 machine 레벨에서 경계를 선택하십시오. 그곳에서는 domain allow list나 물리적으로 분리된 머신이 동일한 작업을 깔끔하게 수행합니다.
Claude Code를 실행하는 대신 API를 사용하여 직접 agent를 구축하는 경우에도 동일한 사고방식이 적용됩니다. VPS에서 Claude로 AI agent 구축하기에서 해당 경로를 다루며, 해당 agent 역시 동일한 전용 user, 동일한 scoped tokens, 동일한 일회용 box가 필요합니다.
먼저 서버를 강화하십시오
어떤 단계를 선택하든, agent가 들어오기 전에 머신 자체에 기본 설정이 필요합니다: SSH keys만 허용, root login 금지, default-deny firewall, 자동 보안 업데이트. 아래 체크리스트를 생성하여 한 번 실행하십시오.
FAQ
--dangerously-skip-permissions를 서버에서 안전하게 사용할 수 있습니까?
그 자체로는 그렇지 않습니다. 이 flag는 모든 승인 프롬프트를 제거하므로, 모델이 생성하는 즉시 첫 번째 잘못된 명령어가 실행됩니다. blast radius가 격리되었을 때만 타당한 선택이 됩니다. 최소한 전용 unprivileged user를 사용해야 하며, 완전한 무인 작업을 위해서는 하나의 project와 하나의 scoped token만 가진 container 또는 일회용 VPS를 사용해야 합니다. production credentials이나 잃어서는 안 될 데이터가 있는 머신에서는 절대 사용하지 마십시오.
Claude Code에 sandbox가 있습니까?
네. Claude Code는 shell 명령어를 위한 내장 sandbox를 제공하며, /sandbox 명령어로 활성화할 수 있습니다. Linux에서는 bubblewrap을, macOS에서는 Seatbelt을 사용하며, 쓰기 권한을 project directory로 제한하고, 승인된 domain만 허용하는 proxy를 통해 network access를 라우팅합니다. auto-allow 모드는 sandboxed command를 프롬프트 없이 실행하므로, skip flag처럼 중단을 줄이면서도 OS가 강제하는 경계를 유지합니다. 완전한 격리 경계는 아니므로, 무인 실행 시에는 전용 user나 전용 머신과 함께 사용하십시오.
왜 skip flag는 root로 실행되는 것을 거부합니까?
프롬프트가 없는 root는 시스템의 모든 파일과 서비스를 수정할 수 있기 때문입니다. Claude Code는 Linux 및 macOS에서 root 또는 sudo로 실행될 때 --dangerously-skip-permissions를 차단합니다. 해결책은 이 체크를 피하는 것이 아닙니다. agent를 위한 unprivileged user를 생성하여 거기서 실행하십시오. 해당 account 경계가 첫 번째이자 가장 저렴한 격리 계층입니다.
Claude Code가 내 SSH keys와 .env 파일을 읽을 수 있습니까?
실행 중인 user가 읽을 수 있는 것은 무엇이든 읽을 수 있습니다. sandbox의 기본 policy조차 사용자가 deny하기 전까지는 credential paths에 대한 읽기를 허용합니다. 따라서 agent를 별도의 user로 실행하고, 본인의 home directory를 mode 750 또는 그보다 엄격하게 유지하며, sandbox 설정에서 credential paths를 deny하고, production secrets는 서버에 아예 두지 마십시오. 서버에 애초에 없던 secret은 읽히거나 유출될 수 없습니다.
Claude Code를 무인으로 실행하는 가장 안전한 방법은 무엇입니까?
agent 작업 전용으로만 사용하는 저렴한 전용 VPS입니다. 10분 만에 강화하고, 깨끗한 상태를 snapshot하며, sandbox가 켜진 상태에서 unprivileged user로 Claude Code를 실행하고, mode-600 파일에 API key를 담으며, repository별 deploy key를 사용하고, 모든 작업은 merge 전 검토할 branch에서 수행하는 방식입니다. 작업이 잘못되면 토큰 하나를 무효화하고 snapshot을 복원하면 되며, 당신의 다른 자산에는 아무런 영향이 없습니다.