권한 요청이 반복되면 명령어를 통째로 허용하고 싶어집니다. 하지만 git의 diff 읽기와 push, pnpm의 test와 install은 같은 프로그램 안에서도 결과와 위험이 다릅니다. 이 글은 Codex와 Claude Code의 공식 권한 모델을 이 저장소의 package.json과 배포 워크플로에 대입해, 자동 승인 범위를 어디까지 좁힐지 정리합니다.
명령어 이름만 보고 허용 여부를 결정하지 않으려면 다음 세 가지를 먼저 묻습니다.
- 영향이 현재 작업 디렉터리 안에 머무는가?
- Git이나 작업 사본으로 되돌릴 수 있는가?
- 외부 시스템이나 다른 사람에게 즉시 영향을 주는가?
세 답이 모두 안전한 쪽이면 자동화 후보입니다. 하나라도 불명확하면 확인을 남기거나 차단합니다.
샌드박스와 승인은 다른 안전장치다
Codex 공식 문서는 로컬 보안을 두 층으로 설명합니다. 샌드박스는 에이전트가 기술적으로 접근할 수 있는 파일과 네트워크 범위를 정하고, 승인 정책은 그 경계를 넘기 전에 사용자에게 물을 시점을 정합니다.
예를 들어 workspace-write 샌드박스에서는 현재 작업 공간을 읽고 수정할 수 있지만 기본적으로 네트워크는 꺼져 있습니다. 에이전트가 작업 공간 밖을 수정하거나 네트워크가 필요한 명령을 요청하면 승인 흐름으로 넘어갑니다. 승인을 묻지 않게 설정해도 샌드박스가 그대로라면 에이전트는 그 경계 안에서만 움직입니다.
Claude Code 권한 설정도 읽기, 셸 명령, 파일 수정에 서로 다른 기본 권한을 적용하고 allow, ask, deny 규칙을 제공합니다. 규칙은 deny, ask, allow 순서로 평가되므로 명시적인 차단 규칙이 허용 규칙보다 우선합니다.
| 구분 | 정하는 것 | 잘못 설정했을 때 생기는 문제 |
|---|---|---|
| 샌드박스 | 접근 가능한 파일과 네트워크 범위 | 한 번의 승인으로 예상보다 넓은 영역에 접근할 수 있음 |
| 승인 정책 | 어떤 행동을 사용자에게 물을지 | 반복 승인 또는 지나친 자동 실행 |
| 허용·차단 규칙 | 특정 명령이나 도구의 예외 | 너무 넓은 패턴이 위험한 하위 명령까지 포함함 |
승인 창을 줄이고 싶다면 먼저 샌드박스를 좁게 잡아야 합니다. 넓은 시스템 권한을 준 뒤 명령어 이름만 보고 막는 방식보다, 작업 공간과 네트워크를 먼저 제한한 뒤 그 안에서 자율성을 주는 편이 경계가 분명합니다.
한 프로그램도 결과에 따라 다르게 취급한다
git은 diff를 읽을 수도 있고 원격 저장소에 push할 수도 있습니다. pnpm은 프로젝트 검증을 실행할 수도 있지만, 패키지를 설치하면서 네트워크와 설치 스크립트를 사용할 수도 있습니다. 도구 전체를 한 줄로 허용하면 서로 다른 결과를 한 권한으로 묶게 됩니다.
작업을 결과와 복구 가능성으로 나누면 범위를 정하기 쉽습니다.
| 작업 | 기본 권장 | 이유 |
|---|---|---|
| 일반 파일 검색과 읽기 | 자동 허용 | 로컬 상태를 바꾸지 않음 |
git status, git diff, git log |
자동 허용 | 저장소 상태를 읽기만 함 |
| 작업 공간 안의 코드 수정 | 조건부 자동 허용 | Git으로 되돌릴 수 있지만 미커밋 변경 보호가 필요함 |
| 단위 테스트, 타입 검사, 린트 | 조건부 자동 허용 | 보통 로컬 검증이지만 프로젝트 스크립트에 부작용이 있을 수 있음 |
| 패키지 설치 | 매번 확인 | 네트워크, lockfile 변경, 설치 스크립트 실행이 함께 일어날 수 있음 |
git commit |
사용자가 요청한 경우만 | 로컬에서 복구 가능하지만 이력이라는 결과물을 만듦 |
git push, PR 병합 |
매번 확인 | 원격 상태와 다른 사람의 작업 흐름에 영향을 줌 |
| 비밀값 읽기 | 원칙적으로 차단 | 한 번 노출되면 Git으로 되돌릴 수 없음 |
| 배포, 데이터 변경 | 매번 확인 | 외부 사용자와 운영 데이터에 직접 영향을 줌 |
| 삭제와 이력 재작성 | 매번 확인 또는 차단 | 복구 비용이 크고 범위를 오판하기 쉬움 |
“조건부 자동 허용”은 저장소가 버전 관리 중이고, 에이전트가 작업 시작 전에 기존 변경을 구분할 수 있다는 뜻입니다. 사용자 변경과 에이전트 변경이 섞인 상태에서 자동 수정을 허용하면 되돌리는 과정에서 원래 작업까지 잃을 수 있습니다.
읽기와 로컬 검증은 비교적 넓게 허용할 수 있다
코드 검색, 파일 읽기, git diff와 같은 작업은 에이전트가 판단하기 위해 계속 반복합니다. 이 구간에 매번 승인을 요구하면 안전성이 크게 늘기보다 사용자가 승인 창을 습관적으로 누르게 될 가능성이 큽니다.
테스트와 린트도 대체로 자동화에 적합합니다. 다만 명령어 이름만 보고 안전하다고 단정하면 안 됩니다. 프로젝트의 test 스크립트가 Docker 컨테이너를 띄우거나, 외부 데이터베이스를 초기화하거나, 스냅샷 파일을 갱신할 수도 있습니다.
다음 조건을 만족할 때 로컬 검증을 자동 허용하기 좋습니다.
- 명령이 사용하는 환경 변수를 확인했습니다.
- 운영용 자격 증명이 로컬 셸에 들어 있지 않습니다.
- 테스트 데이터베이스와 운영 데이터베이스가 분리되어 있습니다.
- 스냅샷 갱신이나 코드 생성처럼 파일을 바꾸는 단계가 구분되어 있습니다.
- 실패해도 현재 작업 사본 밖에 영향을 주지 않습니다.
pnpm test라는 이름이 안전을 보장하는 것이 아닙니다. 그 명령이 실제로 무엇을 실행하는지 한 번 확인한 뒤 허용해야 합니다.
이 저장소에서 확인할 경계
2dayapp의 package.json에는 pnpm verify가 있고, 이 명령은 포맷 검사·lint·Astro/TypeScript 검사·테스트·정적 빌드를 차례로 실행합니다. 이름만 보면 검증 명령이지만 build 단계는 dist/ 산출물을 만듭니다. 자동 허용을 하더라도 아무 파일도 바꾸지 않는 git diff와 같은 등급으로 볼 수는 없습니다.
배포 흐름은 deploy.yml에 더 분명하게 나타납니다. 특히 submit-indexnow.mjs는 배포 뒤 외부 endpoint로 변경 URL을 보내고, indexnow.test.ts는 어떤 URL을 만들지 검사합니다. 테스트가 외부 서비스의 색인 결과까지 보장하는 것은 아니므로, 이 작업은 로컬 빌드와 같은 자동 승인 등급으로 올리면 안 됩니다.
verify → deploy → indexnow
verify는 로컬 품질 게이트에 가깝지만 deploy는 원격 Pages 상태를 바꾸고, indexnow는 외부 검색엔진에 URL을 보냅니다. 세 작업을 모두 “빌드”로 묶으면 외부 효과를 놓치게 됩니다.
현재 저장소에는 AGENTS.md나 CLAUDE.md가 없습니다. 따라서 아래 설정 예시는 2dayapp에 이미 적용된 정책이 아니라, 이 저장소의 파일과 워크플로를 읽고 만든 보수적인 예시입니다.
패키지 관리자는 하위 명령까지 좁혀야 한다
npm, pnpm, yarn, pip를 통째로 허용하면 승인 요청은 빠르게 줄어듭니다. 대신 설치, 게시, 전역 변경까지 같은 권한 범위에 들어올 수 있습니다.
패키지 설치에는 보통 세 가지 변화가 함께 따라옵니다.
- 레지스트리와 통신합니다.
- lockfile과 의존성 디렉터리를 바꿉니다.
- 패키지가 제공하는 설치 스크립트를 실행할 수 있습니다.
따라서 pnpm test, pnpm lint, pnpm build처럼 이미 검토한 프로젝트 명령은 좁게 허용하고, pnpm add, npm install, pip install은 요청마다 확인하는 편이 낫습니다. npm * 같은 넓은 패턴은 npm publish까지 포함할 수 있으므로 승인 피로를 줄이는 대가가 너무 큽니다.
의존성 설치를 자주 반복해야 한다면 권한을 넓히기보다 환경을 분리할 수 있습니다. 개발 컨테이너나 일회용 작업 환경에서 설치 단계를 수행하면 호스트에 미치는 영향과 자격 증명 노출을 줄일 수 있습니다.
Git은 읽기, 로컬 이력, 원격 변경으로 나눈다
Git 전체를 하나의 허용 규칙으로 묶으면 읽기와 원격 변경이 같은 권한을 갖게 됩니다.
자동화하기 좋은 작업
git status
git diff
git log
git show
이 명령들은 저장소를 이해하고 변경을 검토하는 데 필요하며 기본적으로 상태를 읽습니다.
사용자가 요청했을 때만 실행할 작업
git add <구체적인 파일>
git commit
로컬 커밋은 되돌릴 수 있지만, 사용자가 의도하지 않은 파일이 포함되면 검토 단위가 망가집니다. 특히 git add .는 비밀 파일이나 관련 없는 변경을 함께 스테이징할 수 있습니다. 커밋을 맡기더라도 파일 목록과 diff를 먼저 확인하는 절차가 필요합니다.
자동 승인하지 않을 작업
git push
git reset --hard
git clean -fd
git rebase
push는 원격 상태를 바꿉니다. reset --hard와 clean은 로컬 변경을 잃게 할 수 있고, rebase는 공유 이력과 충돌할 수 있습니다. 명령 자체가 항상 나쁜 것은 아니지만 자동 승인 기본값으로 두기에는 복구 조건이 복잡합니다.
네트워크 권한은 목적지까지 좁힌다
네트워크 접근은 파일 쓰기와 다른 위험을 가집니다. 에이전트가 로컬 파일을 수정하면 diff로 확인할 수 있지만, 외부로 전송된 데이터는 같은 방식으로 회수할 수 없습니다.
Codex의 네트워크 정책은 workspace-write에서 명령의 네트워크 접근을 기본적으로 끄고, 네트워크를 켠 경우에도 도메인 정책으로 목적지를 제한할 수 있게 합니다. 네트워크 기능을 켜는 설정과 허용할 목적지를 정하는 설정은 별개입니다.
실무에서는 다음처럼 나누는 편이 안전합니다.
- 공식 패키지 레지스트리와 문서 사이트: 필요한 작업에 한해 허용
- 프로젝트 API의 개발 환경: 정확한 호스트만 허용
localhost: 필요한 포트와 프로세스를 확인한 뒤 허용- 사설망 전체와 임의의 외부 호스트: 기본 차단
- 운영 API와 클라우드 관리 엔드포인트: 매번 확인
도메인 전체를 *로 허용하면 네트워크 승인을 없앨 수는 있지만, 프롬프트 인젝션이나 잘못된 명령이 데이터를 외부로 보낼 수 있는 범위도 함께 넓어집니다.
비밀값은 읽기 권한부터 분리한다
.env, SSH 키, 클라우드 자격 증명, 패키지 레지스트리 토큰은 “수정하지 않으니 안전한 파일”이 아닙니다. 읽기만 해도 위험이 생깁니다.
에이전트가 테스트를 실행하려면 비밀값이 필요하다고 생각하기 쉽지만, 실제로 필요한 것은 대개 운영 자격 증명이 아니라 제한된 개발용 값입니다.
- 운영 토큰을 로컬 셸에서 제거합니다.
- 테스트 전용 계정과 최소 권한 키를 사용합니다.
- 비밀 파일 경로는 명시적으로 읽기 차단합니다.
- 로그와 오류 메시지에 토큰이 출력되지 않는지 확인합니다.
- 클라우드 작업에는 작업 단계에 필요한 비밀만 짧게 주입합니다.
비밀값을 읽은 뒤 “출력하지 마”라고 지시하는 것은 접근 통제가 아닙니다. 읽지 못하게 만드는 것이 먼저입니다.
Claude Code는 allow, ask, deny를 함께 쓴다
Claude Code의 프로젝트 설정에서는 이미 검토한 명령을 허용하고, 외부 부작용이 있는 작업은 묻거나 차단할 수 있습니다. 다음은 권한 범위를 보수적으로 잡은 예시입니다.
{
"permissions": {
"allow": [
"Bash(pnpm test)",
"Bash(pnpm lint)",
"Bash(pnpm build)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git log)"
],
"ask": ["Bash(pnpm add *)", "Bash(npm install *)", "Bash(git commit *)"],
"deny": ["Bash(git push *)", "Read(./.env*)", "Read(~/.ssh/**)"]
}
}
실제 패턴은 프로젝트 명령에 맞게 좁혀야 합니다. 인자가 필요 없다면 예시처럼 정확한 명령부터 허용하고, 반복해서 필요한 인자가 확인됐을 때만 와일드카드를 추가합니다. Claude Code 공식 문서가 설명하듯 와일드카드는 공백을 포함한 여러 인자와 일치할 수 있으므로 /permissions에서 출처와 적용 범위를 확인해야 합니다.
bypassPermissions 또는 --dangerously-skip-permissions는 승인 창만 줄이는 설정이 아닙니다. 보호 경로 쓰기를 포함한 권한 확인을 건너뜁니다. Claude Code 권한 모드 문서는 이 모드를 컨테이너나 VM처럼 호스트와 격리된 환경에서만 사용하라고 안내합니다.
Codex는 좁은 샌드박스 안에서 자율성을 준다
Codex의 보수적인 로컬 설정은 작업 공간 쓰기, 요청 시 승인, 명령 네트워크 차단으로 잡을 수 있습니다. 각 설정이 만드는 경계는 샌드박스 문서에서 확인할 수 있습니다.
sandbox_mode = "workspace-write"
approval_policy = "on-request"
[sandbox_workspace_write]
network_access = false
반복해서 사용하는 명령은 prefix rule로 세분화할 수 있습니다. 예를 들어 git status와 git diff는 허용하고 git push는 계속 묻게 만들 수 있습니다. 규칙이 여러 개 일치하면 더 제한적인 결정이 우선합니다.
전체 승인 요청을 끄는 approval_policy = "never"도 샌드박스와 함께 사용할 수 있습니다. 이 경우 Codex는 승인 없이 샌드박스 안에서 할 수 있는 만큼만 수행하고, 경계를 넘는 작업은 진행하지 못합니다. 반면 danger-full-access나 --dangerously-bypass-approvals-and-sandbox는 승인과 샌드박스를 함께 우회하므로 전혀 다른 위험 수준입니다.
전체 권한 우회가 가능한 조건
전체 우회가 필요한 자동화도 있습니다. 장시간 벤치마크, 대규모 코드 변환, 반복적인 테스트 수정처럼 중간 승인이 작업을 사실상 멈추게 하는 경우입니다.
그래도 개인 노트북에서 바로 전체 권한을 주는 것이 기본값이 되어서는 안 됩니다. 최소한 다음 조건을 모두 만족하는 환경이 필요합니다.
- 작업이 끝나면 폐기할 수 있는 컨테이너나 VM입니다.
- 호스트 홈 디렉터리와 다른 저장소가 마운트되지 않았습니다.
- 운영용 SSH 키, 클라우드 자격 증명과 브라우저 세션이 없습니다.
- 네트워크가 꺼져 있거나 필요한 목적지만 허용되어 있습니다.
- 저장소는 별도 브랜치나 worktree에 있고 원격 push 권한이 없습니다.
- 결과는 diff와 테스트를 통해 사람이 검토합니다.
격리 환경이 없다면 전체 우회보다 dontAsk처럼 미리 허용한 작업만 비대화형으로 실행하고 나머지는 거부하는 방식이 낫습니다. 자동화가 멈추는 것이 호스트나 운영 환경을 잘못 바꾸는 것보다 복구 비용이 낮습니다.
권한 요청이 뜨면 명령어 이름만 보지 말고 범위, 비밀값, 외부 효과와 복구 방법을 확인합니다. 같은 승인이 반복되더라도 곧바로 “항상 허용”을 누르기보다 git 전체가 아닌 git diff, 패키지 관리자 전체가 아닌 pnpm test, 네트워크 전체가 아닌 필요한 도메인으로 규칙을 좁힙니다.
이 비교에서 남는 기본값
자동 승인 범위는 명령어가 익숙한지보다 영향 범위와 복구 가능성으로 정해야 합니다.
- 작업 공간 안의 검색·읽기·diff는 좁은 경로에서 자동화합니다.
- 테스트와 빌드는 실제 스크립트가 만드는 파일과 외부 효과를 확인한 뒤 허용합니다.
- 설치·커밋·원격 변경·배포는 서로 다른 확인 단계로 둡니다.
- 비밀값 읽기와 임의의 네트워크 목적지는 기본 차단합니다.
승인 요청이 반복돼도 git 전체, pnpm 전체, 네트워크 전체를 한꺼번에 허용할 이유는 없습니다. 정확한 명령 하나를 좁게 허용하고, 그 명령이 만드는 결과를 다시 확인하는 편이 이 글의 보수적인 기본값입니다. 실제 적용 전에는 사용하는 버전의 Codex 권한 문서와 Claude Code 권한 문서를 확인해야 합니다.