Codex 훅의 이벤트·신뢰·차단 한계
도구 실행 전에 정책을 확인하거나 완료 뒤 기록을 남기려면 훅을 검토합니다. 지침을 읽고 따르기를 기대하는 것과 이벤트에 연결된 handler가 실행되는 것은 다릅니다. 다만 훅도 모든 실행 경로를 감싸는 완전한 접근 통제는 아닙니다.
공식 문서를 참고한 비공식 한국어 가이드입니다. 훅 등록·셸 스크립트·MCP 호출은 실행 미검증입니다. 새 훅은 코드 실행을 추가하므로 정의와 실제 handler를 모두 읽고 신뢰해야 합니다.
정의와 누적 로딩
공식 문서는 활성 config layer 옆의 hooks.json, config.toml의 [hooks], 플러그인 훅을 설명합니다. 여러 층의 훅은 누적되며 상위 layer가 하위 훅을 대체하는 방식이 아닙니다. 중복 실행이나 예상 밖의 전역 훅이 있는지 확인합니다.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "/absolute/policy-script" }]
}]
}
}
구조만 보여 주는 합성 예시이며 해당 스크립트는 제공하지 않습니다. command 문자열은 실제 실행되므로 검토 없이 붙여 넣지 않습니다. 작업 디렉터리나 환경변수에 의존하는 상대 경로보다 실행 대상의 정체를 먼저 명확히 합니다.
실행 전과 실행 후
PreToolUse에서 공식 응답의 hookSpecificOutput.permissionDecision = "deny"를 사용하면 대상 호출을 거부할 수 있습니다. PostToolUse는 이미 실행한 도구 뒤에 오므로 앞서 발생한 파일 수정·외부 전송을 되돌리지 못합니다.
Stop의 decision: "block"은 프로세스 강제 종료가 아니라 추가 실행을 요청하는 의미입니다. 완료 검증이 실패하면 무한 반복되지 않도록 실패 이유와 종료 조건을 설계해야 합니다. 이벤트 이름만 보고 차단 시점과 효과를 추측하지 않습니다.
신뢰 승인과 비동기
비관리 훅은 정의 hash별로 신뢰 승인을 요구하며 변경되면 승인 전까지 건너뛰는 조건이 있습니다. CLI /hooks, 앱 Settings > Hooks에서 실제 로드/신뢰 상태를 확인합니다. 플러그인의 스크립트 변경도 재검토 대상입니다.
현재 실행 handler는 command, mcp_tool이며 prompt, agent는 파싱되더라도 건너뛰는 차이가 있습니다. async: true command 훅은 차단·승인·입력 변경에 사용할 수 없습니다. features.hooks = false와 deprecated alias의 차이도 해당 버전 문서를 확인합니다.
실패가 항상 차단은 아닙니다
MCP 훅은 기존 연결을 사용하며 연결 오류·timeout·잘못된 응답이 언제나 차단으로 이어지는 것은 아닙니다. hosted tool 등 미포함 경로가 있고, Cloud orchestration은 지원되는 enterprise Global MCP hooks를 사용하며 로컬 command/plugin hooks를 그대로 실행하지 않습니다.
따라서 보안 필수 조건을 훅 하나에만 맡기지 않습니다. 권한, 실행 규칙, 조직 요구사항과 함께 설계합니다. 도입 전에는 허용·거부·오류·timeout·중복 이벤트를 작은 합성 입력으로 각각 시험하고 handler 로그에 비밀값이 남지 않는지도 봅니다. 예기치 않은 미실행이 있으면 성공 보고 대신 적용 경로부터 확인하세요.
공식 한국어 도움말: ChatGPT 플랜과 Codex에서 계정별 이용 안내를 확인할 수 있습니다. 이 글은 해당 도움말의 공식 번역이 아니며 계정 조건과 요금은 공식 안내를 우선합니다.