Executive Summary
이 글은 2026년 10월 1일 앤트로픽이 Claude Code에 낸 Mods를 공식 문서와 내장 가드 소스로 다시 읽은 기록이다. Mods는 플러그인 안에 넣은 자바스크립트·타입스크립트 함수가 Claude Code 프로세스 안에서 도는 구조다. 도구 호출을 붙잡고, 프롬프트를 고쳐 쓰고, 화면을 다시 그리고, 자기 명령을 더한다. 기본값은 켜짐이다. 소개 기사 대부분은 여기까지 적고 멈췄다. 강력하다, 그런데 격리가 없다. 격리가 없는 쪽은 Claude Code만이 아니다. VS Code는 자기 문서에 확장 호스트가 VS Code 자신과 같은 권한을 갖는다고 적어 둔다. 거기서 멈추면 아직 아무 말도 안 한 셈이다.
문서는 그보다 구체적인 것을 적어 두었다. 첫째, 내가 적은 금지 규칙이 버티는 자리와 안 버티는 자리가 갈린다. Claude Code의 권한 규칙은 거부가 허용을 이기는 순서로 돌지만, 도구 호출의 최종 판정에 끼어드는 mod는 그 판정 뒤에 답하고 그 답이 앞의 판정을 대신할 수 있다. 그 답을 되돌리는 일은 엔진이 하지 않는다. 먼저 앉는 내장 가드가 하고, 가드는 관리 설정이 깔렸거나 회사 요금제로 로그인했을 때만 적재된다. 둘째, 막는 쪽의 기본값이 통과다. 훅이 던지거나 시간 한도를 넘기면 Claude Code는 그 훅을 건너뛰고, 붙잡아 두려던 명령은 그대로 간다. 셋째, Mods는 격리된 상자가 아니라 가로챌 수 있는 길목이다. 바깥에 닿는 길이 하나뿐이고 그 길의 호출마다 다시 이벤트가 서서, 설치 전에 무엇을 부르는지 뽑아 볼 수 있다. 대신 그 길목 밖으로 나가는 문이 둘 있다.
여기까지가 공식 문서와 공개 소스에 적힌 사실이다. 여기서부터는 이 글의 해석이다. 세 가지는 각각 새로 생긴 결함이라기보다, 규칙이 적히는 자리와 규칙이 적용되는 범위가 다르다는 하나의 모양이다. 파일 하나를 읽지 못하게 막아 두어도 플러그인 코드는 그 파일을 읽는다. 규칙이 틀린 게 아니라 규칙이 덮는 대상이 다르다. 그리고 이 모양에는 50년 전에 붙은 이름이 있다.
45 / 80
걸 수 있는 이벤트와 API 메서드
v2.1.289 문서 기준. 이름 붙은 이벤트 45개, 메서드 80개이고 그 메서드 호출도 전부 다시 이벤트다
15
내장 가드가 거는 이벤트
가드 소스에서 직접 셌다. 파일·네트워크·프로세스·도구 실행은 그냥 통과시킨다
10초 / 1초
훅과 실패 처리의 시간 한도
v2.1.289 문서 기준. 훅 한 번에 10초, 그 실패를 받아 막는 처리기에는 1초
0 / 3
실패 처리기를 단 공식 예제
공개된 예제 mod 세 개의 소스를 열어 센 수. 위험한 명령을 붙잡는 예제도 안 달았다
프로세스 안으로 들어온 함수들
Mods는 따로 떨어진 새 제품이 아니라 플러그인의 한 부분이다. 플러그인 폴더 안에 훅 모듈 하나를 넣어 두면, Claude Code가 자기 프로세스 안에서 그 모듈의 함수를 부른다. 터미널에서는 v2.1.287부터, 데스크탑 앱에서는 v2.1.286부터 돌고 기본값은 켜짐이다. 설정 파일에 적던 기존 훅은 그대로 살아 있다. 문서가 그 자리를 못 박았다. "그것들에 관해 폐기된 것은 아무것도 없다."
함수가 받는 것은 이벤트다. 이름 붙은 이벤트가 45개 있고, 모듈이 바깥에 닿을 때 쓰는 API에는 네임스페이스 21개와 메서드 80개가 있다. 둘 다 v2.1.289 기준 공식 문서의 표를 그대로 센 값이고, 메서드 80은 상태 저장용 임포트 헬퍼 다섯과 사용량 조회의 반환 필드 다섯을 뺀 수다. 여기에 조건 하나가 더 붙는다. 그 메서드 호출 하나하나가 다시 이벤트로 선다. 공개된 타입 선언 파일은 판본이 더 낮아(v2.1.277) 네임스페이스 20개·메서드 78개가 나오므로, 두 기준을 한 문장에 섞어 쓰면 수가 틀린다.
훅이 이벤트를 다루는 수는 셋뿐이다. 보고 넘기거나(observe), 고쳐서 넘기거나(rewrite), 뒤를 부르지 않고 자기가 답한다(answer). 세 번째가 이 글 전체의 축이다. 도구 호출을 받은 훅이 뒤를 부르지 않고 "거부"라고 답하면 그 명령은 실행되지 않고, "승인"이라고 답하면 권한 프롬프트가 뜨기 전에 통과한다.
1.1훅 모듈에는 파일도 네트워크도 없다
모듈 자체의 권한은 좁다. 문서가 직접 적는다.
훅 모듈 자체에는 Node.js API가 없고, setTimeout 같은 타이머 전역도 없으며, 자기 몫의 네트워크나 파일 접근도 없다.
원문: "The hooks module itself has no Node.js APIs, no timer globals such as setTimeout, and no network or file access of its own." — mods API 문서
파일을 읽거나 프로그램을 띄우거나 네트워크를 쓰려면 전부 그 API를 지나야 한다. 이 설계가 §2의 내용을 가능하게 만든다. 길이 하나뿐이면 그 길에 검문소를 세울 수 있다. 다만 모듈이 그 API로 하는 일은 모듈을 실행한 사용자의 권한으로 이뤄진다. 좁은 것은 모듈의 문법이지 모듈의 권한이 아니다.
1.2같은 틀 위에서 할 수 있는 일의 폭
Claude Code 자신의 기능 가운데 여럿이 이미 이 틀로 옮겨져 있다. /plugin 목록에는 여섯이 뜨고, 그중 넷은 소스가 공개돼 있다. 이 공개분을 열어 보면 같은 틀 위에서 할 수 있는 일의 폭이 보인다. 변경 내용을 보여 주는 diff는 네임스페이스 21개 중 10개를 건드리고 API 메서드 23개를 부른다. 보안 기본값 노릇을 하는 내장 가드는 설정 읽기와 로그 쓰기 둘만 부른다. 둘 다 같은 자리에 앉는 같은 종류의 코드인데, 손이 닿는 범위가 그만큼 벌어져 있다.
1.3훅은 일곱 자리 중 여섯에서 돌고, 그림은 두 자리에서만 나온다
"터미널과 데스크탑 앱 둘 다 지원"이라는 요약은 절반만 옮긴 것이다. 공식 문서의 실행 자리 표를 보면 훅이 도는 범위와 화면에 그림이 나오는 범위가 서로 다르다. 무인으로 도는 자리에서도 훅은 돈다. 이 사실이 §6으로 이어진다.
| Claude Code를 돌리는 자리 | 훅이 도나 | mod가 그린 게 보이나 |
|---|---|---|
터미널의 claude (편집기 내장 터미널·JetBrains 플러그인 포함) | 돈다 | 보인다 |
| 데스크탑 앱 Code 탭 (WSL 세션 제외) | 돈다 | 보인다 (터미널 전용 요소 제외) |
| 데스크탑 앱의 WSL 세션 | 안 돈다 (플러그인 자체가 안 된다) | 안 보인다 |
| VS Code 확장의 채팅 패널 | 돈다 | 안 보인다 |
claude -p 와 Agent SDK | 돈다 | 안 보인다 |
| claude.ai·모바일에서 쓰는 원격 제어 | 돈다 (내 기계의 세션에서) | 내 기계 터미널에서 |
| 클라우드 세션 | 돈다 (설정이 넘어가는 플러그인에 한해) | 안 보인다 |
Mods 개요 문서의 실행 자리 표를 옮겼다. 일곱 자리 중 여섯에서 훅이 돌고, 그림은 둘에서만 나온다. 사람이 화면을 보지 않는 자리에서도 훅은 돈다는 뜻이다.
격리는 없지만 길목은 있다
해설 기사들이 공통으로 멈춘 자리가 "격리가 없다"이다. 틀린 말은 아니지만 설계의 절반만 옮긴 문장이다. 앤트로픽이 Mods에 둔 장치는 길목이다. §1에서 본 대로 훅 모듈에는 파일도 네트워크도 없고, 바깥에 닿는 길이 API 하나뿐이다. 그리고 그 길에서 일어나는 호출마다 다시 이벤트가 선다.
이 호출 하나하나가 그 자체로 이벤트이고, 네임스페이스와 메서드 이름을 그대로 딴 이름을 갖는다. 체인에서 앞에 있는 mod가 당신의 호출을 보거나, 고쳐 쓰거나, 거절할 수 있다. 조직이 mod가 닿는 범위를 제한하는 방법이 그것이다. 원문: "Every one of these calls is itself an event … A mod earlier in the chain can observe, rewrite, or refuse your call, which is how an organization restricts what mods reach." — mods API 문서
여기에 더해 앞선 mod는 뒤에 올 mod가 받을 API 객체 자체를 바꿔서 넘길 수 있다. 그리고 이 길목이 성립하려면 코드가 정적으로 읽혀야 하므로, 읽히지 않는 방식으로 API를 쓰는 mod는 적재 자체가 거부된다. 확장 생태계에서 흔치 않은 장치다.
2.1격리가 없는 것은 이 범주의 기본값이다
그러면 "격리가 없다"는 문장은 어디에 놓아야 하나. 비교 대상의 공식 문서를 열어 보면 답이 나온다. VS Code는 자기 문서에 이렇게 적는다. "확장 호스트는 VS Code 자신과 같은 권한을 갖는다." 개발도구의 확장이 호스트 권한으로 도는 것은 이 범주의 기본값이고, 그래서 그 문장은 제품 비평이 아니라 범주 서술이다. 이 글이 다음 칸으로 가야 하는 이유가 거기 있다.
2.2길목 밖으로 나가는 문이 둘 있다
첫째 문은 자식 프로세스다. 공식 문서는 격리를 켜도 "mod가 띄운 프로세스는 그 밖에서 돈다"고 적는다. 네트워크 정책도 같다. 조직이 웹 요청을 꺼 두면 mod가 API로 보내는 요청은 거부되지만, mod가 띄운 프로그램은 사용자 자신의 접근 권한으로 네트워크에 닿는다.
둘째 문은 권한 규칙이 덮는 대상의 경계다. 플러그인 보안 문서가 한 문장으로 못 박았다. "Claude Code의 권한 규칙과 격리는 Claude가 하는 도구 호출을 덮지, 플러그인이 스스로 돌리는 코드를 덮지 않는다." 조직 관리 문서는 같은 사실을 예까지 들어 적는다. Read(.env)를 거부해 두어도 mod는 파일 읽기 메서드로 그 파일을 읽거나, 그렇게 하는 프로그램을 띄울 수 있다는 것이다. 그런데 비밀을 지키는 정식 방법으로 권한 문서가 안내하는 것이 바로 그 거부 규칙이다. 두 문서가 서로를 갉는 것처럼 보이지만 모순은 아니다. 같은 파일을 두 주체가 두 경로로 만지고, 규칙은 그중 한 경로에만 걸려 있다.
페블러스가 플러그인 보안 문서와 조직 관리 문서의 두 문장을 도식으로 옮겼다. 왼쪽 경로와 오른쪽 경로는 같은 파일에 닿는데, 거부 규칙은 왼쪽에만 걸린다. 규칙이 틀린 게 아니라 규칙이 덮는 대상이 다르다는 것이 이 그림의 요지다.
2.3이 설계에는 이름이 있고, 그 계보가 아는 한계도 같은 자리에 있다
이 구조에 문서는 이름을 붙이지 않는다. 아래 이름은 이 글이 가져다 붙인 것이다. 모든 권한을 객체 하나로 넘기고 그 객체의 호출을 다시 가로챌 수 있게 하는 구조는 처음 나온 것이 아니다. 객체 능력(object-capability) 모델에서 이것을 끼어들기에 의한 권한 감쇠라고 부른다. 밀러(Mark S. Miller)가 2006년 박사논문에서 정리한 정의에 따르면, 참조를 그대로 넘기면 받는 쪽은 깎이지 않은 권한을 갖고, 권한을 깎으려면 중간에 객체를 하나 끼워 전달 행동을 통제해야 한다. 앞선 mod가 뒤 mod에게 넘길 API 객체를 바꿔 주는 수가 그 정의와 겹친다.
이름을 붙이고 나면 그 계보가 이미 아는 한계도 따라온다. 자바스크립트에서 이 모델을 구현한 계열(SES와 Endo, 의존성 격리를 하는 LavaMoat)이 공통으로 서는 자리가 있다. 컴파트먼트는 언어 층의 경계이지 운영체제의 경계가 아니다. 참조 그래프는 제약하지만 프로세스 권한은 제약하지 않는다. 독립 감사 보고서에서도 환경변수를 고쳐 격리 적재 자체를 건너뛰게 만든 사례가 나왔다. 그러니 위에서 본 첫째 문, 자식 프로세스가 밖에서 도는 것은 구멍이 뚫린 결과가 아니다. 그 권한은 처음부터 중재 대상 밖에 있었다. 이 대비는 "다른 구현은 되는데 Claude Code만 안 된다"는 이야기가 아니다. 같은 자리에서 다 같이 멈춘다.
2.4길목이 바꾸는 것은 화면에 그려지는 것이다
발표 직후 널리 퍼진 요약 하나를 여기서 바로잡고 가야 한다. "Mods가 민감 정보를 자동으로 지워 준다"는 서술이다. 두 겹으로 틀렸다. 그런 필터는 Claude Code의 내장 기능이 아니고, 그 서술이 근거로 든 예시 mod가 하는 일도 삭제가 아니다. 그 예시는 이메일 주소를 "마우스를 올리기 전까지 화면에서 시각적으로 가린다." 지우지 않고, 올리면 보인다. 길목에 앉은 mod가 바꾸는 것은 화면에 그려지는 것이지 Claude가 이미 읽은 값이 아니다. 이 구분을 놓치면 가림막을 보호 장치로 세게 된다.
금지 규칙이 버티는 자리에는 조건이 붙는다
이 절이 재는 것은 사람의 작성 습관이 아니라 엔진의 적용 범위다. 사람이 권한 규칙을 미리 적게 했더니 무슨 일이 생겼는지는 권한 규칙을 미리 쓰게 한 실험에서 따로 다뤘고, 여기서는 잘 쓴 규칙이 어디까지 효력을 갖는지만 본다. 결론부터 적는다. 관리 설정이 깔려 있지도 않고 회사 요금제로 로그인하지도 않은 기계에서는, 설치한 mod가 사용자의 금지 규칙이 거부한 도구 호출을 승인할 수 있다. 조건절을 떼면 과장이 되고, 붙이면 설계 사실이 된다.
3.1규칙의 순서와 그 뒤에 답하는 자리
Claude Code의 권한 규칙에는 명시된 우선순위가 있다. 권한 문서의 문장은 이렇다. "규칙은 거부, 질문, 허용 순으로 평가된다. 그 순서에서 처음 일치하는 것이 결과를 정한다." 그리고 같은 절이 못 박는다. "허용 규칙은 거부 규칙에 예외를 낼 수 없다." 거부가 가장 세다는 뜻이다.
그다음 문단이 새로 생긴 자리를 적는다. 도구 호출의 최종 판정 이벤트를 거는 mod는 규칙과 설정 훅이 전부 결정한 뒤에 답하고, "그 답이 앞의 답을 대신할 수 있다." 문서는 그 대신하기가 어디까지 가는지를 네 줄로 나눠 적는데, 마지막 줄이 이 글의 중심이다.
거부 규칙: 관리 설정이 있는 기계이거나 Team 또는 Enterprise 요금제로 로그인한 경우에는, 거부 규칙이 기본적으로 mod보다 우선하고 당신의 조직이 그것을 바꿀 수 있다. 그 밖의 어디서든, mod는 거부 규칙이 거절한 호출을 승인할 수 있다. 원문: "Deny rules: on a machine with managed settings, or when you're signed in with a Team or Enterprise plan, deny rules hold over the mod by default, and your organization can change that. Anywhere else, the mod can approve a call that a deny rule refuses." — 권한 문서
3.2거부 우선을 지키는 주체는 또 하나의 mod다
왜 조건이 붙는지는 조직 관리 문서를 열면 나온다. 거부 우선을 되돌리는 주체가 엔진이 아니기 때문이다. 그 일은 또 하나의 mod가 한다. Claude Code는 사용자가 설치한 모든 mod보다 앞에 sec-default@builtin이라는 내장 가드를 적재하고, 사용자는 그것을 끌 수 없다. 다만 적재 조건이 둘 있다. 기계에 관리 설정이 깔려 있거나, 사용자가 Team 또는 Enterprise 요금제로 로그인했거나다. API 키로 인증하거나 클라우드 사업자를 거쳐 들어오는 사용자는 관리 설정이 깔린 기계에서만 가드를 받는다. 그리고 같은 문서가 덧붙인다. "가드가 적재되지 않는 곳에서는 두 선택지 중 어느 것도 적용되지 않는다."
순서는 이렇게 선다. 체인에서 맨 앞에 앉은 mod가 가장 바깥이고, 이벤트를 남보다 먼저 보고 결과를 남보다 나중에 받으며, 뒤의 것들이 아예 돌지 말지를 정한다. 설정 파일에 적는 기존 훅도 이 줄 안에 자리가 있는데, 그 자리가 어디냐에 따라 효력이 갈린다. 관리 설정에 적힌 도구 호출 전 훅은 첫 mod보다 앞에서 돌고 거기서 막히면 그것이 최종이다. 반면 내 설정 파일에 적은 같은 훅은 체인 맨 끝에서 돌기 때문에, 앞에 앉은 mod가 다음을 부르지 않고 자기가 답해 버리면 아예 돌지 않는다. §3.1에서 본 비대칭이 설정 훅에서도 같은 모양으로 한 번 더 나온다.
사용자 뒤에 오는 칸도 하나 있다. 조직은 관리 설정에 목록을 적어 자기 mod를 사용자 mod보다 앞에 세울 수도 있고 뒤에 세울 수도 있다. 뒤에 세운 것은 사용자가 설치한 mod가 전부 지나간 다음에 도는데, 앞 칸의 mod가 다음을 부르지 않고 자기가 답해 버리면 그 호출을 보지 못한다. 아래 그림의 네 번째 칸이 그 자리다. 그 칸에 앉은 정책 mod가 실패하면 어떻게 되는지는 §4.4에서 따로 적는다.
페블러스가 이벤트 문서의 체인 순서 절과 조직 관리 문서의 가드 적재 조건을 한 줄로 그렸다. 가드 칸만 점선인 것이 이 글의 논지다. 그 칸이 비는 기계가 개인 요금제로 혼자 쓰는 흔한 설치다.
그러면 개인이 가드를 자기 손으로 깔면 되지 않나. 가드 소스는 공개돼 있다. 그런데 가드 자신의 설명서가 그 길을 막아 둔다. "이것은 다른 어떤 것과도 같은 플러그인 폴더이지만, 중요한 단 하나의 동작인 next.to가 관리 티어 밖에서는 거부되므로, --plugin-dir로 적재하면 통과만 할 수 있는 플러그인이 앉는다." 읽을 수는 있는데 깔아 쓸 수는 없다.
3.3가드가 보는 것과 그냥 통과시키는 것
그렇다면 반대로, 관리 설정을 깔면 안전해지는가. 가드가 무엇을 보는지 세어 보면 답이 나온다. 공개 소스의 등록 파일을 열어 on( 호출을 전부 세면 거는 이벤트가 15개이고, 가드 자신이 API에서 부르는 것은 설정 읽기와 로그 쓰기 둘뿐이다. 그 15개는 조직이 설정한 것(관리 CLAUDE.md와 규칙, 설정, 도구 목록과 설명, 최종 판정, 다른 mod의 적재 여부)을 사용자 티어의 손이 닿지 않게 하는 데 쓰인다. 설명서 마지막 행이 나머지를 한 줄로 적는데, 그 목록에 파일 접근과 네트워크 요청과 프로세스 실행과 도구 호출 자체가 들어 있다. 전부 통과다. 설명서가 스스로 범위를 좁혀 적은 문장이 그 뜻이다. "이 플러그인은 정확히 그것들을 사용자 티어의 손이 닿지 않는 곳에 두고, 자기 몫의 정책은 아무것도 더하지 않는다." 가드는 조직이 이미 갖고 있던 통제를 지키는 물건이지 사용자의 파일을 지키는 물건이 아니다.
3.4조직이 쥔 두 스위치는 서로 반대 방향으로 엄격하다
가드에는 관리 설정으로만 켜지는 선택지가 둘 있다. 조직이 배포한 mod만 적재하게 잠그는 쪽과, 거부 규칙을 설치한 mod가 넘어설 수 있게 푸는 쪽이다. 뒤쪽은 기본이 잠김이다. 공개된 정책 판정 코드를 읽어 보면 두 선택지가 서로 반대 방향으로 엄격하게 짜여 있다. 잠그는 쪽은 값이 비어 있지만 않으면 무엇이 와도 잠기고, 푸는 쪽은 정확히 true라는 값일 때만 풀린다. 문자열 'true'나 숫자 1을 적으면 안 풀린다. 오기입이 보호를 깨는 방향으로는 가지 않게 한 설계이고, 그 원칙을 테스트 이름이 말로 적어 두었다. "잘못 쓴 값도 여전히 잠근다, 관리 잠금이 읽히는 대로."
가드가 살아 있는 기계에서 거부 규칙이 실제로 버티면, 사용자는 한 줄을 본다. 설명서에 적힌 문구와 소스의 반환 문자열이 한 글자도 다르지 않다.
<plugin> tried to lift a deny rule in your settings from a <tool> call (<rule>); the deny rule holds over the plugins you install (allowModsToOverrideDenyRules)
가드 설명서와 소스의 알림 문자열을 대조해 확인했다. 옮기면 이렇다. "어떤 플러그인이 당신의 설정에 있는 거부 규칙을 어떤 도구 호출에서 들어 올리려 했고, 거부 규칙이 당신이 설치한 플러그인보다 우선한다." 이 줄이 안 보이는 기계가 §3.2의 점선 칸이 빈 기계다.
3.550년 된 잣대로 재면 한 칸이 빈다
아래 맞댐은 공식 문서에 없다. 이 글이 댄 잣대다. 접근을 중재하는 장치가 갖춰야 할 것을 처음 적어 둔 문헌이 1972년 앤더슨(James P. Anderson) 보고서이고, 거기 적힌 세 요건은 오늘날에도 그대로 인용된다. 변조가 불가능할 것, 항상 불릴 것, 분석과 시험이 가능할 만큼 작을 것. 그 잣대를 내장 가드에 대면 두 칸이 차고 한 칸이 빈다.
| 1972년의 세 요건 | 내장 가드 | 근거 |
|---|---|---|
| 변조 불가 (tamper proof) | 찬다 | 사용자가 끌 수 없고, 체인 맨 바깥에 앉아 뒤의 것들이 돌지 말지를 정한다 |
| 분석·시험 가능할 만큼 작음 | 찬다 | 등록 파일이 3,643바이트이고 판정마다 별도 파일과 유닛테스트가 붙어 있으며 소스가 공개돼 있다 |
| 항상 불림 (always invoked) | 빈다 | 관리 설정이 있거나 회사 요금제로 로그인했을 때만 적재된다 |
세 요건의 축자는 앤더슨 보고서를 그대로 인용한 미 국방부 평가 기준 문서에서 가져왔고, 오른쪽 두 칸은 공식 문서와 공개 소스에서 확인했다. 앤더슨 보고서도 가드 설명서도 서로를 가리키지 않는다.
하필 비는 칸이 "항상 불린다"라는 점이 눈에 걸린다. 다만 이것을 설계 실패로 읽으면 틀린다. 가드 설명서가 스스로 범위를 좁혀 적었듯, 그 물건은 중재자가 되려고 만들어진 것이 아니다. 여기서 쓸 수 있는 문장은 한 줄까지다. 그 자리에 앉은 유일한 물건을 중재자의 잣대로 재면 한 칸이 빈다.
막는 쪽이 실패하면 통과시킨다
Mods의 홍보 문구 가운데 가장 솔깃한 것이 "안전 장치를 직접 만들 수 있다"이다. 위험한 명령을 훅으로 붙잡아 두고 사람에게 물은 다음 진행 여부를 정하는 식이다. 그 문구에는 뒷면이 있고, 그 뒷면도 같은 문서에 적혀 있다. 직접 만든 안전 장치는 자기가 실패할 때 막는 대신 통과시킨다.
4.1실패하면 건너뛴다
이벤트 문서가 실패 처리를 두 줄로 나눠 적는다. 실패 처리기를 달지 않은 훅이 예외를 던지거나, 시간 한도를 넘기거나, 모양이 틀린 결과를 돌려주면 이렇게 된다.
다음을 부르기 전에 실패한 경우: Claude Code가 그 훅을 건너뛰고, 다음 처리기가 그 자리에서 돈다. / 다음이 완료된 뒤에 실패한 경우: 그 결과가 그대로 서고, 아무것도 두 번 돌지 않는다. 원문: "It failed before callingnext: Claude Code skips it, and the next handler runs in its place" / "It failed afternextresolved: that result stands, and nothing runs a second time" — 이벤트 문서
무엇이 남는지도 적혀 있다. 한 줄이다. 그 mod와 이벤트와 사유를 적은 로그 한 줄이 어딘가에 남고, 붙잡혀 있던 명령은 간다. 같은 문서의 보류 예제가 주석으로 그 결과를 직접 말한다. "Claude Code는 시간 한도를 넘긴 훅을 건너뛰므로, 붙잡아 두었던 명령이 실행된다." 사람이 아직 답하지 않았는데 명령이 먼저 간다는 뜻이다.
4.2닫히게 하려면 직접 달아야 하고, 그 대가가 1초다
닫히게 만드는 방법도 같은 쪽에 있다. 등록한 훅에 실패 처리기를 붙여 자기 자리에서 대신 답하게 하면 된다. 문서가 싣는 예제는 이렇다.
on('tool.call', { tool: 'Bash' }, guard).catch(async ($, e, next) => {
// next.error.kind 는 'throw' 또는 'timeout' — guard 가 어떻게 실패했는지를 말한다
return { deny: 'The command guard failed, so this command was not run: ' + next.error.kind }
})
이벤트 문서에 실린 공식 예제를 그대로 옮겼다. guard가 멀쩡히 도는 동안 이 처리기는 한 번도 돌지 않는다. 문서의 설명은 이렇게 닫힌다. "이 처리기가 없으면 Claude Code는 guard를 건너뛰고 명령을 실행할 것이다."
대가는 시간이다. 훅 자신에게 주어진 시간이 10초인데, 그 실패를 받아 대신 답하는 처리기에게 주어진 시간은 1초다. 그리고 그 1초 안에 판단에 필요한 자료를 다시 모으려 하면 같은 함정에 다시 걸린다.
표의 나머지 세 줄도 같은 눈금 위에 있다. 프롬프트를 고쳐 쓰는 훅에 주어진 시간은 50밀리초이고, 세션이 끝날 때 도는 훅은 전부를 합쳐 1.5초다. 반대로 mod가 띄운 프로세스에는 기본 30초가, 길게 잡으면 10분이 주어진다. 표 첫 줄이 단서를 달아 둔 대로 그 대기는 훅 자신의 10초에서 빠지므로, 훅이 자기 자리에서 판단하는 시간은 10초와 1초로 끊기는데 훅이 바깥 프로그램에 맡긴 일은 10분까지 간다.
| 한도 | 값 |
|---|---|
| 한 이벤트에서 훅 자신의 실행 시간 (다음 호출과 API 호출 대기는 빼고 센다) | 10초 |
| 프롬프트 편집 훅의 실행 시간 | 50밀리초 |
| 실패 처리기의 실행 시간 | 1초 |
| 세션 종료 훅 전부를 합친 예산 | 1.5초 |
| mod가 띄운 프로세스의 시간 초과 | 기본 30초, 최대 10분 |
v2.1.289 기준 공식 문서의 한도 표에서 이 절에 필요한 다섯 줄만 옮겼다. 10초와 1초의 차이가 이 절의 요지다.
4.3공개된 공식 예제 셋 중 실패 처리기를 단 것은 없다
그러면 앤트로픽이 공개한 예제들은 이 함정을 피했을까. 공식 예제 저장소의 세 mod를 소스 전문으로 열어 등록 체인에 실패 처리기가 붙었는지 세어 봤다. 위험한 명령을 붙잡는 것, 토큰 사용량을 띄우는 것, 세션을 되감아 보여 주는 것 셋이다. 셋 다 붙이지 않았다.
| 공식 예제 mod | 하는 일 | 거는 이벤트 | 실패 처리기 |
|---|---|---|---|
blast-radius | 위험한 셸 명령을 붙잡고 사람에게 묻는다 | 2종 | 없음 |
token-weather | 토큰 사용량을 프롬프트 위에 띄운다 | 3종 | 없음 |
replay-theater | 세션을 되감아 보여 준다 | 7종 | 없음 |
공식 예제 저장소의 소스 전문을 2026년 10월 6일에 읽고 등록 호출을 전부 세었다. 표본이 셋뿐이라 의도를 추정하지 않는다. 적을 수 있는 것은 관찰된 사실까지다.
셋 가운데 성격이 다른 것이 하나 있다. 위험한 명령을 붙잡는 예제다. 그 코드는 자기 로직 안의 예외는 내부에서 잡아 거부로 바꾼다. 그러나 그것은 엔진에 등록하는 실패 처리기가 아니다. 엔진이 정의한 실패, 즉 던지거나 시간을 넘기는 경우는 그 내부 처리로 막지 못한다. 그리고 그 예제의 설명서가 스스로 격을 낮춰 둔다. "이것은 안전망이지 권한 체계가 아니다. 확실히 막으려면 권한 규칙을 쓰라." 설명서는 잡히지 않는 명령 꼴도 여럿 나열해 둔다.
4.4조직이 깐 정책 mod도 같은 자리에 선다
이 기본값은 개인이 만든 장치에만 적용되는 게 아니다. 조직 관리 문서는 자기 조직의 정책 mod를 쓰는 법을 안내하면서 같은 경고를 붙인다. 다른 mod의 적재 여부를 심사하는 훅이 던지거나 시간 한도를 넘기면 Claude Code는 그 훅을 건너뛰므로 "검사가 열린 채로 실패하고, 검사받던 mod가 적재된다." 그리고 설치된 mod를 돌리는 작업 스레드가 세 번 죽으면 내장이 아닌 mod가 전부 내려간다. 조직이 깐 정책 mod도 같이 내려간다.
내장 가드만 반대 방향이다. 다만 그 반대도 조건부다. 공개 소스를 읽어 보면 가드 안에서 실패 처리기가 붙은 자리는 둘뿐이고, 둘의 동작이 다르다. 최종 판정 쪽은 실패하면 "검사되지 않은 거부"로 떨어진다. 테스트 이름이 그 결과를 그대로 적어 두었다. "규칙을 평가할 수 없을 때 그 호출은 거절된다." 다른 mod의 적재를 심사하는 쪽은 실패 시점을 본다. 이미 통과시킨 뒤에 실패했으면 그 통과를 유지하고, 아직 결정 전이면 거부한다. 그러니 "가드는 무조건 닫힌다"가 아니라, 가드는 자기가 아직 허락하지 않은 상태에서 실패하면 닫고 이미 통과시킨 뒤에 실패하면 그 통과를 유지한다고 적어야 정확하다. 정책을 아예 못 읽는 경우는 더 막는 쪽으로 접힌다.
4.51975년 문장 하나가 이 실패 모양을 이름까지 적어 두었다
아래 인용은 공식 문서가 아니라 1975년 논문에서 온다. 맞대는 것은 이 글이다. 솔처(J. H. Saltzer)와 슈뢰더(M. D. Schroeder)가 1975년에 정리한 여덟 설계 원칙 가운데 둘째가 안전한 기본값이다. 그 항목의 마지막 문장이 위에서 본 실패 모양을 거의 그대로 적는다.
접근을 명시적으로 배제하는 기제에서 설계나 구현의 실수는 접근을 허용하는 쪽으로 실패하는 경향이 있으며, 그 실패는 평소 사용 중에 눈에 띄지 않고 지나갈 수 있다. 원문: "a design or implementation mistake in a mechanism that explicitly excludes access tends to fail by allowing access, a failure which may go unnoticed in normal use." — Saltzer & Schroeder (1975), fail-safe defaults 항목
위험한 명령을 붙잡는 훅은 정의상 접근을 명시적으로 배제하는 기제다. 그 기제의 실패 모드가 허용이고, 남는 것이 로그 한 줄이니 눈에 띄지 않는다는 뒷부분까지 맞는다. 두 문헌 어디에도 서로를 가리키는 문장은 없다. 그리고 이 고전은 답지가 아니라 잣대다. 1975년에 이미 풀렸다고 적는 쪽으로 가면 지금 이 기본값을 바꿀 수 있는 자리가 어디인지를 놓치게 된다. 그 자리는 두 줄짜리 실패 처리기 안에 있다.
설치 전에 뽑아 볼 수 있는 두 줄
지금까지는 적재된 뒤의 이야기였다. 적재 전에 할 수 있는 일도 문서에 있다. 설치하려는 플러그인 폴더에 검증 명령을 돌리면 그 코드가 무엇을 받고 무엇을 부르는지가 두 줄로 나온다. 받는 이벤트를 적는 줄과, 부르는 API 메서드를 적는 줄이다.
❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane}
❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open
조직 관리 문서에 실린 출력 예시를 그대로 옮겼다. 환경변수를 읽거나 쓰는 모듈에는 그 변수 이름을 적는 줄이, 상태 저장을 쓰는 모듈에는 그 항목을 적는 줄이 조건부로 더 붙는다. 기본이 두 줄이고 쓰는 기능에 따라 줄이 는다.
5.1두 줄이 알려 주는 것과 안 알려 주는 것
이 장치에는 드문 성질이 하나 붙어 있다. 정적으로 읽히지 않는 방식으로 API를 쓰면 Claude Code가 그 mod의 적재 자체를 거부한다. 목록을 뽑아 주는 데서 그치지 않고 뽑히지 않는 코드를 들여보내지 않는다는 뜻이다. 문서는 어느 줄을 눈여겨봐야 하는지도 표로 적어 둔다. 파일 읽기와 쓰기, 프로그램 실행, 네트워크 요청, 환경변수와 설정 읽기, 프롬프트 제출 같은 것들이다.
안 알려 주는 것도 분명하다. 그 줄은 무엇을 부르는지를 말하지 무엇을 하는지를 말하지 않는다. 특히 프로그램 실행 메서드가 한 줄 들어 있으면 그 한 줄이 사실상 "무엇이든"을 뜻한다. §2에서 본 대로 그렇게 띄운 프로세스는 길목 밖에서 돌고, 권한 규칙도 네트워크 정책도 거기까지 닿지 않는다. 그리고 검토에는 시점이 붙는다. 마켓플레이스 자동 업데이트가 켜져 있으면 내가 읽은 파일이 나중에 디스크에서 바뀔 수 있는데, 그 문제는 이름은 같은데 내용이 바뀌는 플러그인을 다룬 글에서 따로 썼다.
5.2같은 범주의 다른 도구들은 어느 칸을 채웠나
이 능력 선언을 다른 개발도구의 확장 체계와 나란히 놓으면 Mods의 자리가 보인다. 아래 표의 칸은 전부 각 제품의 공식 문서와 마켓플레이스 정책 문서에서 확인했고, 순위를 매기지 않는다. "문서가 없다고 적음"과 "문서가 그 질문을 다루지 않음"은 다른 칸이라 나눠 적었다.
| 도구 | 격리 | 심사 | 서명·게시자 검증 | 능력 선언 | 권한 판정을 뒤집나 |
|---|---|---|---|---|---|
| Claude Code Mods | 없음 (문서가 명시) | 문서에 없음 | 문서에 없음 | 있음 — 두 줄을 뽑고, 못 읽으면 적재 거부 | 조건부로 그렇다 |
| VS Code 확장 | 없음 (문서가 명시) | 있음 — 게시 때 자동 검사 | 있음 — 전수 서명 | 없음 | 문서에 없음 |
| JetBrains 플러그인 | 문서에 별도 없음 | 있음 — 신규와 업데이트 전건을 사람이 본다 | 있음 — 작성자와 마켓플레이스 이중 서명 | 없음 | 문서에 없음 |
| Chrome 확장 | 이 조사에서 확인 못 함 | 있음 — 신규와 업데이트 전건 | 있음 | 있음 — 매니페스트 권한 선언 | 문서에 없음 |
| Gemini CLI 확장 | 있음 — 운영체제 격리 선택지 | 없음 (문서가 명시) | 없음 | 매니페스트는 있으나 능력 선언은 아니다 | 문서에 없음 |
각 제품의 1차 문서로 채웠다. Cursor와 OpenAI Codex 행은 2차 출처로만 확인돼 이 표에서 뺐다. Chrome의 격리 칸도 1차로 확인하지 못해 비워 두었다.
표에서 세 문장이 나온다. 첫째, "격리가 없다"는 Mods만의 특징이 아니다. §2.1에서 본 VS Code 문서가 같은 말을 자기 제품에 대해 적는다. 둘째, 능력 선언 칸을 채운 쪽은 Mods와 Chrome이고, 개발도구 넷만 놓고 보면 Mods 하나다. 심사와 서명이 둘 다 "있음"이 아닌 쪽도 Mods와 Gemini CLI인데, 앞은 문서가 그 질문을 다루지 않아서고 뒤는 문서가 없다고 적어서다. 셋째, 마지막 열에 표시가 붙은 쪽이 하나뿐인데 그 이유는 다른 제품이 못 뒤집어서가 아니다. 그 질문에 명시적으로 답한 문서를 가진 쪽이 Claude Code 하나이고, 그 답이 조건부 긍정이다.
5.3가장 촘촘한 심사도 같은 자리에서 멈췄다
그러면 빈 두 칸을 채우면 되는가. 표에서 그 두 칸이 가장 촘촘한 쪽이 JetBrains다. 신규와 업데이트를 전부 사람이 보고, 작성자와 마켓플레이스가 각각 서명한다. 그 체제에서 2026년 6월에 악성 AI 플러그인 15개가 발견돼 제거됐다. 빼낸 것은 개발자가 설정해 둔 AI 제공자 API 키였고, JetBrains 자신이 왜 못 잡았는지를 공개 글에 적었다.
역사적으로 우리의 플러그인 검증 도구는 전용 데이터 흐름 분석기나 악성코드 스캐너가 아니라 호환성과 API 사용 방식을 보는 검사기로 설계돼 있었다. 플러그인이 쓴 핵심 API들이 따로 떼어 놓고 보면 정상으로 보였기 때문에, 하드코딩된 개별 종단점과 맞춤 TLS 설정이 최초 반입 과정에서 걸러지지 않았다. 원문: "Historically, our Plugin Verifier tool was architected as a compatibility and API-usage checker rather than a dedicated data-flow or anti-malware scanner. Because the core APIs used by the plugins appeared normal in isolation, individual hardcoded endpoints and custom TLS configurations were not flagged during initial ingestion." — JetBrains Platform Blog, 2026-06
이 사례가 이 글에서 하는 일은 하나다. 심사와 서명은 각자 다른 것을 보증하고, 그 보증의 범위는 도구가 무엇을 보도록 만들어졌는지로 정해진다. 통과한 심사가 보증한 것은 호환성과 API 사용 방식이었지 그 코드가 무엇을 하느냐가 아니었다. 그러니 "심사는 소용없다"로 읽으면 틀린다. JetBrains는 같은 글에서 새 검사 층을 배치 중이라고 적는다. 마켓플레이스에 플러그인이 올라 있던 기간과 설치 수는 그 공식 글에 없으므로 이 글도 적지 않는다.
학계 쪽에도 같은 방향의 근거가 있다. 브라우저 확장의 권한 선언 효과를 잰 초기 연구(Felt 외, 2011)는 거의 모든 확장이 설치 시점에 위험 권한을 최소 하나는 요구한다는 사실에서 출발해, 경고가 자주 뜨고 대개 나쁜 결과로 이어지지 않으면 설치 시점의 경고에서 사용자가 얻는 정보가 줄어든다고 적었다. 능력 목록은 목록에 든 항목이 드물 때만 정보를 준다는 뜻이다. 이 논리를 §5.1의 두 줄에 대 보면 질문이 하나 선다. 프로그램 실행 메서드가 쓸 만한 mod 대부분에 들어가게 되면, 그 줄은 경고가 아니라 배경이 된다. 지금은 발표 닷새째라 실제 분포를 잴 자료가 없다. 그래서 이 문단은 예측이 아니다. 다른 생태계에서 같은 장치가 걸어간 길을 옮긴 것이다.
5.4조직이 쓸 수 있는 설정 다섯과 각각이 안 덮는 것
조직이 당장 쥘 수 있는 손잡이는 다섯이다. 전부 공식 문서에 적힌 것이고, 이 글이 새 통제를 발명하지 않는다. 다만 각각이 덮지 않는 칸을 같이 적어야 쓸모가 있다.
다섯이 같은 층에 있지는 않다. 조직 배포분만 적재하게 잠그는 쪽과 거부 규칙을 넘어서게 푸는 쪽은 §3.4의 가드 선택지 둘이라, 가드가 적재되는 기계에서만 뜻이 있다. 나머지 셋은 가드가 없는 기계에서도 쓸 수 있는 대신 mod 하나를 골라 막지 못한다. 설치한 것을 한꺼번에 멈추거나, 어디서 받을 수 있는지를 정하는 데서 그친다.
| 설정 또는 선택지 | 하는 일 | 안 덮는 것 |
|---|---|---|
allowManagedModsOnly | 조직이 배포한 mod와 내장 mod만 적재한다 | 내장 mod. 설정 훅·상태줄·/goal은 그대로 돈다 |
allowModsToOverrideDenyRules | 거부 규칙을 설치한 mod가 넘어설 수 있게 푼다 (기본은 잠김) | 가드가 적재되지 않는 기계. 거기서는 두 선택지 중 어느 것도 적용되지 않는다 |
disableAllHooks | 사용자가 설치한 mod를 모든 세션에서 멈춘다 | 내장 mod. 같이 멈추는 것이 설정 훅과 상태줄이라 대가가 크다 |
--safe-mode | 그 세션 한 번만 설치한 mod 없이 돈다 | 내장 mod. 다른 사용자 설정도 함께 멈춘다 |
| 마켓플레이스 제한 설정 | 어디서 받은 플러그인을 설치할 수 있는지를 정한다 | 적재된 뒤의 동작. mod는 플러그인이라 설치 범위만 정해진다 |
Mods 개요 문서와 조직 관리 문서에서 옮겼다. 같은 문서가 다섯 줄 아래에 공통 단서를 달아 둔다. "이 통제들 가운데 어느 것도 mod를 격리하지 않는다. 당신이 허용한 mod는 그 사용자로서, 그 사용자의 파일·프로세스·네트워크 접근 권한을 가지고 돈다."
기록을 쓰는 층도 같은 권한 안에 있다
지금까지 본 것은 도구 호출과 그 판정이었다. 이벤트 전표에는 다른 줄도 있다. Claude가 읽는 것과 사람에게 남는 것을 다루는 줄들이다. 이 절은 기록이 없다는 이야기가 아니다. 검사하겠다는데 볼 장부가 없는 상황은 그 주제를 다룬 글에서 따로 썼고, 여기서는 반대쪽을 본다. 기록은 남는다. 그 기록을 쓰는 층이 교체 가능하다.
6.1바꿀 수 있는 자리 넷
공식 문서와 공개 타입 선언 양쪽에 다 있는 것만 골라 적는다. 네 자리다. 첫째, 커밋과 풀 리퀘스트에 붙는 귀속 문구를 만드는 이벤트가 있다. Claude가 작업했다는 표시를 어떤 문장으로 적을지가 그 훅의 반환값으로 정해진다. 둘째, 시스템 프롬프트는 이름 붙은 절들로 조립되는데, 그 절 하나하나에 훅이 걸리고 빈 값을 돌려주면 해당 절이 빠진다. 셋째, 다른 세션이나 에이전트에서 도착한 메시지에 훅이 걸리고, 문서가 그 순서를 분명히 적는다. "승인을 받으려고 붙잡혀 있는 메시지도 훅에 먼저 닿으므로, mod는 당신이 아직 승인하지 않은 메시지를 읽을 수 있다." 넷째, 프롬프트를 사용자가 친 말처럼 밀어 넣는 호출이 있다. 보통은 mod가 보냈다는 문장이 앞에 붙는데, 사용자 자신의 말로 보내는 선택지를 쓰면 그 문장이 붙지 않는다.
여기에 공식 문서가 적어 둔 기능이 둘 더 있다. 대화에 남길 각 행을 저장되기 전에 고쳐 쓰는 이벤트와, 분석 기록을 막을 수 있는 이벤트다. 다만 이 둘은 조건을 달아 읽어야 한다. 2026년 10월 6일 기준 공개 저장소의 타입 선언 파일은 판본이 v2.1.277이고, 그 판본에는 두 이벤트가 아직 없다. 문서는 v2.1.289를 기준으로 적혀 있다. 문서가 스스로 그 격차를 예고해 두기도 했다. "깃허브에 있는 사본은 당신이 설치한 Claude Code 판본보다 오래된 것일 수 있다." 그러니 이 둘은 문서에 적힌 기능으로만 다루고, 소스에서 확인했다고 적지 않는다.
6.2가드가 덮는 칸과 안 덮는 칸
§3.3에서 본 가드의 15개 목록을 여기에 대 보면 칸이 갈린다. 귀속 문구와 시스템 프롬프트의 절은 가드가 사용자 티어를 건너뛰게 만드는 쪽에 들어 있다. 조직이 관리하는 지침이 사용자 mod에 고쳐지지 않고 모델에 닿게 하려는 설계다. 반면 세션 계열 이벤트는 가드의 통과 목록에 이름이 올라 있고, 분석 기록 쪽은 가드가 거는 15개에 없어 그대로 지나간다. 그러니 가드가 켜진 기계에서도 세션·에이전트 메시지가 먼저 닿는 자리와 분석 기록 쪽은 열려 있다.
§3.3의 가드 15개 목록을 §6.1·§6.2가 적은 자리에 대 본 결과를 페블러스가 도식으로 옮겼다. 왼쪽 둘은 가드가 사용자 티어의 손이 닿지 않게 막고, 오른쪽 둘—세션·에이전트 메시지와 분석 기록—은 가드가 켜진 기계에서도 그대로 열려 있다.
에이전트 파이프라인에서 감사 기록 노릇을 하는 것이 대화 기록인데, 그 기록을 쓰는 층은 기록되는 대상과 같은 권한 안에 있다. 그래서 기록의 신뢰 조건이 바뀐다. 무엇이 적혔는지가 아니라 적을 때 무엇이 적재돼 있었는지가 먼저 온다. 권한 승인과 감사 추적이 어디에 남는지를 벤더 경계에서 따져 본 앞선 글의 질문이 여기서는 같은 프로세스 안으로 들어온다.
6.3세션 중에 가로채기 층이 하나 더 생긴다
Mods를 만드는 가장 쉬운 길은 Claude에게 부탁하는 것이다. 문서가 안내하는 흐름은 이렇다. 사람이 말로 요청하면 Claude가 세션 아이디로 이름 붙은 폴더 안에 모듈을 쓴다. 첫 파일을 저장할 때 Claude Code가 한 번 묻는다. 이 세션에서 뜨거운 재적재를 켤 것인가. 켜면 그 폴더의 mod들이 턴이 끝날 때 적재되고, 이후 "그것들을 바꾸는 턴이 끝날 때마다 다시 적재된다." 그 답은 세션이 끝날 때까지, 재개한 뒤에도 유효하다.
승인은 세션당 한 번이고 그 뒤의 변경은 턴 단위로 들어간다. 다만 파일 쓰기 자체에는 별도 관문이 있다. 기본 권한 모드와 편집 자동 승인 모드에서는 해당 폴더가 보호 경로라 파일마다 묻는다. 다른 권한 모드에서 어떻게 되는지는 이번 조사에서 1차 문서로 확인하지 못해 적지 않는다. "에이전트가 자기를 다시 프로그래밍한다"는 수사가 문자 그대로 참이 되는 자리가 여기인데, 참이 되는 범위는 그 세션과 그 폴더까지다.
6.4그래서 Mods가 새 위험을 만든 건가
반대 방향의 근거를 같은 무게로 적어야 이 글이 제 몫을 한다. 비교 대상이 "아무것도 없음"이라는 점부터 그렇다. 설정 파일에 적는 기존 훅은 Mods 이전부터 사용자 권한으로 셸 명령을 돌렸고, 무엇을 걸고 무엇을 부르는지 뽑아 주는 명령이 없었다. VS Code 확장에도 능력 선언이 없다. 같은 범주 안에서 정보가 늘어난 쪽은 Mods다. 정적으로 안 읽히면 적재를 거부하는 장치까지 붙어 있다. 그러니 Mods가 늘린 것은 위험의 크기보다 그 위험의 모양과 가시성 쪽일 수 있다.
그 반대쪽도 약하지 않다. §5.3에서 본 대로 능력 목록은 목록에 든 항목이 드물 때만 정보를 주고, 심사와 서명을 다 갖춘 쪽도 거기서 멈췄다. 에이전트 쪽에는 승인 장치 자체를 겨냥한 공격 문헌이 따로 쌓인다. 2026년 1월에 올라온 한 종합 논문은 2021년부터의 연구 78편을 모아 코딩 보조 도구에 대한 프롬프트 주입 기법 42종을 분류하고, 적응형 전략을 쓰면 최신 방어를 상대로도 공격 성공률이 85%를 넘는다고 적는다. 거기 포함된 경로 하나가 이 글의 모양과 정확히 겹친다. 주입된 지시가 편집기 설정 파일에 도구 자동 승인을 켜 버리면, 그 뒤의 모든 도구 호출이 사람 확인 없이 돈다는 것이다. 승인을 끄는 스위치가 에이전트의 쓰기 대상 안에 있다는 뜻이고, 이 글이 그 목록에 한 줄을 더한다. 권한 판정을 대신 답하는 층도 적재 대상 안에 있다.
그래서 이 글이 권하는 것은 장치를 더 쌓자는 말이 아니다. 지금 있는 장치가 어디까지 닿는지 아는 것 하나다. 멈추려면 먼저 보여야 한다는 이야기는 앞선 글에서 다뤘고, 여기서 더해지는 것은 보는 일조차 적재 상태에 달려 있다는 조건이다. 세 줄이면 확인이 끝난다. 내 기계에서 가드가 적재되는 조건을 만족하는가, 설치할 mod의 호출 목록에 프로그램 실행이 있는가, 내가 만든 안전 장치에 실패 처리기가 달려 있는가.
페블러스 관심의 이유
우리가 쓰는 실행 환경이 프로그래밍 가능해졌다
먼저 이해관계를 밝힌다. 페블러스는 Claude Code로 돌아가는 여러 에이전트 파이프라인을 실무에 쓰고 있고, 이 글을 만든 파이프라인도 그중 하나다. 그래서 이 소식은 남의 도구 이야기가 아니다. §1.3의 표가 적어 둔 대로 무인으로 도는 자리에서도 훅은 돈다. 우리처럼 claude -p로 파이프라인을 돌리는 조직이라면, 사람이 화면을 보지 않는 그 자리에도 mod가 붙는다는 뜻이다. DataClinic이 들어온 데이터셋의 상태를 묻고 AI-Ready Data가 학습 전 정리를 다루는 것과 같은 질문을 파이프라인 자신에게 돌리면 이렇게 된다. 이 산출물은 어떤 코드가 적재된 상태에서 만들어졌는가.
기록의 품질은 적재 상태에서 온다
데이터 품질 논의는 보통 값의 결측과 중복과 범위를 다룬다. 이 글이 가리키는 결함은 한 칸 위에 있다. §6.2에서 본 대로 에이전트 파이프라인에서 기록을 쓰는 층과 기록되는 대상이 같은 권한 안에 있다. 그러면 "대화 기록에 이렇게 적혀 있다"는 문장의 신뢰 조건이 달라진다. 그 기록의 품질을 정하는 것은 적힌 내용 앞에 놓인 조건, 곧 적을 때 무엇이 적재돼 있었는지다. 데이터 계보를 설계해 본 사람은 이 모양을 안다. 계보의 신뢰도는 계보를 쓰는 주체가 기록 대상과 얼마나 떨어져 있는지에서 온다. 감사 증거의 요건을 금융 쪽에서 정리한 앞선 글의 기준을 여기에 대면, 지금 대화 기록은 그 독립성 칸이 비어 있다.
오늘 확인할 수 있는 세 가지
이 글을 읽는 조직이 당장 할 수 있는 일이 셋이다. 하나, 내 기계에서 금지 규칙이 버티는 상태인지 본다. 관리 설정이 깔려 있는가, 회사 요금제로 로그인했는가. 둘 다 아니면 §3.2의 점선 칸이 비어 있다. 확인 절차는 한국어 공식 문서에 이미 있다. 세션 안에서 /status를 돌려 설정 출처 줄에 관리 설정 항목이 보이는지 읽으면 된다. 둘, 설치하려는 mod에 검증 명령을 돌려 호출 목록을 본다. 프로그램 실행이 거기 있으면 그 한 줄이 "무엇이든"을 뜻한다. 셋, 안전 장치를 mod로 만들었다면 실패 처리기가 달려 있는지 본다. 없으면 그 장치는 실패할 때 막는 대신 통과시킨다. 셋 다 공식 문서에 적힌 방법이다. 이 글은 새 통제를 발명하지 않고, 이미 있는 통제가 어디까지 닿는지를 한국어로 정리한다.
심사표에 아직 칸이 없는 항목
국내 사정도 같이 적어 둔다. 공개된 자료로 확인되는 국내 AI 도구 도입 심의 항목은 모델 출처의 신뢰성, 학습 데이터 오염 가능성, 프롬프트 주입 취약성, 개인정보 처리 방식 같은 축으로 짜여 있다. 개발도구에 지금 무엇이 적재돼 있는지를 묻는 칸은 거기 없다. 국내 기업이 Claude Code를 관리 설정으로 배포한 공개 사례도 이번 조사에서 찾지 못했다. 없는 것은 없다고 적는다.
지금까지 AI 에이전트 관리 논의는 무엇을 금지할 것인가에 머물렀다. 이 사례가 보여 주는 것은 한 칸 앞이다. 금지를 적는 자리와 그 금지가 적용되는 범위가 다를 수 있다. 페블러스가 할 수 있는 일은 이 구분을 데이터 쪽에서 먼저 한국어로 언어화하는 것이다. 규칙이 있는 것과 규칙이 닿는 것은 다르다는 것, 그리고 그 경계를 확인하는 절차가 이미 공개 문서에 있다는 것. 둘 다 품질 규격으로 옮겨 적을 수 있는 문장이다.
본문의 축자 인용은 Claude Code 공식 문서 열네 쪽과 내장 가드의 공개 소스·설명서·테스트, 공식 예제 저장소의 모듈 세 개, 비교 대상 제품의 공식 문서에서 직접 대조했다. 발표 닷새째라 채택률이나 사용률 수치는 존재하지 않으므로 하나도 쓰지 않았다. 2차 매체가 퍼뜨린 "전환점이라는 평가"는 발화자를 찾지 못해 뺐고, "민감 정보 자동 삭제"는 §2.4에서 바로잡았다. 공격 방법과 우회 절차는 적지 않았고, 인용한 코드는 공식 문서에 이미 실린 예제뿐이다. §1부터 §5까지와 §6.1~6.3은 공식 문서와 공개 소스가 적은 사실이고, §2.3·§3.5·§4.5와 이 절은 그 문서들이 하지 않은 이야기이니 나눠서 읽어 주시기 바란다. 긴 글 읽어 주셔서 감사하다.
참고문헌
이 글의 대상 — 공식 문서와 공개 소스
- 1.Anthropic, Claude Code docs — Mods. overview · admin · events · api · reference · create. 각 쪽 주소 뒤에
.md를 붙이면 마크다운 전문이 그대로 온다. 이벤트 45개·네임스페이스 21개·메서드 80개·한도 표는reference쪽의 v2.1.289 기준 표를 직접 다시 세어 확인했다. - 2.Anthropic, Permissions — 거부·질문·허용 우선순위와 "Extend permissions with hooks" 절의 네 줄. §3.1의 축자가 여기서 나왔다.
- 3.Anthropic, Plugin security — 권한 규칙과 격리가 덮는 대상의 경계. §2.2의 축자.
- 4.Anthropic, 관리형 설정 배포(한국어 공식 문서) — 운영체제별 배포 경로와
/status의 설정 출처 줄로 적용을 확인하는 절차. - 5.내장 가드
sec-default소스 — 설명서,hooks/register.ts(3,643바이트),hooks/policy/,tests/. 거는 이벤트 15개와 부르는 메서드 2개를 등록 파일에서 직접 셌고, 사용자에게 보이는 알림 문구를 소스의 반환 문자열과 대조했다. 가드가 적재되지 않는 경우를 재는 테스트는 이 저장소에 없다. - 6.
mods/types/claude-code.d.ts— 2026년 10월 6일 확인 기준 첫 줄의 판본 문자열이 v2.1.277이다. 문서 기준판(v2.1.289)과 12패치 차이가 나고, §6.1에서 조건을 단 두 이벤트가 이 판본에는 없다. 이 판본 기준으로는 네임스페이스 20개·메서드 78개가 나온다. - 7.공식 예제 mod 저장소 —
blast-radius·token-weather·replay-theater세 모듈의 소스 전문을 읽고 등록 호출과 실패 처리기 유무를 셌다. 저장소 설명이 "있는 그대로, 지원 없이 공유한다"고 밝힌다.
설계 원칙 — 고전과 계보
- 8.Saltzer, J. H., & Schroeder, M. D. (1975). The Protection of Information in Computer Systems. Proceedings of the IEEE 63(9), 1278–1308. 전문 — §4.5의 안전한 기본값 항목 축자를 저자 본인 사이트의 전문에서 확인했다.
- 9.Anderson, J. P. (1972). Computer Security Technology Planning Study, ESD-TR-73-51. 원문 PDF. ⚠️ 원문이 스캔 이미지라 기계 추출에 실패해, §3.5의 세 요건 축자는 그것을 그대로 인용한 미 국방부 평가 기준 문서 Part II §6.1에서 가져왔다.
- 10.Miller, M. S. (2006). Robust Composition: Towards a Unified Approach to Access Control and Concurrency Control. PhD thesis, Johns Hopkins University. 전문 PDF — §2.3의 끼어들기에 의한 권한 감쇠 정의. ⚠️ 정의의 요지까지 확인했고 쪽수 단위 축자는 쓰지 않았다.
- 11.Endo / SES · LavaMoat 공식 문서 · MetaMask, LavaMoat and the Ledger Software Supply Chain Attack · LeastAuthority, MetaMask Plugin System + LavaMoat 감사 보고서 — §2.3의 "언어 층 경계이지 운영체제 경계가 아니다"와 환경변수로 격리 적재를 건너뛴 사례.
- 12.Felt, A. P., Greenberg, A., Chin, E., Hanna, S., & Wagner, D. (2011). The Effectiveness of Application Permissions. USENIX WebApps '11. PDF — §5.3의 경고 피로 논거. ⚠️ PDF 기계 추출에 실패해 축자를 확보하지 못했고, 본문에는 수치 없이 결론 방향만 썼다. 같은 계열로 Kariryaa 외(SOUPS 2021)와 Reeder 외(CHI 2018)가 있으나 표본 수치를 1차로 확인하지 못해 본문에 쓰지 않았다.
- 13.Maloyan, N., & Namiot, D. (2026). Prompt Injection Attacks on Agentic Coding Assistants. arXiv:2601.17548(2026-01-24 제출) — §6.4의 수치는 초록에서 직접 확인했다. 연구 78편 종합, 공격 기법 42종, 적응형 전략의 성공률 85% 초과. 어느 도구를 몇 개 시험했는지는 초록에 없어 적지 않았고, 자동 승인 설정을 켜는 경로는 2차 요약 경유라 수치 없이 서술만 썼다.
비교 대상 제품의 공식 문서
- 14.Microsoft, VS Code — Extension runtime security — §2.1과 §5.2의 축자 "확장 호스트는 VS Code 자신과 같은 권한을 갖는다", 전수 서명과 게시 시 자동 검사.
- 15.JetBrains, Understanding plugin security · Marketplace Approval Guidelines · Plugin Signing.
- 16.JetBrains Platform Blog (2026-06), Marketplace Ecosystem Security Update: Addressing Malicious Third-Party AI Plugins — §5.3의 악성 플러그인 15개와 검증 도구 설계 한계 축자. 마켓플레이스에 있던 기간과 설치 수는 이 공식 글에 없다.
- 17.Google, Chrome Web Store review process · Gemini CLI — Sandboxing과 확장 디렉터리 고지. §5.2의 두 행.
- 18.PostCutoff (2026-10-01), Claude Code Mods — 이 글이 출발점으로 삼은 2차 보도. §2.4에서 바로잡은 예시가 이 기사에 실려 있고, "전환점"이라는 평가는 발화자가 달린 인용이 아니라 매체 자신의 편집 논평이라 본문에서 뺐다.
페블러스 블로그 인접 글
- 19.사람이 미리 쓴 권한 규칙의 한계(§3) · 이름은 같은데 내용이 바뀌는 플러그인(§5.1) · 검사할 기록이 없는 자리(§6) · 권한 승인과 감사 추적의 소재지(§6.2) · 멈추려면 먼저 보여야 한다(§6.4) · 감사 증거의 요건(페블러스 관심의 이유) · 에이전트가 쓰는 부품의 출처 · 실행이 자기 환경보다 오래 살 때 · 에이전트 사이의 권한 위임 · 이름만 무서운 가드레일 · 쓴 쪽과 채점하는 쪽 · 루프를 설계한다는 것