Tips & Tricks (업데이트: 2026. 6. 7.)

Claude Code 매일 안전하게 돌리기: 승인과 sandbox 경계 운영법

allow/ask/deny 경계, plan·acceptEdits·auto·bypassPermissions 사용 구분, dangerously-skip-permissions의 함정, sandbox를 쓰는 자리를 실무 시선으로 정리합니다.

Claude Code 매일 안전하게 돌리기: 승인과 sandbox 경계 운영법

“어쨌든 승인 창은 뜨니까, 뭐 괜찮겠지.”

처음 도입했을 때 저는 그렇게 생각했습니다. Claude Code가 뭔가 할 때마다 확인 창이 뜬다. 읽고 OK를 누른다. 안전 운전을 하고 있다고 믿었죠.

그런데 2주 뒤, 제 손가락이 어떻게 움직이는지 깨닫고 아찔했습니다. 확인 문구를 읽지도 않고 반사적으로 Enter를 누르고 있더군요. “늘 하던 흐름”이 된 동작은 더 이상 확인하지 않습니다. git push도, 외부 API 쓰기도, 내용을 보지 않고 그냥 통과시키고 있었습니다. 사고가 안 난 건 그저 운이 좋았을 뿐입니다.

승인 창은 많이 띄운다고 안전해지는 게 아닙니다. 너무 많으면 사람은 읽지 않게 되고, 너무 적으면 되돌릴 수 없는 작업까지 흘러갑니다. 오늘은 이 “경계 긋기”를 설정 항목 하나하나가 아니라 매일 어떻게 판단할지에 초점을 맞춰 써 보겠습니다.

핵심 요약

  • 승인은 “전부 멈추기”도 “전부 통과”도 아니라, 되돌릴 수 있는 작업은 빠르게, 되돌릴 수 없는 작업은 느리게 하는 게 축입니다. undo가 되느냐로 선을 긋습니다.
  • permission mode(default / acceptEdits / plan / auto / dontAsk / bypassPermissions)는 작업 단계에 맞춰 전환합니다. 탐색은 plan, 리뷰하며 고칠 땐 acceptEdits.
  • --dangerously-skip-permissions(= bypassPermissions)는 일상에서 쓰지 않습니다. 대신 auto mode나 sandbox를 씁니다.
  • sandbox는 Bash가 닿을 수 있는 “범위”를 OS 레벨에서 좁히는 장치입니다. macOS / Linux / WSL2에서 동작하고, native Windows에서는 동작하지 않습니다.
  • 팀에서는 “승인을 두는 자리”를 사람의 의지에 맡기지 말고, deny 규칙과 hook으로 물리적으로 고정합니다.

설정 파일 문법 자체는 자매 글 Claude Code 권한 설정 레퍼런스에, CLAUDE.md와 권한을 엮는 구체 레시피는 CLAUDE.md × 권한 레시피에 정리해 뒀습니다. 이 글은 “어디서 멈출 것인가”라는 운영 판단에만 집중합니다.

승인은 “되돌릴 수 있는가”로 선을 긋는다

경계 긋기로 헷갈릴 땐, 기술적 위험의 크기보다 먼저 딱 하나만 자문해 보세요.

“이거, 5분 뒤에 취소할 수 있어?”

파일을 읽고, grep 하고, diff를 보고, npm run build를 돌린다. 이건 몇 번을 해도 다시 할 수 있습니다. 최악의 경우라도 git checkout으로 돌아옵니다. 그러니 빠르게 돌리고 싶죠. 반대로 git push, 프로덕션 deploy, 메일 발송, 외부 DB 쓰기는 누른 순간 바깥 세계가 바뀝니다. 취소가 안 됩니다. 그래서 일부러 느리게 만듭니다.

제가 자주 쓰는 3단 분류는 이렇습니다.

작업판단이유
열람·grep·diff·build·test·lintallow되돌릴 수 있다. 속도를 떨어뜨리고 싶지 않다
브랜치 위의 코드 수정ask 또는 acceptEdits저장소 성숙도에 따라 다르다
push·deploy·publish·메일 발송·외부 API 쓰기ask바깥 세계에 영향을 준다. 취소 불가
.env 읽기·rm -rf·git reset --hard·curl | shdeny사고 났을 때 피해가 너무 크다

여기서 가장 헷갈리는 게 “수정”입니다. 수정이 무조건 위험한 건 아닙니다. 테스트가 잘 갖춰진 개인용 저장소라면 수정을 빠르게 돌려도 무섭지 않습니다. 오히려 무서운 건, 테스트가 약한 프로덕션에 가까운 저장소에서 수정을 방치하는 겁니다. 그래서 판단 기준은 “수정을 허용할 것인가”가 아니라 수정 후에 무엇으로 검증하는가입니다. 검증 명령이 잘 갖춰져 있으면 수정은 빠르게 해도 됩니다. 안 갖춰져 있으면 ask로 남겨 둡니다.

deny는 “혹시 모르니까”라며 넉넉하게 깔아 둬도 손해 볼 게 없습니다. .env 읽기나 파괴적 명령은 allow로 올릴 날이 안 온다는 전제로 처음부터 막아 둡니다. 위험한 프롬프트 모음에서 다룬 “permissions 건너뛰고 최대한 빠르게” 류의 지시는, 이 경계를 일부러 부수는 행위입니다. deny에 넣어 두면 프롬프트 쪽에서 뭐라고 하든 본체가 멈춰 줍니다.

permission mode는 단계에 맞춰 전환한다

allow/ask/deny가 “무엇을” 멈출지의 설정이라면, permission mode는 “지금 얼마나 멈출지”의 기어 선택입니다. Shift+Tab으로 default → acceptEdits → plan을 전환할 수 있습니다. 공식 permission modes에 전체 모드가 정리돼 있지만, 운영에서 외워야 할 건 다음 대응표입니다.

모드확인 없이 동작하는 범위이럴 때
default읽기만처음 보는 저장소, 신중하게 가고 싶은 작업
plan읽기만(수정 없이 계획만 세움)코드베이스를 파악한 뒤 움직이고 싶다
acceptEdits읽기 + 작업 폴더 안 수정직접 리뷰하며 고친다
auto거의 전부(뒤에서 분류기가 안전 체크)긴 작업, 확인 피로를 줄이고 싶다
dontAsk미리 allow한 것만CI나 스크립트의 닫힌 환경
bypassPermissions전부(체크 없음)격리 컨테이너·VM 안에서만

제 사용 구분은 단순합니다. 새 작업의 입구는 plan. Claude에게 먼저 읽혀서 절차를 뽑게 하고, 방향이 맞는지 확인한 다음 움직입니다. 방향이 굳어지면 acceptEdits로 내려서 한 번에 수정시키고, 결과를 git diff로 한꺼번에 봅니다. 한 줄씩 승인하는 것보다 나중에 모아서 읽는 편이 집중해서 읽힙니다. 이건 “마지막에 반드시 본다”를 장치로 만드는 이야기로, Harness Engineering에서 쓴 “문지기를 기계에 둔다”는 사고방식과 그대로 이어집니다.

주의할 점 하나. bypassPermissions를 뺀 어떤 모드에서도 protected paths에 대한 쓰기는 자동 승인되지 않습니다. .git, .claude, .bashrc, .npmrc 같은, 망가지면 저장소나 설정 자체가 죽는 자리입니다. acceptEdits로 기분 좋게 수정하고 있어도 여기만큼은 확인이 들어옵니다. 이건 방해가 아니라 마지막 안전망이라고 생각하세요.

--dangerously-skip-permissions 없이 해결하기

“확인이 너무 많아서 귀찮다”를 해결하려고 많은 사람이 --dangerously-skip-permissions(= bypassPermissions 모드)에 손을 뻗습니다. 이름 그대로 모든 체크를 끄는 플래그입니다.

이걸 일상 대화에서 상시로 쓴다면, 더 이상 “감독 붙은 에이전트”가 아닙니다. 그저 아직 사고가 안 났을 뿐입니다. 공식 문서도 이 모드를 “격리된 컨테이너·VM 안에서만”이라고 못 박았고, rm -rf /rm -rf ~ 같은 최악의 경우를 빼면 아무런 프롬프트도 뜨지 않습니다. prompt injection에 대한 방어도 0입니다.

하지만 “귀찮다”는 감정 자체는 옳습니다. 그러니 없애야 할 건 확인의 개수지, 안전망이 아닙니다. 대안은 두 가지입니다.

하나는 auto mode. 이건 확인은 지우지만, 별도의 분류기 모델이 뒤에서 각 작업을 보면서 curl | bash, 프로덕션 deploy, main에 직접 push, force push 같은 위험한 작업은 차단합니다. 대화 중에 “push 하지 마”라고 말하면 그것도 일시적인 차단 신호로 작동합니다. 확인은 줄지만 위험한 작업은 멈춥니다. bypassPermissions와는 전혀 다른 물건입니다. 다만 auto mode는 research preview라서, 민감한 작업의 리뷰를 통째로 생략하는 도구가 아니라 “방향은 신뢰할 수 있는 작업”에서 쓰는 겁니다.

다른 하나가 sandbox. 다음 장에서 설명합니다.

확인을 줄이고 싶다면 먼저 acceptEditsauto, 그래도 부족하면 sandbox. bypassPermissions는 컨테이너 전용으로 딱 잘라 둡니다. 이 순서로 생각하면 굳이 안전망을 전부 떼어낼 이유는 거의 사라집니다.

sandbox는 “닿는 범위”를 OS로 묶는다

승인이 “이 작업을 해도 되는가”를 묻는 장치라면, sandbox는 Bash가 닿는 파일과 네트워크의 범위 자체를 OS 레벨에서 좁히는 장치입니다. 승인은 “실행 전 체크”, sandbox는 “실행 중의 벽”. 레이어가 다릅니다.

여기가 효과적인 건 승인의 약점을 메워 주기 때문입니다. 승인은 명령 문자열을 보고 판단하기 때문에, npm run build가 뒤에서 예상 밖의 짓을 해도 알아채지 못합니다. 하지만 sandbox라면 그 명령이 쓸 수 있는 건 기본적으로 작업 폴더 안뿐입니다. 이름대로 행동하지 않아도 OS가 물리적으로 멈춥니다.

/sandbox를 실행하면 설정 패널이 열리고 두 가지 모드를 고를 수 있습니다.

  • auto-allow: sandbox 안이라면 확인 없이 Bash를 실행한다(범위가 갇혀 있으니 안전). 범위 밖으로 나가는 작업만 일반 승인으로 돌아간다.
  • regular permissions: sandbox 안에서도 평소처럼 승인을 띄운다. 제어는 강하지만 확인이 많다.

즉 “확인은 줄이고 싶지만 아무거나 실행되는 건 무섭다”는 사람에게 딱 맞습니다. 범위로 지키니까 일일이 안 물어봐도 되는 거죠.

다만 중요한 제약이 있습니다. sandbox가 동작하는 건 macOS / Linux / WSL2뿐이고, native Windows에서는 동작하지 않습니다. Windows 사용자는 WSL2 안에서 Claude Code를 돌려야 합니다. WSL을 못 쓰거나 순수 Windows에서 쓴다면 sandbox에 기대지 말고 allow/ask/deny 분류를 더 빡빡하게 하세요. deploy·publish·secret 주변은 특히 ask 쪽으로 몰아 둡니다. 이게 Windows에서의 현실적인 타협점입니다.

sandbox 설정은 이런 모양입니다. 작업 폴더 바깥에 쓰기가 필요한 도구(예: kubectl~/.kube를 건드림)에만 명시적으로 구멍을 뚫습니다.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": false,
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"],
      "denyRead": ["~/.aws", "~/.ssh"]
    }
  }
}

failIfUnavailable: false는 “sandbox를 못 쓰는 환경이면 경고만 띄우고 일반 실행으로 내려간다”는 설정입니다. 반대로 조직에서 sandbox를 필수로 두려면 true로 해서 실행 자체를 막습니다. 그리고 의외로 중요한 게 denyRead. sandbox의 기본값은 거의 모든 파일을 읽을 수 있게 돼 있으니, ~/.aws~/.ssh 같은 비밀은 명시적으로 막아 두면 안심됩니다.

”매일의 운영”으로 떨어뜨리는 설정의 출발점

여기까지의 판단을 한 파일로 만들면, 일상 운영의 출발점은 이 정도면 충분합니다. 문법의 세세한 의미(Bash(npm run build)Bash(npm*)의 차이 등)는 권한 설정 레퍼런스에 넘깁니다.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "defaultMode": "plan",
    "allow": [
      "Read",
      "Grep",
      "Glob",
      "Bash(npm run build)",
      "Bash(npm run test)",
      "Bash(npm run lint)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npx wrangler pages deploy *)",
      "Bash(node scripts/outreach-send-mails.mjs --send)",
      "WebFetch(domain:api.gumroad.com)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(rm -rf *)",
      "Bash(git reset --hard *)",
      "Bash(curl * | sh)"
    ]
  },
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": false
  }
}

하는 일은 세 가지뿐입니다. 읽기와 검증은 빠르게 돌린다. 바깥에 영향을 주는 작업은 반드시 멈춘다. 명백히 위험한 건 처음부터 금지한다. defaultMode: "plan"을 넣은 건 새 세션을 “일단 읽고 계획”부터 시작하고 싶어서입니다. 그다음엔 작업하면서 Shift+Tab으로 acceptEdits로 올려 가면 됩니다.

수정(Edit / Write)을 allow에도 ask에도 안 적은 건 의도적입니다. mode 쪽(acceptEdits)에서 제어하고 싶으니까요. 규칙과 모드 양쪽에서 수정을 묶으면 어느 쪽이 작동하는지 알 수 없게 됩니다. 수정은 모드로, 외부 부작용은 규칙으로, 이렇게 역할을 나누면 머리가 정리됩니다.

팀에서는 “승인을 두는 자리”를 물리로 고정한다

여기까지는 개인 이야기였습니다. 팀이 되면 문제가 하나 더 늘어납니다. 사람마다 경계 긋기가 제각각이 되는 것. 신중한 사람도 있고, bypassPermissions로 돌리고 싶어 하는 사람도 있습니다. 의지와 양식에 기대면, 가장 느슨한 사람의 운영이 팀의 실질 기준선이 됩니다.

그래서 멈추고 싶은 자리는 사람의 판단에 맡기지 말고 물리로 고정합니다. 구체적인 예 세 가지.

1. 커밋 전에 secret 혼입을 막는다. PreToolUse hook으로 git add 전에 .env가 스테이징되지 않았는지 기계가 체크합니다. 사람이 “아, 이거 넣으면 안 됐는데” 하고 깨닫기 전에 커밋이 멈춥니다.

2. deploy 전에 build를 강제한다. “로컬에서 build 통과시킨 셈”을 믿지 않습니다. deploy 명령 앞에 hook으로 npm run build를 반드시 돌립니다.

3. 수정 후에 검증을 자동으로 돌린다. Edit / Write 뒤에 npm run test를 흘립니다. 얕은 수정이라도 검증이 돌아가니, 망가진 채로 진행되지 않습니다.

최소 구성은 이 정도입니다. hook은 많을수록 좋은 게 아니라, 멈추는 hook 하나·검증 hook 하나 정도가 운영이 잘 안 무너집니다.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git add*)",
        "hooks": [{
          "type": "command",
          "command": "git diff --cached --name-only | grep -E '^\\.env' && echo 'Blocked: .env staged' && exit 1 || exit 0"
        }]
      },
      {
        "matcher": "Bash(npx wrangler pages deploy*)",
        "hooks": [{
          "type": "command",
          "command": "npm run build"
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "npm run test || true"
        }]
      }
    ]
  }
}

Windows라면 grep 부분은 findstr나 작은 Node 스크립트로 바꾸면 동작합니다. 중요한 건 명령 자체보다 “commit 전에 멈추기 / deploy 전에 build / 수정 후에 검증”이라는 세 가지 형태입니다. 조직 레벨로 묶으려면 managed settings에서 bypassPermissionsdisable로 하고 sandbox를 필수로 두는 방법도 있습니다. 팀 규모가 되면 도입 상담 페이지에서 운영 규칙째 설계하는 게 결국 가장 빠릅니다.

자주 하는 실패 사례

세 가지 모두 저 또는 제 주변이 실제로 저지른 것들입니다.

전부 ask로 해 놓고 안심한다

첫날은 안전해 보입니다. 하지만 일주일 뒤에는 확인 문구를 읽지도 않고 OK를 누르기 시작합니다. 이건 deny가 약한 상태보다 더 위험합니다. “확인한 셈”이라는 착각이 남기 때문입니다. ask를 늘어놓기 전에 먼저 deny를 굳히세요.

--dangerously-skip-permissions가 입버릇이 된다

“이거 빠른데” 하고 한번 맛을 들이면 돌아오지 못합니다. 하지만 그건 감독을 떼어낸 것뿐입니다. 확인이 귀찮으면 auto mode나 sandbox의 auto-allow를 쓰세요. 안전망째 떼어낼 이유는 어디에도 없습니다.

build 성공을 release 성공으로 착각한다

이건 콘텐츠 운영에서도 개발에서도 자주 나옵니다. 로컬 build는 통과했는데, 공개 URL이 옛것이거나, 한 언어만 반영이 안 됐거나, CTA가 모바일에서 깨져 있습니다. 승인이나 sandbox로는 이 실패를 막을 수 없습니다. 필요한 건 공개 후의 확인입니다. 저는 이걸로 몇 번이나 “낸 셈”을 했습니다.

자주 묻는 질문

Q. auto mode와 sandbox의 auto-allow, 뭐가 다른가요? A. 지키는 방식이 다릅니다. auto mode는 분류기 모델이 “이 작업은 위험한가”를 판단해서 차단합니다. sandbox의 auto-allow는 작업의 내용이 아니라 “닿는 범위”를 OS로 묶어서 안전을 확보합니다. 판단으로 지키는 게 전자, 범위로 지키는 게 후자. 둘을 조합할 수도 있습니다.

Q. Windows에서 sandbox를 쓸 수 있나요? A. native Windows에서는 못 씁니다. WSL2 안에서 Claude Code를 돌리면 쓸 수 있습니다. 순수 Windows에서 쓸 경우엔 sandbox에 기대지 말고 deploy·publish·secret 주변을 ask로 몰고, deny를 빡빡하게 하세요.

Q. plan mode와 acceptEdits mode, 어떻게 나눠 쓰나요? A. plan은 “읽기만·수정 안 함”으로 코드베이스를 파악해 절차를 세우는 단계용. acceptEdits는 “작업 폴더 안 수정을 확인 없이 통과”로 방향이 굳어져 한 번에 고치는 단계용입니다. 저는 plan으로 시작해서 합의되면 acceptEdits로 내립니다.

Q. deny에 넣은 작업을 정말 딱 한 번만 실행하고 싶을 때는? A. deny는 Claude Code 본체가 강제하기 때문에 프롬프트로는 풀 수 없습니다(그게 deny의 가치입니다). 정말 필요하면 그 자리에서 settings에서 빼고 실행한 뒤, 끝나면 되돌립니다. “잠깐 뺐다”는 그 수고 자체가 위험한 작업의 브레이크가 됩니다.

Q. hook과 permission, 역할이 겹치지 않나요? A. 겹치지 않습니다. permission은 “이 작업을 실행해도 되는가”를 제어하고, hook은 “실행 전후에 무엇을 반드시 돌릴 것인가”를 제어합니다. secret 혼입을 막기·deploy 전에 build 하기 같은 결정론적 체크는 hook의 담당입니다.

실제로 해 본 결과

이 사고방식을 이 사이트의 daily automation에 그대로 다시 넣었습니다. 가장 크게 바뀐 건 AI의 출력 품질 그 자체보다 “어느 시점에 사람이 멈추는가”가 분명해진 것입니다.

예전엔 “뭔가 하나 진행하기”라는 애매한 운영이라, 기존 글을 조금 고치고 run이 끝나는 경우도 있었습니다. 지금은 plan으로 절차 → acceptEdits로 수정 → deploy 전에 hook으로 build → 공개 후에 전 언어를 모바일 확인이라는 흐름이 고정돼 있습니다. bypassPermissions 쓰기를 그만두고 acceptEdits + sandbox로 바꾼 뒤로, “어느새 바깥에 뭔가 하고 있었네” 하는 아찔함이 사라졌습니다.

똑똑한 AI에게 전부 맡기기보다, 되돌릴 수 없는 작업 직전에 한 박자 쉼표를 둔다. 돌아가는 것처럼 보여도, 매일 안심하고 돌릴 수 있는 건 이쪽이었습니다. 먼저 무료 치트시트를 옆에 두고, 자기만의 deny 리스트를 한 줄씩 채우는 데서 시작해 보세요.

#claude-code #permissions #approval #sandbox #security #workflow
무료

무료 PDF: Claude Code 치트시트

이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.

개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.

Masa

작성자 소개

Masa

Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.