시리즈: 클로드 코드 Team 기능 완전 가이드 (총 9편) | 7편
가드레일 패키지 - 권한, 승인, Hooks로 팀을 안전하게
Team 기능이 강력한 만큼, 통제 없이 쓰면 위험도 커져요. 이 글에서는 권한 상속 구조와 리더가 단일 실패 지점(SPOF)이 되는 이유부터 Plan approval, Hooks, CI/브랜치 보호까지 Team을 안전하게 운영하는 가드레일 전략을 정리해 드릴게요.
Summary
- 리더의 권한 설정이 팀원에게 그대로 상속되기 때문에 리더가 단일 실패 지점(SPOF)이에요
- Plan approval로 위험한 작업은 계획 제출 → 승인 → 실행 흐름을 강제할 수 있어요
- Hooks는 "테스트를 실행했느냐"가 아니라 "통과했느냐"를 완료 조건으로 만들어요
- 로컬 훅 + CI required checks + 보호 브랜치를 조합하면 다층 안전망이 완성돼요
이 글의 대상
- Team 기능을 도입했는데 보안/안정성이 걱정되는 분
- 팀원 에이전트가 위험한 작업을 실행하지 못하게 막고 싶은 분
- CI/CD와 연동해서 자동화된 안전 장치를 구축하고 싶은 분
목차
- 권한 상속 구조와 단일 실패 지점
- 최소 권한 정책 설계하기
- Plan approval - 위험 작업에 승인 단계 넣기
- Hooks - 완료 조건을 코드로 강제하기
- CI/브랜치 보호와 결합하기
1. 권한 상속 구조와 단일 실패 지점
리더의 permission 설정이 팀원에게 그대로 상속되기 때문에, 리더 설정 하나가 전체 팀의 보안 수준을 결정해요.
이게 Team 기능에서 가장 먼저 이해해야 할 보안 구조예요. 리더가 특정 디렉토리 쓰기를 허용하면, 모든 팀원도 그 디렉토리에 쓸 수 있어요. 반대로 리더가 제한하면 팀원도 제한돼요.
여기서 진짜 위험한 건 --dangerously-skip-permissions 플래그예요. 이름부터 "위험하게 권한을 건너뛰겠다"잖아요. 리더가 이 플래그로 실행하면 팀원도 동일하게 권한 검사 없이 작동해요.
| 리더 설정 | 팀원 상태 | 위험도 |
|---|---|---|
| allowlist 기반 permission | 동일한 allowlist 적용 | 낮음 |
| 느슨한 permission | 팀원도 느슨하게 동작 | 중간 |
--dangerously-skip-permissions |
팀원도 권한 검사 없음 | 매우 높음 |
그래서 리더가 단일 실패 지점(SPOF)이 되는 거예요. 리더 한 명의 설정 실수가 팀원 전체에 전파되거든요.
2. 최소 권한 정책 설계하기
프로덕션 환경에서는 반드시 allowlist 중심으로 권한을 설계하고, --dangerously-skip-permissions는 금지해야 해요.
최소 권한 원칙이라는 게 있어요. "필요한 것만 허용하고, 나머지는 전부 차단한다"는 원칙이에요. Team 기능에서도 이걸 그대로 적용하면 돼요.
실질적인 설계 가이드를 정리하면 이래요:
| 항목 | 권장 설정 | 이유 |
|---|---|---|
| 파일 쓰기 | 프로젝트 디렉토리만 허용 | 시스템 파일 변경 방지 |
| 명령 실행 | 테스트/빌드 명령만 허용 | 임의 스크립트 실행 차단 |
| 네트워크 | 필요한 엔드포인트만 허용 | 외부 유출 방지 |
--dangerously-skip-permissions |
프로덕션 금지 | 전체 보안 무력화 방지 |
/permissions 명령을 활용해서 허용 목록을 세밀하게 관리하는 게 핵심이에요. "이것만 할 수 있어"라고 정하는 게 "이것만 못 해"보다 훨씬 안전하거든요.
3. Plan approval - 위험 작업에 승인 단계 넣기
DB 마이그레이션, 인증 로직 변경, 배포 스크립트 같은 고위험 작업에는 "계획 → 승인 → 실행" 흐름을 강제할 수 있어요.
Plan approval은 에이전트가 바로 실행하지 않고, 먼저 계획서를 제출하도록 만드는 기능이에요. 사람이 계획을 검토하고 승인해야만 실행이 진행되거든요.
승인이 필요한 대표적인 작업 유형은 이래요:
- DB 마이그레이션 — 스키마 변경은 되돌리기 어려우니까요
- 인증/권한 로직 수정 — 보안 허점이 생길 수 있어요
- 배포 스크립트 실행 — 프로덕션에 직접 영향을 주는 작업이에요
- 광범위 리팩터링 — 여러 모듈에 걸친 대규모 변경이에요
계획서에는 뭘 포함해야 할까요? 권장 템플릿이 있어요:
[Plan 템플릿 권장 항목]
1. 목표와 성공 기준 — 무엇을 달성하려는지, 어떻게 확인하는지
2. 변경 파일 목록 — 어떤 파일이 바뀌는지 전체 목록
3. 롤백 전략 — 문제 생기면 어떻게 되돌리는지
4. 리스크와 완화책 — 예상 위험과 대응 방안이 템플릿을 따르면 "승인하는 사람"이 빠르게 판단할 수 있어요. "뭘 하려는 건지, 위험한 건 뭔지, 망하면 어떻게 복구하는지"가 한눈에 보이거든요.
4. Hooks - 완료 조건을 코드로 강제하기
Hooks는 "테스트를 실행했느냐"가 아니라 "통과했느냐"를 완료 조건으로 만드는 장치예요.
이게 미묘하지만 정말 중요한 차이예요. 에이전트에게 "테스트 돌려"라고 시키면 테스트를 돌리긴 해요. 근데 실패해도 "돌렸으니 됐지" 하고 넘어갈 수 있거든요. Hooks는 이걸 방지해요.
TaskCompleted 같은 이벤트에 훅을 연결하면, 에이전트가 작업 완료를 선언할 때 자동으로 테스트/린트/보안 스캔이 실행돼요. 그리고 exit code 2를 반환하면 완료 자체가 차단돼요.
Hooks가 할 수 있는 대표적인 역할을 정리하면 이래요:
| 훅 역할 | 설명 | 트리거 이벤트 |
|---|---|---|
| 테스트 통과 강제 | 테스트 실패 시 완료 차단 | TaskCompleted |
| 린트 검사 | 코드 스타일 위반 감지 | TaskCompleted |
| 보안 스캔 | 취약점 탐지 시 차단 | TaskCompleted |
| 금지 경로 변경 감지 | 건드리면 안 되는 파일 변경 시 경고 | TaskCompleted |
| 감사 로그 전송 | 누가 뭘 했는지 기록 | TaskCompleted |
핵심은 이거예요: 훅이 exit code 0을 반환하면 "통과", exit code 2를 반환하면 "차단"이에요. 에이전트가 아무리 완료하고 싶어도, 훅이 허락하지 않으면 완료할 수 없어요.
# 예시: TaskCompleted 훅에서 테스트 실행
# exit code 0 → 완료 허용
# exit code 2 → 완료 차단, 에이전트에게 수정 요구
npm test
if [ $? -ne 0 ]; then
exit 2 # 테스트 실패 시 완료 차단
fi
5. CI/브랜치 보호와 결합하기
로컬 훅은 빠른 피드백, CI required checks는 병합 차단, 보호 브랜치는 최종 방어선이에요. 이 세 겹을 조합하면 돼요.
하나만 쓰면 허점이 있어요. 로컬 훅은 우회될 수 있고, CI만 쓰면 피드백이 느려요. 그래서 세 겹을 쌓는 거예요.
| 레이어 | 역할 | 속도 | 우회 가능성 |
|---|---|---|---|
| 로컬 Hooks | 작업 중 즉시 피드백 | 빠름 (초 단위) | 있음 (설정 변경 시) |
| CI required checks | PR 병합 전 자동 검증 | 중간 (분 단위) | 낮음 (관리자만 우회) |
| 보호 브랜치 | main/production 직접 푸시 차단 | - | 매우 낮음 |
이 조합이 만들어내는 흐름은 이래요:
- 에이전트가 작업 완료를 선언하면 로컬 훅이 테스트/린트를 즉시 돌림
- 훅 통과 후 PR을 올리면 CI required checks가 전체 테스트 스위트를 돌림
- CI 통과해도 보호 브랜치 설정에 의해 리뷰 승인 없이는 병합 불가
이렇게 하면 에이전트가 만든 코드가 프로덕션에 도달하기까지 세 번의 관문을 거치는 거예요. 각 관문이 다른 종류의 문제를 잡아내기 때문에, 전체적으로 훨씬 안전해져요.
정적 분석 게이트도 여기에 추가하면 좋아요. ESLint, Pylint, SonarQube 같은 정적 분석 도구를 CI 파이프라인에 넣으면, 코드 품질까지 자동으로 관리할 수 있거든요.
핵심 정리
1. 리더의 권한이 팀원에게 그대로 상속 → 리더가 단일 실패 지점(SPOF)
2. --dangerously-skip-permissions는 프로덕션에서 절대 금지, allowlist 중심 설계
3. Plan approval로 고위험 작업에 계획→승인→실행 흐름 강제
4. Hooks의 exit code 2로 테스트 미통과 시 완료 자체를 차단
5. 로컬 훅 + CI checks + 보호 브랜치 = 세 겹 안전망FAQ
Q. --dangerously-skip-permissions 없이 개발이 불편하지 않나요?
A. 처음에는 좀 번거로울 수 있어요. 하지만 /permissions에서 allowlist를 잘 설계해 두면 일상 작업에서는 거의 걸리지 않아요. "필요한 건 다 열어두되, 위험한 건 막는다"가 핵심이에요. 한 번 세팅하면 오히려 마음 편해져요.
Q. Plan approval은 모든 작업에 적용해야 하나요?
A. 아니에요. 모든 작업에 승인을 넣으면 속도만 느려져요. DB 마이그레이션, 인증 로직 수정, 배포 스크립트, 대규모 리팩터링처럼 되돌리기 어려운 작업에만 적용하는 게 좋아요. 일반적인 코드 수정이나 테스트 작성에는 필요 없어요.
Q. Hooks의 exit code 2와 일반 에러(exit code 1)는 뭐가 다른가요?
A. exit code 1은 훅 자체가 실패한 거예요(스크립트 오류 등). exit code 2는 "의도적으로 차단한다"는 뜻이에요. 즉, 테스트가 실패했으니 완료를 허용하지 않겠다는 명시적 신호인 거예요. 에이전트는 exit code 2를 받으면 문제를 수정하고 다시 시도해요.
Q. 팀원이 훅을 우회할 수 있나요?
A. 팀원은 리더의 설정을 상속받기 때문에, 리더가 훅을 제대로 설정해 두면 팀원이 임의로 우회하기 어려워요. 다만 이건 로컬 훅의 한계이기도 해서, CI required checks와 보호 브랜치를 함께 쓰는 게 중요한 거예요. 세 겹을 쌓아야 안전해요.
Q. 보호 브랜치 설정은 어디서 하나요?
A. GitHub이라면 Settings → Branches → Branch protection rules에서 설정할 수 있어요. "Require status checks to pass before merging"과 "Require pull request reviews"를 켜면 돼요. GitLab이나 Bitbucket도 비슷한 기능이 있어요.
Q. Hooks로 감사 로그를 남기려면 어떻게 하나요?
A. TaskCompleted 훅에서 작업 내역을 파일에 기록하거나, 외부 로깅 서비스(Slack webhook, 로그 수집 서버 등)로 전송하는 스크립트를 연결하면 돼요. 누가 어떤 작업을 완료했는지, 어떤 파일을 변경했는지를 자동으로 추적할 수 있어요.
Q. 기존 CI/CD 파이프라인이 있는데 Hooks를 추가로 써야 하나요?
A. CI/CD가 이미 잘 구축되어 있다면 Hooks는 빠른 피드백 레이어로 추가하는 거예요. CI는 PR을 올린 뒤에 돌아가니까 피드백이 느려요. 로컬 훅은 에이전트가 작업을 끝내는 그 순간에 바로 검증하니까, 문제를 더 일찍 잡을 수 있어요. 역할이 겹치는 게 아니라 보완하는 거예요.
참고 자료 (References)
데이터 출처
| 출처 | 설명 | 링크 |
|---|---|---|
| Agent Teams 공식 문서 (KO) | 한국어 공식 가이드 | Agent Teams KO |
| Agent Teams 공식 문서 (EN) | 영문 공식 가이드 | Agent Teams EN |
| Hooks Guide | 훅 설정 및 활용 가이드 | Hooks Guide |
| Best Practices | Claude Code 운영 모범 사례 | Best Practices |
| GitHub Protected Branches | 브랜치 보호 규칙 설정 | GitHub Docs |
핵심 인용
"Hooks는 테스트를 실행했는가가 아니라, 통과했는가를 완료 조건으로 만든다"
— Claude Code Best Practices
다음 편 예고
[8편] 비용 관리와 실패 대응 전략
- 토큰 비용 구조: 팀원 수와 실행 시간이 비용에 미치는 영향
- 예산 제한:
--max-budget-usd로 비용 폭주 방지하기 - 실패 모드 복구: stuck 태스크 분류, 고아 세션 정리, 체크포인트 설계
