Claude Code 훅 문서에 따르면 대부분의 이벤트에서 훅이 실패하거나 시간 초과되어도 Claude Code는 동작을 그대로 실행합니다. 경로가 잘못됐거나 스크립트 실행에 실패한 정책 훅은 모든 동작을 통과시킬 수 있습니다.
문서에 적힌 기본 동작이며, 비슷한 경우는 이 밖에도 있습니다. 아래 사례에서 정책 문구에는 문제가 없었습니다. 문제가 된 것은 정책이 실행된 위치, 또는 답을 받지 못했을 때의 동작이었습니다.
이 글에서는 이를 설명하는 용어인 정책 결정 지점과 정책 집행 지점을 먼저 정리합니다. 이어 어떤 배치에서든 확인할 세 가지 속성을 살펴봅니다. 무엇을 볼 수 있는지, 누가 우회하거나 수정할 수 있는지, 결정이 도착하지 않으면 어떻게 동작하는지입니다.
AI 에이전트 정책 집행의 의미
AI 에이전트 정책 집행은 에이전트 내부, 게이트웨이, 호스트, OS처럼 AI 에이전트의 동작 경로상 특정 지점에서 그 동작에 인가 결정을 적용하는 일입니다. 정책이 지켜지는지는 문구보다 그 지점의 다음 세 가지 속성에 더 크게 달려 있습니다.
- 무엇을 볼 수 있는가: 도구 호출, 요청, 명령, 또는 해석이 끝난
execve(2)인자. - 누가 우회하거나 수정할 수 있는가: 에이전트가 그 지점을 우회하거나 수정할 수 있는가.
- 결정이 도착하지 않으면 어떻게 동작하는가: 동작이 진행되는가(fail-open), 중단되는가(fail-closed).
정책 결정 지점(PDP)과 정책 집행 지점(PEP)의 역할
정책 결정 지점(PDP, policy decision point)은 정책을 평가해 결정을 내립니다. 정책 집행 지점(PEP, policy enforcement point)은 그 결정을 요청에 적용하는 곳입니다. OASIS XACML 3.0 명세는 PDP를 적용 가능한 정책을 평가해 인가 결정을 내리는 시스템 개체로, PEP를 결정을 요청하고 그 결정을 집행해 접근 제어를 수행하는 시스템 개체로 정의합니다.
NIST도 제로 트러스트 아키텍처에서 같은 쌍을 씁니다. SP 800-207은 접근이 정책 결정 지점(PDP)과 이에 대응하는 정책 집행 지점(PEP)을 통해 허용된다고 설명하고, 둘을 하나의 상자로 그립니다. 이 구분은 논리적인 것이라, 에이전트 내부 훅처럼 두 역할을 한 프로세스에서 함께 돌릴 수도 있습니다.
둘을 나누는 이유는 실패하는 방식이 다르기 때문입니다. 결정이 완벽하게 옳아도 그 결정을 적용할 쪽에 전달되지 않을 수 있습니다. 훅 기본값과 아래 두 CVE 사례는 모두 이 전달 단계에서 문제가 생겼습니다. 두 GitHub 이슈는 집행 지점이 잘못되는 다른 두 가지 방식을 보여 줍니다.
집행 지점이 볼 수 있는 범위
AI 에이전트 정책 집행 지점은 흐름 속 자기 위치에서 관찰한 것에만 정책을 적용할 수 있고, 그 위치 뒤쪽은 모두 검사되지 않은 채 남습니다. 관찰 수준은 세 가지 속성 중 첫 번째입니다.
NIST는 이 제약을 분명하게 말합니다. PDP/PEP는 트래픽 흐름에서 자신이 놓인 위치를 넘어서는 추가 정책을 적용할 수 없습니다. NIST의 제로 트러스트 원칙은 PDP/PEP를 리소스 가까이 옮기는 데 초점을 둡니다. NIST는 마지막 집행 지점과 리소스 사이 구간을 "암묵적 신뢰 영역(implicit trust zone)"이라고 부르며 경고합니다. 이 구간 안의 개체는 모두 적어도 마지막 PDP/PEP 게이트웨이만큼 신뢰받는다는 뜻입니다.
에이전트 환경에서 "트래픽 흐름 속 위치"를 구체적으로 풀면 이렇습니다. 에이전트 안의 훅은 에이전트가 하기로 결정한 도구 호출을, 게이트웨이는 자신을 지나는 요청을 봅니다. 호스트의 프로세스는 호스트가 곧 실행하려는 것을, 커널 수준 통제는 셸이 모든 확장을 끝낸 뒤 execve(2)에 전달되는 해석된 경로와 최종 인자를 봅니다. 각 지점은 자기가 관찰한 것에만 정책을 적용할 수 있고, 뒤쪽에 일부 신뢰 영역을 남깁니다. 매칭 규칙이 읽는 문자열과 실제로 실행되는 것이 달라질 수 있는 이유는 앞선 글 명령어 필터링과 GTFOBins에서 다뤘습니다.
에이전트의 우회·수정 가능성
도달 범위는 AI 에이전트가 정책 집행 지점을 우회하거나 수정할 수 있는지를 뜻합니다. 둘 다 확인해야 합니다. 에이전트가 우회하거나 수정할 수 있는 지점은 아무것도 제약하지 못합니다.
에이전트 내부 집행은 제약 대상과 같은 신뢰 도메인에 있습니다. Claude Code 훅은 문서화가 자세해서 가장 분명한 예입니다. PreToolUse 훅은 도구 호출이 실행되기 전에 돌며 그 호출을 막을 수 있습니다. 훅은 Claude Code의 환경에서 실행되고, 이는 에이전트가 작업하는 환경과 같습니다. anthropics/claude-code #11226의 제보자는 2025년 11월에 permissions.deny 규칙이 있는데도 Edit과 Write가 ~/.claude/hooks/를 수정할 수 있었다고 보고했습니다. 이 이슈는 2026년 1월 장기 미활동 이슈를 정리하는 봇이 "not planned"로 닫았고, 메인테이너는 답하지 않았습니다. 지금 Claude Code 권한 문서는 ~/.claude/를 보호 경로로 적고 있어서, 이 경로에 쓰려면 bypassPermissions 모드가 아닌 한 자동 승인되지 않고 확인을 거칩니다.
조직은 관리형 훅을 배포할 수 있고, allowManagedHooksOnly는 사용자·프로젝트·로컬·플러그인 출처의 훅을 막습니다. 이 설정은 훅을 추가할 수 있는 주체를 좁힐 뿐, 훅을 클라이언트 밖으로 옮기지는 않습니다.
결정 출처가 둘 이상이면 집행 지점에서 잘못 합쳐질 수도 있습니다. anthropics/claude-code #39344에서는 PreToolUse 훅이 permissionDecision: "ask"를 반환하면 permissions.deny가 아무 표시 없이 무시됐습니다(2.1.84 버전). Claude Code 협업자는 이 문제가 v2.1.101에서 수정됐다고 적었습니다. 버그는 패치됐지만 같은 유형의 문제는 남아 있습니다. 집행 지점에서 모든 결정 출처가 만나므로, 출처 사이의 상호작용도 여기서 정확하게 맞아야 합니다.
게이트웨이에도 도달 범위의 한계가 있습니다. 자신을 지나는 트래픽에만 정책을 집행하므로, 행위자가 이를 피할 수 있는지는 그 정책이 아니라 네트워크와 자격 증명이 트래픽을 게이트웨이로 강제하는지에 달려 있습니다.
결정이 도착하지 않을 때의 기본값
모든 AI 에이전트 정책 집행 지점에는 결정을 불러오지 못하거나, 닿지 못하거나, 평가하지 못할 때의 기본값이 있고, 이 기본값도 정책의 일부입니다. fail-open이면 동작이 실행되고, fail-closed이면 동작이 중단됩니다. 세 번째 속성은 가장 덜 주목받습니다.
Claude Code 훅 문서는 기본값을 명시합니다. PreToolUse에서는 종료 코드 2가 차단합니다. 그 밖의 0이 아닌 종료 코드는 stdout에 평문이 있거나 아무것도 없으면 차단하지 않는 오류로 처리되어 동작이 그대로 진행됩니다. 시간 초과된 command, http, mcp_tool 훅은 도구 호출을 막지 않습니다. command나 http 훅에 "onFailure": "block"을 설정하면(Claude Code v2.1.295 이상) 실패한 훅이 호출을 막습니다. 통제용으로 쓴 command·http 훅에 onFailure: "block"이 설정되어 있지 않으면, 모든 것이 정상일 때만 작동하는 권고에 불과합니다.
서버 측 집행 지점도 같은 속성을 가집니다. AWS API MCP Server의 CVE-2026-16584에 대해 GitHub 보안 권고문(advisory)은 프로세스가 유지되는 동안 요청별 정책 검사가 아무 표시 없이 생략된다고 설명합니다. 영향받는 버전은 0.2.13 이상 1.3.47 미만이고, 1.3.47에서 수정됐습니다. 결정 로직은 문제가 아니었습니다. 시작 시 정책 데이터를 불러오지 못했는데도 서버는 그 데이터 없이 요청을 계속 처리했습니다.
LiteLLM MCP 엔드포인트의 CVE-2026-59822도 다른 경로를 거친 같은 형태입니다. CISA는 2026-09-02에 "BerriAI LiteLLM Improper Authentication Vulnerability"를 Known Exploited Vulnerabilities 카탈로그에 추가했습니다. BerriAI 보안 권고문에 따르면 원인은 폴백 경로가 실패한 키 검증을 요청 거부 대신 빈 인증 객체로 대체할 수 있었다는 점입니다. 1.84.0 이전 버전이 영향을 받습니다.
두 경우 모두 통제에서 가장 약한 곳은 실패 경로였습니다.
AI 에이전트 정책 집행 배치 네 가지
네 가지 배치, 즉 에이전트 내부, 게이트웨이, 호스트, OS 또는 커널은 무엇을 보는지, 누가 닿을 수 있는지, 결정이 없을 때 무엇을 하는지가 서로 다릅니다.
| 배치 | 볼 수 있는 것 | 도달 범위: 에이전트가 우회하거나 수정할 수 있는가 | 결정이 없을 때의 기본값 |
|---|---|---|---|
| 에이전트 내부(훅, deny 규칙, 미들웨어) | 클라이언트가 보여 주는 도구 호출과 그 텍스트 | 에이전트와 같은 신뢰 도메인. 훅 파일 수정이 가능했다는 제보가 있음 | Claude Code 훅: PreToolUse에서는 종료 코드 2나 JSON deny만 차단하고, 그 밖의 실패와 시간 초과는 일반 권한 흐름으로 넘어감. command·http 훅에 onFailure: "block"을 설정하면 차단 |
| 게이트웨이 또는 프록시 | 자신을 지나는 요청 | 트래픽을 강제로 통과시키는 네트워크·자격 증명 경로만큼만 강함 | 구현에 따라 다름. LiteLLM의 MCP 엔드포인트는 실패한 키 검사를 빈 인증 객체로 대체했음(CVE-2026-59822) |
| 호스트(머신 위의 데몬이나 래퍼) | 호스트가 곧 실행하려는 것 | 에이전트가 호스트에서 무엇에 닿을 수 있는지에 따라 다름 | 구현에 따라 다름 |
| OS 또는 커널 | execve(2) 시점의 해석된 경로와 인자 | 권한, 그리고 통제가 행위자보다 아래에 있는지에 따라 다름 | 구현에 따라 다름 |
모든 행에 답이 정해지지 않은 속성이 하나 이상 있고, 네 행 중 세 행에서는 기본값이 그렇습니다. 중요한 건 지금 운영 중인 통제에서 어느 속성이 비어 있는지 아는 것입니다.
배치는 의도적인 절충일 수도 있습니다. Microsoft의 Agent Governance Toolkit은 콜백 핸들러나 미들웨어처럼 프레임워크의 기본 확장 지점으로 연결되는 상태 비저장 정책 엔진을 설명하고, Azure Kubernetes Service에서는 이 엔진을 에이전트 옆 사이드카 컨테이너로 배포하라고 권합니다. 저희가 보기에 프레임워크 안에 두면 지연이 낮고 프레임워크 맥락을 쓸 수 있고, 사이드카로 두면 에이전트와 한 단계 더 분리됩니다.
운영 중인 정책 집행에 던질 세 가지 질문
운영 중인 에이전트 통제 하나를 골라 세 가지에 답해 봅니다.
- 어디서 실행되는가? 에이전트 프로세스 안인가, 게이트웨이인가, 호스트인가, OS 아래인가? 그 위치에서 무엇을 볼 수 있고, 뒤쪽 신뢰 영역에는 무엇이 남는가?
- 누가 쓸 수 있는가? 에이전트, 또는 에이전트가 작업 중인 저장소가 정책이나 그 정책을 집행하는 프로세스를 수정할 수 있는가? 에이전트가 그 프로세스를 멈출 수 있는가?
- 결정하지 못하면 어떻게 되는가? 시간 초과, 크래시, 가져오기 실패, 초기화 오류, 닿지 않는 결정 서비스 앞에서 동작은 진행되는가, 중단되는가? 누가 그렇게 정했고, 어디에 적혀 있는가?
세 번째 질문에 답하지 못한다면 그 자체가 점검에서 찾아낸 문제입니다. 문제없어 보이는 정책 파일이나 정상 상태에서 통과한 테스트만으로는 그 답을 알 수 없습니다.
