AI Coding Assistants Are Unpredictable. GitGuardian AI Hooks Give You Control
요약 (TL;DR)
- 지침은 제안일 뿐, 통제가 아니다: Prompts, AGENTS.md, 및 CLAUDE.md 파일은 에이전트에게 단지 지침을 제공할 뿐이며, 에이전트는 이를 재해석하거나 우회할 수 있습니다. 보안에는 에이전트가 어떻게 추론하든 관계없이 유지되는 결정론적 통제가 필요합니다.
- Hooks는 시스템 수준에서 규칙을 강제한다: AI hooks는 프롬프트가 모델에 도달하기 전, 도구가 실행되기 전, 그리고 출력이 반환된 후에 결정론적 검사를 수행하여 에이전트의 추론과 관계없이 각 단계를 허용하거나 차단할 수 있습니다.
- GitGuardian AI Hooks가 에이전트 루프에서 비밀 정보를 차단한다: ggshield의 일부로서, 이들은 프롬프트, 명령어, 파일 읽기, MCP 호출 및 출력을 스캔합니다. 하나의 명령어인 ggshield machine setup은 Claude Code, Cursor, Codex를 포함한 지원되는 어시스턴트를 구성합니다.
AI 코딩 에이전트가 설계상 예측 불가능한 이유
거의 모든 사람이 이제 '시민 개발자(citizen coder)'입니다. AI coding assistants have evolved는 개발자가 함수를 자동 완성하는 것을 돕는 것에서, 원하는 소프트웨어를 설명할 수 있는 누구에게나 유용한 도구와 프로그램을 만드는 데 도움을 주는 것으로 발전했습니다. 누구나 코드를 만들 수 있는데, 이는 작업을 완료하는 데 필요한 모든 단계를 타이핑할 필요가 없기 때문입니다. AI 에이전트에게 목표, 일부 컨텍스트, 그리고 도구에 대한 접근 권한만 주면, 그들은 앞으로 나아갈 경로를 알아냅니다.
그 능력은 엄청나게 강력합니다. 하지만 동시에 우리가 그들이 취할 모든 경로를 신뢰성 있게 예측할 수 없다는 것을 의미하기도 합니다. 때로는 이것이 매우 나쁜 결과를 초래할 수도 있습니다.
에이전트는 우리가 예상하지 못한 설정 파일을 읽을 수 있습니다. MCP 서버를 호출하거나, 셸 명령어를 실행하거나, 다른 디렉토리를 검색하거나, 눈앞의 문제를 해결하는 데 우연히 도움이 되는 자격 증명을 찾을 수 있습니다. 그러한 결정들은 에이전트 시스템을 매우 강력하게 만드는 부분입니다.
보안 팀은 그 힘을 직접적으로 고려해야 합니다.
AI 에이전트가 강력한 이유: 우리가 예측하지 못한 경로를 찾아내기 때문입니다
우리는 이미 에이전트들이 사용자가 예상치 못했던 경로를 찾는 고통스러운 사례들을 많이 가지고 있습니다.
예를 들어, 2026년 4월 PocketOS는 한 에이전트가 회사 프로덕션 데이터베이스와 백업을 약 9초 만에 삭제했다고 보도했습니다. 이 에이전트는 스테이징(staging) 자격 증명 문제를 해결하는 과정에서 작동했으며, 그 문제를 해결할 다른 방법을 찾아 나섰습니다. 그러다 관련 없는 파일에서 광범위한 권한을 가진 Railway API 토큰을 발견했고, 이 자격 증명을 사용하여 파괴적인 API 호출을 실행했습니다.
이 에이전트는 파괴적인 작업 주변에서는 조심하라는 지침을 받았습니다. 하지만 그 지침은 토큰을 찾거나 API를 사용하는 능력을 제거하지는 못했습니다.
작년의 Replit 사고 사례도 같은 더 큰 문제를 보여주었습니다. SaaS 솔루션을 코딩한 개발자는 Replit의 AI 에이전트가 코드 동결(code freeze) 기간 동안 자신의 프로덕션 데이터베이스를 삭제했다고 보고했습니다. 이에 Replit은 이후 개발용 데이터베이스와 프로덕션 데이터베이스 사이에 더 강력한 분리 조치를 도입했습니다.
이러한 이야기들은 극적이지만, 목표를 향해 실제로 취해진 단계들은 평범한 에이전트의 행동이었습니다. 에이전트는 장애물을 만나고 다른 경로를 찾습니다.
이것은 버그가 아니라 기능입니다. 이것이 바로 사람들이 에이전트를 찾는 정확한 이유입니다.
에이전트에게 문제 해결을 요청할 때, 당신은 그것이 검사해야 할 모든 파일, 실행해야 할 모든 명령어, 고려해야 할 모든 진단 경로를 지정하지 않습니다. 만약 당신이 이미 이 모든 것을 알고 있다면, 아마도 도움 없이 문제를 해결할 수 있을 것입니다.
우리는 에이전트가 경로와 솔루션을 탐색하기를 원합니다. 보안 문제는 에이전트가 예상치 못한 접근 권한이나 건드려서는 안 될 강력한 도구를 접했을 때 시작됩니다.
왜 CLAUDE.md 및 AGENTS.md 규칙은 통제가 아닌 제안인가요
어떤 에이전트를 사용하든, 우리는 일반 언어를 사용합니다. 우리가 원하는 것을 설명하는 프롬프트를 작성합니다. 가능한 한 정확하려고 노력하지만, 언어는 지나치게 장황하지 않으면서도 상당히 부정확한 경향이 있습니다.
저희는 AGENTS.md와 CLAUDE.md 파일을 만듭니다. 여기에 시스템 지침과 프로젝트별 가이드를 추가합니다. 에이전트에게 어떤 명령어를 사용해야 하는지, 어떤 디렉토리를 피해야 하는지, 테스트를 어떻게 실행하는지, 그리고 어떤 프로덕션 시스템은 건드리지 말아야 하는지를 알려주려고 노력합니다.
이러한 메커니즘들은 매우 유용합니다.
Cursor는 시스템 수준의 지침을 일컫는 용어로 Rules라고 설명하며, 이는 "AI가 코드를 생성하거나, 수정을 해석하거나, 워크플로우를 돕기 위해 일관된 가이드를 제공하는 것"입니다. AGENTS.md 파일 역시 이러한 아이디어에 기반하고 있으며, 이곳에는 작업을 안내하기 위한 평문 지침을 저장할 수 있습니다.
여기서 핵심 단어는 "가이드(Guidance)"입니다.
자연어 지침은 제안일 뿐이다
다음과 같은 간단한 규칙을 고려해 봅시다: 절대로 프로덕션 데이터를 수정하지 마라
이것은 사람에게 말한다면 매우 간단해 보입니다. PocketOS 팀도 정확히 그렇게 생각했습니다. 에이전트에게 "애플리케이션을 고치고 다시 작동하게 만드는 것"이라는 더 큰 임무를 부여하면, 에이전트는 그 임무를 완수하기 위해 프로덕션 수정이 절대적으로 필요하다고 판단할 수 있습니다. 규칙을 우회하는 경로(예: 다른 도구, 자격 증명, API 또는 워크플로우를 통해)를 찾으려고 할 수도 있고, 프롬프트의 목적 달성을 위해 규칙을 무시할 수도 있습니다.
우리는 우리가 알고 있는 경로들을 막기 위해 계속 지침을 추가할 수 있지만, 에이전트는 부분적으로 우리가 미리 생각하지 못한 경로를 찾는 방식으로 설계되었고, 따라서 통제하는 내용을 작성하지 않았습니다. 이것이 바로 그 가치입니다. 보안은 오직 지침에만 의존할 수 없습니다. 우리는 에이전트가 작업을 추론하는 방식과 관계없이 특정 행동을 불가능하게 만드는 결정론적(deterministic) 제어 장치가 필요합니다.
작동하는 AI 에이전트 가드레일: 결정론적 제어
제어(Control)는 제안(Suggestion)과 다릅니다. 왜냐하면 AI가 규칙을 따를지, 또는 언제 따를지에 대해 아무런 발언권이 없기 때문입니다.
제어는 시스템 수준에서 에이전트가 무엇을 할 수 있고 무엇을 할 수 없는지를 결정합니다. 당신은 LLM에게 무언가를 제안하거나 추론하도록 시도하는 것이 아닙니다. 당신은 어떤 일이 발생할지 여부를 결정론적으로 허용하거나 금지하는 시스템 수준의 도구 실행을 강제하는 것입니다.
만약 에이전트가 특정 디렉터리에 대해 rm -rf를 절대 실행해서는 안 된다면, 해당 명령을 에이전트가 사용할 수 있는 도구 목록에서 제거할 수 있습니다. 심지어 에이전트가 실행되는 환경에서 특정 명령 자체를 완전히 제거할 수도 있습니다.
만약 에이전트가 프로덕션 API를 호출해서는 안 된다면, AI의 결정과는 떨어진 지점인 이그레스(egress) 규칙에서 해당 엔드포인트를 차단할 수 있습니다. 그리고 만약 에이전트가 자격 증명(credential)을 수집하거나 전송해서는 안 된다면, 워크플로우를 검사하여 비밀 정보가 도달하기 전에 이를 차단할 수 있습니다.
이러한 제어 장치를 어떻게 구현하느냐는 에이전트를 얼마나 격리시키는지에 달려 있는데, 예를 들어 Docker Sandboxes를 통한 샌드박싱(sandboxing)을 이용하거나, 에이전트 워크플로우의 핵심 순간에 특정 결정론적 도구 호출이나 정책 검사를 실행하는 방식이 있습니다.
바로 이 두 번째 부분이 코딩 어시스턴트들이 후크(hook)를 추가한 정확한 이유입니다.
AI 후크란 무엇인가요?
후크는 특정 무언가가 발생했을 때 자동으로 실행되는 코드 조각을 의미합니다.
개발자들은 이 아이디어를 수년 동안 사용해 왔습니다. 컴파일러나 운영체제가 필요할 때 시스템의 다른 부분에 알리도록 호출하는 방식이 바로 이것입니다. 대부분의 개발자는 Git 후크(Git hooks)에 대해 익숙할 것입니다. 예를 들어, 프리커밋 후크(pre-commit hook)는 Git이 커밋을 생성하기 전에 실행됩니다. 팀은 이 순간을 활용하여 코드를 검사하거나, 테스트를 실행하거나, 비밀 정보를 스캔할 수 있습니다. 만약 검사에 실패하면 커밋을 중단시킬 수 있습니다.
AI 후크는 동일한 기본 아이디어를 에이전트에 적용합니다.
에이전트가 프롬프트를 받거나, 파일을 읽거나, 셸 명령을 실행하거나, MCP 서버를 호출하거나, 다른 도구를 사용할 때, LLM(대규모 언어 모델)이 이를 추론하기 위해 호출되기 전과 후에 여러 단계가 발생해야 합니다.
후크는 우리가 이러한 중요한 순간에 검사를 배치할 수 있게 해줍니다.
예를 들어, 에이전트가 명령을 실행하기 전에 후크를 실행할 수 있습니다. 이 후크는 해당 명령을 검사하여 허용되어야 할지 여부를 결정할 수 있습니다.
프롬프트는 다음과 같이 말할 수 있습니다: "위험한 셸 명령어는 절대 실행하지 마세요."
이것은 지침(guidance)입니다. 에이전트는 여전히 무엇을 위험하다고 간주하는지, 그리고 더 큰 작업이 그것을 어쨌든 수행할 가치가 있는지 결정해야 합니다.
훅(hook)은 훨씬 더 직접적일 수 있습니다: 만약 명령어 == 'rm -rf' 이면 2로 종료
참고: 종료 코드 2는 이 단계를 중지하고 시스템 수준에서 더 이상 진행하지 않음을 의미합니다.
이것이 강제(enforcement)입니다.
Claude Code는 이러한 종류의 체크포인트를 PreToolUse라고 부릅니다. 도구가 실행되기 전에 다른 프로그램이 에이전트가 무엇을 하려고 하는지 검사하고 허용하거나 거부할 수 있습니다.
같은 아이디어가 워크플로우의 다른 지점에도 적용됩니다. 훅은 모델에 도달하기 전 프롬프트를 검사할 수 있습니다. 에이전트가 내용을 보기 전에 파일 읽기를 확인할 수 있습니다. 실행된 후 도구로부터 돌아오는 것을 검사할 수도 있습니다.
하지만 에이전트는 원하는 대로 추론할 수 있습니다. 특정 명령어, 파일 또는 도구가 작업을 완료하는 가장 빠른 방법이라고 결정할 수 있습니다. 훅은 그 결정과 실제 행동 사이에 직접 놓입니다.
Claude Code 훅, Cursor 훅, 및 Codex 훅 비교
모두가 훅이 존재해야 한다는 데 동의하며 아키텍처를 설계하여 이를 수용하고 있지만, 현재 단일한 산업 표준은 없습니다. 그리고 용어 또한 여전히 복잡합니다.
예를 들어, Claude Code 문서에는 사용자 프롬프트 제출(UserPromptSubmit) 및 PreToolUse부터 작업 생성, 권한 요청, 모델 전환, 컨텍스트 압축, 세션 수명 주기 이벤트에 이르기까지 모든 것을 다루는 33개의 훅 이벤트가 있습니다 (게시 시점 기준).
Cursor는 현재 에이전트 상호 작용, 탭 작업 및 워크스페이스 수명 주기 이벤트를 통해 21개의 이벤트를 문서화하고 있습니다. Cursor의 훅은 셸 실행, MCP 호출, 파일 읽기, 프롬프트, 도구 호출, 서브에이전트 및 에이전트 루프의 다른 부분들을 검사하거나 제어할 수 있습니다. Cursor는 특히 비밀 검색(scanning for secrets)과 위험한 작업 차단(gating risky operations)을 훅 사용 사례로 명시적으로 나열합니다.
이들(AI Hooks)은 정확히 같은 이름을 사용하거나 똑같은 기능을 노출하지는 않습니다. 현재 모든 코딩 어시스턴트가 따르는 중앙에서 합의된 훅 표준은 없습니다. 하지만 몇 가지 중요한 유사점들이 존재하며, 가장 위험한 순간들을 중심으로 훅을 구현하려는 수렴 경향이 커지고 있습니다.
이러한 시스템을 구축하는 모든 사람들은 대략적으로 동일한 워크플로우를 고려해야 합니다:
- 프롬프트가 입력됩니다.
- 모델이 도구를 사용하기로 결정합니다.
- 도구가 실행되려 합니다.
- 도구가 실행됩니다.
- 무언가가 반환됩니다.
- 에이전트가 계속 진행합니다.
Flowchart of the six-step AI agent loop, with three GitGuardian AI Hooks checkpoints
이러한 전환점들은 보안 팀들이 모델이 시도할 수 있는 모든 행동을 예측하려고 노력하지 않고도 정책을 강제할 수 있는 지점을 제공합니다.
Cursor는 심지어 Claude Code 훅 구성을 로드하는 지원까지 추가하여, Claude 훅 이름을 Cursor 등가물로 변환합니다. 이는 이러한 제어 지점 주변에서의 상호 운용성이 나타나기 시작했다는 고무적인 신호입니다.
훅을 통해 보안은 의도가 아닌 기능에 집중할 수 있다
에이전트가 올바르게 작동하는지에 대한 관심이 많습니다. 이는 확실히 유용하며 논의할 가치가 있습니다. 실제로 정책(policy)을 코드로 사용하여 가장 해로운 행동들을 막을 수 있기 때문입니다. 하지만 의도(intent)는 매우 빠르게 복잡해지며, 계속해서 규칙을 만드는 것은 끝없는 '무엇아? 무엇아?' 게임으로 변질됩니다.
사용자의 ~/.aws/credentials를 읽는 에이전트가 실제로 AWS 인증 오류를 문제 해결하는 중일 수 있습니다. MCP 서버 호출은 에이전트나 개발자가 전혀 예상하지 못한 API 키를 반환할 수도 있습니다. 개발자는 디버깅 프롬프트에 토큰을 알아차리지 못하고 붙여넣을 수도 있습니다.
이러한 시나리오들 중 어느 것도 악의적인 에이전트를 요구하지는 않습니다. 하지만 각 접근 권한(arm)은 에이전트에게 부여되며, 에이전트는 이를 예상되는 방식으로 사용할 수도 있고 사용하지 않을 수도 있습니다. 이 과정에서 에이전트는 해당 키들을 기록하고 복사하며, 평문(plaintext)으로 나타나는 곳이라면 어디든 보안 사고를 발생시킵니다.
Hooks는 시스템 수준에서 에이전트가 경로상에서 비밀 정보(secrets)를 사용하거나 볼 자격 자체가 있는지 여부를 우리에게 물어볼 수 있게 해줍니다.
바로 이 질문에 GitGuardian AI Hooks가 인증 정보(credentials)를 위해 답하도록 설계되었습니다.
GitGuardian AI Hooks는 에이전트 루프 내부에 비밀 탐지 기능을 배치합니다