hooks 하나 붙이면 일은 확실히 편해진다.
그런데 편해진다는 건 보통 자동 실행이 늘어난다는 뜻이고, 자동 실행이 늘어난다는 건 결국 권한이 자주 쓰인다는 뜻이다.
권한이 자주 쓰이면, 시크릿이 많이 지나가고, 로그가 많이 남고, 실수도 더 빨리 커진다.
그래서 hooks는 “자동화 도구”가 아니라 “보안 경계가 있는 자동화 도구”로 봐야 한다.
핵심만 먼저 잡으면, Claude Code hooks는 편의성보다 먼저 어떤 정보가 어느 권한으로 어디까지 흘러갈 수 있는지를 정해두지 않으면 언젠가 사고 난다.
이 글이 필요한 사람
- hooks로 lint, test, formatting, notify를 붙이기 시작한 사람
- 프로젝트별로 다른 secret을 쓰는데도 설정을 한 군데서 우겨 넣는 사람
- 팀에서 “일단 자동화부터”라는 말이 너무 빨리 나오는 사람
- log file과 env file이 어디에 남는지 신경 안 쓰고 있는 사람
- 세션마다 다른 권한을 쓰는 구조를 아직 정리하지 못한 사람
지금 결론
자동 실행은 편하지만, 편한 만큼 위험도 늘어난다.
그래서 hooks 보안의 순서는 늘 같다.
- 입력값을 줄인다.
- 권한을 최소화한다.
- secret을 실행 컨텍스트에서 분리한다.
- 실패 로그는 남기되, 민감정보는 지운다.
- 과한 자동화는 애초에 안 붙인다.
이 순서를 뒤집으면 나중에 “왜 잘 돌아가던 게 갑자기 위험하지”가 된다.
먼저 봐야 할 경계
| 경계 | 왜 중요하나 | 흔한 실수 | 안전한 기본값 |
|---|---|---|---|
| secret | hook이 읽을 수 있으면 유출 경로도 생김 | .env를 repo 안에 둠 |
세션별 최소 export만 사용 |
| 권한 | hook은 사람이 직접 실행하는 것보다 자주 돈다 | write 권한을 기본으로 둠 | read-only부터 시작 |
| 경로 | hook이 어디서 도는지 항상 같지 않음 | pwd를 진실로 착각 |
$CLAUDE_PROJECT_DIR 기준 |
| 로그 | 디버깅에 유용하지만 민감정보도 남음 | 전체 env dump | 필요한 키만 마스킹 |
| 네트워크 | 외부 요청이 붙으면 유출면이 커짐 | 아무 API나 허용 | allowlist만 허용 |
왜 위험이 빨리 커지나
hooks는 한 번 설정하면 사람이 매번 확인하지 않는다.
즉, 처음에는 아주 작아 보였던 권한이 나중엔 자동으로 반복된다.
그게 무서운 이유는 단순하다.
- 한 번의 실수로 끝나지 않는다
- 한 번의 과한 권한이 수십 번 재사용된다
- 사람이 빠르게 고치기 어려운 곳에서 자동으로 반복된다
이건 편의성의 반대편에 있는 리스크다.
실전 체크리스트
1. secret은 hook 내부에서 직접 읽지 않는다
가능하면 필요한 최소 값만 환경으로 넘긴다.
예를 들면 이런 식이다.
export REVIEW_API_KEY="..."
export NOTIFY_TOKEN="..."
그런데 여기서도 핵심은 “많이”가 아니라 “최소”다.
hook이 필요한 키보다 더 많은 키를 보면, 나중에 누가 어디까지 쓸 수 있는지 흐려진다.
2. read-only hook과 write hook을 나눈다
검사용 hook과 수정용 hook을 같은 그룹으로 묶지 않는 게 좋다.
예를 들면:
- lint, verify, dry-run -> read-only
- file modify, auto-fix, deploy prep -> write
같은 자동화라도 위험도는 다르다.
3. 세션과 프로젝트를 같은 것으로 보지 않는다
pwd는 현재 위치고, $CLAUDE_PROJECT_DIR는 프로젝트 기준이다.
이걸 섞어 쓰면 경로 꼬임이 생기고, 경로 꼬임은 보통 로그 꼬임으로 이어진다.
4. 로그는 남기되 값은 마스킹한다
운영에서 로그가 없으면 디버깅이 안 된다.
하지만 시크릿이 로그에 그대로 남으면 디버깅보다 사고가 먼저 온다.
좋은 로그는 이런 느낌이다.
- 실행된 명령
- 현재 폴더
- 사용한 hook 이름
- 결과 코드
나쁜 로그는 이런 느낌이다.
- 전체 env
- 토큰 원문
- secret 값 그대로
- 파일 전체 덤프
5. 네트워크는 기본 차단, 예외만 허용한다
hook이 외부로 나가는 건 생각보다 위험하다.
왜냐면 외부 전송은 “내 컴퓨터에서 끝나는 작업”이 아니기 때문이다.
기본값은 차단이 낫고, 꼭 필요할 때만 allowlist로 여는 편이 덜 피곤하다.
실패 TOP
1. .env를 repo에 같이 넣는 실수
처음엔 편하다.
나중엔 보안팀이 제일 싫어하는 형태가 된다.
2. write 권한을 너무 빨리 붙이는 실수
수정 자동화는 좋지만, 검증 없이 자동 수정만 붙이면 사고 확률이 오른다.
3. 실패를 조용히 넘기는 실수
hook 실패를 숨기면 “자동화가 잘 돈다”고 착각한다.
사실은 그냥 조용히 망하고 있는 걸 수도 있다.
4. team-wide hook에 개인 secret을 얹는 실수
공용 설정과 개인 비밀정보는 분리하는 게 맞다.
5. 네트워크 호출을 아무 검증 없이 여는 실수
외부 API 호출은 편하지만, 그만큼 책임도 커진다.
6. 권한 경계보다 편의성을 먼저 보는 실수
자동화가 편해질수록 경계 설계는 더 중요하다.
7. 어디까지 자동인지 문서가 없는 실수
문서가 없으면 사람마다 다른 자동화를 상상한다.
그게 가장 운영하기 어렵다.
언제 과한가
hooks가 과해지는 순간은 보통 세 가지다.
- 검증보다 수정이 많아질 때
- 사람이 최종 승인하는 단계가 사라질 때
- 실패해도 누가 봐야 하는지 안 정해졌을 때
이 중 하나라도 걸리면, 자동화는 이미 편의 도구가 아니라 운영 리스크가 된다.
이럴 땐 안 써도 된다
- 단발성 수동 작업
- 팀 공용 저장소에서 아직 규칙이 정리되지 않은 상태
- secret 분리가 안 된 상태
- 외부 네트워크를 막아야 하는 프로젝트
- 로그/감사 추적이 아직 없는 프로젝트
자동화는 항상 정답이 아니다.
안 붙이는 게 더 안전한 시기도 있다.
FAQ
Q1. hooks를 다 막아버리는 게 더 안전하지 않나?
완전 차단은 안전해 보이지만 운영 효율을 많이 깎는다.
그래서 read-only부터 시작하고, 필요한 것만 점진적으로 여는 편이 낫다.
Q2. secret은 어디에 두는 게 좋나?
최소 노출 원칙으로 세션 단위 환경 변수나 별도 안전 저장소를 쓰는 게 낫다.
repo 안에 plain text로 두는 건 피해야 한다.
Q3. 로그를 얼마나 남겨야 하나?
재현에 필요한 만큼만 남기고, 비밀값은 마스킹한다.
Q4. hooks가 잦아질수록 무엇을 먼저 점검해야 하나?
권한, 경로, 로그, 네트워크 순서다.
Q5. 팀에서 제일 먼저 합의할 건 뭐냐?
어떤 hook이 read-only인지, 어떤 hook이 write인지부터 정해야 한다.
다음에 읽을 글
- Claude Code MCP vs script 2026 — 내부 도구 연결할 때 언제 커스텀 툴이 과하고 언제 셸이면 충분할까
- AI 코딩 에이전트 오케스트레이터가 필요한 순간 2026 — Claude Code·Codex·Copilot을 한 데 묶기 전 체크할 5가지
- Claude에게 아키텍처 그림 맡길 수 있을까 2026 — mermaid·draw.io·diagram workflow가 진짜 실무에 먹히는 조건