
AI 코딩 에이전트를 위한 보안 계층을 구축했습니다 — LLM 개입 없이 결정하는 방법
요약
AI 코딩 에이전트의 도구 호출 시 발생할 수 있는 보안 위협을 방지하기 위한 오픈 소스 보안 계층 'Belay'를 소개합니다. LLM의 비결정론적 판단 대신 결정론적인 정책 엔진을 사용하여 위험한 명령어를 밀리초 단위로 차단합니다.
핵심 포인트
- AI 에이전트의 도구 호출 시 발생할 수 있는 데이터 유출 및 시스템 파괴 위험 방지
- LLM 기반 감시 방식의 느린 속도와 비결정론적 특성 및 인젝션 취약성 해결
- 로컬 우선 방식의 결정론적 정책 엔진을 통한 신속하고 정확한 보안 검증
- 오픈 소스(AGPL-3.0) 프로젝트 Belay를 통한 에이전트 보안 계층 구축
저는 코딩 에이전트에게 셸(shell) 액세스 권한을 주었고, 대부분의 상황은 훌륭했습니다 — 문제가 발생하기 전까지는 말이죠.
한 세션에서는 형제 디렉토리를 통째로 삭제할 뻔한 명령어를 제안했습니다. 또 다른 세션에서는 "배포를 테스트하기 위해" curl을 통해 .env 파일을 유출하려고 시도했습니다. 일반적인 해결책은 사람이 모든 호출을 승인하는 것이지만, 이틀만 지나도 아무도 실제로 그렇게 하지 않습니다. 또 다른 해결책인 LLM이 LLM을 감시하는 방식은 느리고, 비결정론적(non-deterministic)이며, 그 자체로 인젝션(injectable) 공격에 취약합니다.

저는 지루하지만 정확한 것을 원했습니다. 즉, 도구 호출(tool-call) 경계에서 명백히 위험한 작업을 밀리초 단위로 차단하고, 호출이 진정으로 모호할 때만 저를 방해하는 결정론적인 정책 엔진(deterministic policy engine) 말입니다.
그것이 바로 Belay입니다. 이는 오픈 소스(AGPL-3.0)이며, 로컬 우선(local-first) 방식이고, 사용자의 권한으로 실행됩니다. 여기서는 위협 모델(threat model), 위치, 그리고 모델을 전혀 호출하지 않고 정확히 어떻게 결정을 내리는지에 대해 설명하겠습니다.
위협 모델: 에이전트가 도구 액세스 권한을 가질 때 발생하는 문제
보안 관점에서 AI 코딩 에이전트는 **신뢰할 수 없는 소스로부터 지침을 받아 이를 행동으로 전환하는 권한이 없는 프로세스(unprivileged process)**입니다. 여기서 "신뢰할 수 없는 소스"는 모델 출력(model output)이며, 모델 출력은 컨텍스트 윈도우(context window)에 들어오는 모든 텍스트에 의해 유도됩니다. 물론 사용자의 프롬프트도 포함되지만, 여러분이 연 리포지토리(repo), 에이전트가 가져온 웹 페이지, 읽은 GitHub 이슈, 의존성(dependency)의 README 파일 등도 포함됩니다.
따라서 실패 모드(failure modes)는 생소한 것이 아닙:
따라서 실패 모드(failure modes)는 생소한 것이 아닙:
- Secret 유출(Secret exfiltration) — 에이전트가
~/.aws/credentials나.env파일을 읽어 URL로 전송합니다. - 파괴적 명령어(Destructive commands) — 잘못된 경로에 대한
rm -rf; 실제로는 '정리'가 아닌 것입니다. - 역방향 셸 / C2 외부 통신(Reverse shells / C2 egress) — 승인하지 않은 곳으로의 아웃바운드 연결입니다.
- 프롬프트 주입 → 실행(Prompt injection → action) — 오염된 README 파일에
하나의 설치 프로그램이 사용자가 이미 실행 중인 도구들 — Claude Code, Codex, Cursor, Cline, Roo, Gemini CLI, Goose, Hermes, OpenClaw, opencode — 을 자동으로 감지하여 각 도구에 맞는 방식으로 연결합니다. 이 프로그램은 사용자의 권한으로 실행되며(절대 root 권한이 아님), 외부로 데이터를 전송(phone home)하지 않습니다.
결정 방식 — LLM 없는 결정론적(deterministic) 방식
도구 호출(tool call)이 도착하면, Belay는 컴파일된 규칙 카탈로그(rule catalog)를 기준으로 이를 분류하고 다음 세 가지 판결 중 하나를 반환합니다:
- 허용 (Allow) — 명확하게 안전함. 조용히 실행되며, 프롬프트 피로(prompt fatigue)를 유발하지 않음.
- 거부 (Deny) — 명확하게 위험함 (비밀 정보 유출,
rm -rf, 리버스 셸(reverse shells), 주입 유도 호출 등). 즉시 차단됨. - 질문 (Ask) — 진정으로 모호함. 실행을 일시 중지하고 사람에게 질문함 (자세한 내용은 아래 참조).
가장 중요한 두 가지 속성은 다음과 같습니다:
- 결정 경로에 LLM이 없음. 이는 결정론적 규칙 엔진(deterministic rules engine)입니다. 동일한 입력 → 동일한 판결이 100ms 미만의 매우 빠른 속도로 이루어지므로, 모든 호출을 동기적(synchronously)으로 제어할 수 있습니다.
- 실패 시 차단 (Fail-closed). 평가 오류가 발생하거나, 타임아웃이 발생하거나, 호출을 분류할 수 없는 경우 결과는 허용이 아닌 **거부(deny)**가 됩니다. 안전벨트의 고장 모드는
그러한 경우, Belay의 판결은 **질문(Ask)**입니다. 즉, 에이전트를 일시 중지하고 사용자에게 원터치 **허용(Allow) / 거부(Deny)**를 보냅니다. 단순히 터미널에서만 작동하는 것이 아닙니다: Telegram, Discord, WhatsApp, Matrix, Mattermost, 또는 Slack을 통해서도 전달됩니다. 따라서 키보드에서 떨어져 있는 동안에도 에이전트가 계속 작업하도록 두고, 의도하지 않은 동작을 수행하려 할 때 단순히 "거부"를 누르기만 하면 됩니다. 제때 응답하지 않으면 **자동 거부(auto-denies)**됩니다. 다시 한번 '실패 시 폐쇄(fail-closed)' 원칙을 따르는 것입니다.
논리적으로 추론 가능한 커버리지: OWASP, MITRE, SARIF
규칙이 명시적이기 때문에, 탐지 결과는 막연한 느낌(vibes)이 아닌 프레임워크에 매핑됩니다:
- 규칙들은 OWASP Agentic Security Initiative (ASI) Top 10, OWASP LLM Top 10, 그리고 MITRE ATLAS에 태그되어 있습니다.
- 판결 및 스캔 결과는 SARIF 2.1.0 형식으로 내보내지므로, 이미 CI(지속적 통합)에서 사용 중인 코드 스캐닝 도구에 바로 적용할 수 있습니다.
또한 코드를 설치하기 전에 코드/기술을 검사하는 정적 스캐너, 해시 체인 방식의 (변조 방지) 감사 로그(audit log), 그리고 허니팟 카나리(honeypot canaries)도 제공되지만, 핵심은 도구 호출 경계(tool-call boundary)입니다.
솔직한 한계 — 개선이 필요한 부분
이 도구가 하지 못하는 것을 미리 말씀드리는 것이 나중에 지적받는 것보다 낫다고 생각합니다:
- 이것은 샌드박스(sandbox)가 아니라 정책 계층(policy layer)입니다. 이는 훅(hooks)/프록시(proxy)를 통해 애플리케이션 경계에서 탐지 및 대응을 수행하는 것이지, 커널 수준의 방지책이 아닙니다. 심층 방어(Defense-in-depth)를 위해서는 여전히 하단에 컨테이너나 VM(가상 머신)이 필요합니다.
- 결정론적 규칙(Deterministic rules)은 회피 기술과의 군비 경쟁을 의미합니다. 난독화된 명령 구성(base64-piped-to-sh, 단계적 쓰기, Living-off-the-land 바이너리 활용 등)은 실제 공격 표면입니다. 이 부분에 대한 여러분의 피드백을 진심으로 기다립니다.
- 인간 참여(Human-in-the-loop)는 보안을 UX와 맞바꾸는 측면이 있습니다. "질문(Ask)" 프롬프트가 너무 많으면 사람들은 그냥 클릭해서 넘겨버립니다. 허용/질문/거부의 경계를 조정하는 작업은 계속 진행 중입니다.
사용해 보기
curl -fsSL https://dl.belay.secblok.io/install.sh | bash
또는 데스크톱 앱을 내려받거나 **belay.secblok.io**에서 문서를 확인하세요.
만약 에이전트 (agents)를 무인 상태로 실행하신다면, 특히 다음 두 가지 사항에 대한 여러분의 피드백을 받고 싶습니다. 기본 차단 규칙 (default deny rules)이 실제 워크플로우 (workflows)에 대해 너무 공격적인지, 그리고 제가 놓치고 있는 회피 표면 (evasion surface)은 어디인지에 대한 것입니다. 차단/허용 규칙 (block/allow rules)은 공개되어 있으니, 이에 대해 논쟁하거나, 규칙을 깨뜨려 보거나, 제가 놓친 부분에 대해 풀 리퀘스트 (PR)를 보내주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기