AI 코딩 에이전트를 팀에 붙이는 순간, 보안 문제는 '나중에 챙길 일'이 아니라 '지금 설계할 일'이 된다. 그런데 현장을 보면 여전히 세 곳이 뚫려 있다. MCP 서버가 주는 과잉 권한, 배포 직전에야 발견되는 코드 취약점, 그리고 AI 채팅창에 붙여넣은 API 키. 세 가지는 서로 다른 레이어에서 터지는 문제다. 따로따로 설계해야 한다.
1층: MCP 권한—'Stripe 붙였더니 환불 권한도 따라왔다'
PolicyLayer가 Stripe, GitHub, Supabase, Cloudflare 등 주요 플랫폼의 공식 .mcp.json 설정 파일을 스캔한 결과는 불편하다. Stripe MCP는 27개 도구 중 9개가 금융·파괴적 작업(create_refund, cancel_subscription)이고, GitHub MCP는 83개 도구 중 53개가 쓰기 혹은 삭제 권한(delete_file, create_branch)을 포함한다. Supabase는 reset_branch, deploy_edge_function이 아무 제약 없이 열려 있다. 공통점은 하나다. 최소 권한 원칙(least privilege)이 존재하지 않는다. 도구가 서버에 등록돼 있으면 에이전트는 그걸 전부 호출할 수 있다.
팀이 실수하는 지점이 여기다. 'Stripe 연동'을 원해서 MCP를 추가했는데, cancel_subscription이 보너스로 딸려 온다는 걸 아무도 확인하지 않는다. MCP 프로토콜 자체에 권한 스코프나 정책 개념이 없으니, 제어는 전적으로 팀의 설계에 달렸다. 당장 할 수 있는 것은 두 가지다. npx policylayer로 현재 설정의 위험 도구 목록을 확인하고, CI 파이프라인에 MCP 보안 스캔 액션을 추가해 PR마다 설정 변경을 자동 감사하는 것. 비용은 없다. 안 하는 이유도 없다.
2층: 코드 취약점—배포 전 OWASP 감사를 에이전트에게 위임하라
보안 리뷰가 프로젝트 막바지에 몰리는 이유는 습관이 아니라 구조 문제다. 코드를 쓰는 시점과 검토하는 시점이 분리돼 있으면, 발견된 취약점을 고치는 비용이 기하급수적으로 올라간다. Claude Code 커스텀 커맨드(/review-security)는 이 구조를 바꾸는 실용적인 접근이다. .claude/commands/review-security.md에 OWASP 기반 프롬프트를 심어두면, 파일을 저장하는 순간 SQL Injection(CWE-89), XSS, 민감 데이터 노출(CWE-312) 등을 실시간으로 잡아낼 수 있다.
이 접근의 핵심은 프롬프트 설계에 있다. '거짓 양성(false positive)을 보고하지 말라'는 지시를 명시적으로 넣어야 한다. 이 한 줄이 없으면 에이전트는 이론적 가능성만 있는 경고를 쏟아내고, 팀은 결국 그 출력을 무시하게 된다. 실제 사용 사례에서는 두 개의 실제 취약점(SQL Injection, 패스워드 해시 노출)이 노이즈 없이 검출됐다. AI가 생성한 코드를 AI가 감사하는 구조—이 루프를 파이프라인에 공식화하는 것 자체가 설계 결정이다.
3층: 시크릿 관리—채팅창에 붙여넣은 API 키는 이미 유출이다
AI 코딩 세션이 실제 작업을 하려면 진짜 시크릿이 필요하다. OPENAI_API_KEY, DB URL, Stripe 키. 가장 저항이 적은 경로는 그냥 채팅창에 붙여넣는 것이다. 그러면 그 값은 대화 기록에 남고, 어쩌면 로그에 남고, 클라우드에 동기화된다. 세션이 쌓일수록 시크릿은 사방에 흩어진다.
Envkeep은 이 문제를 구조적으로 해결한다. 사람은 GUI로 시크릿을 관리하고, 에이전트는 CLI(envkeep get my-app/OPENAI_API_KEY)로 한 번에 하나씩 필요한 값만 가져간다. 평문이 채팅창을 통과하지 않는다. 저장소는 age 암호화(X25519 + ChaCha20-Poly1305) 기반 vault로, git에 올려도 암호문만 노출된다. Touch ID 게이트, TOTP 2FA, 클립보드 자동 초기화, 감사 로그까지 지원한다. 다만 개발자 스스로 설계 한계를 솔직하게 인정한다. HashiCorp Vault나 HSM의 대체재가 아니며, 에이전트가 CLI를 실행할 수 있다면 에이전트가 가리키는 시크릿은 읽힌다. 목표는 시크릿이 채팅·.env·커밋으로 흘러 다니는 것을 막는 것이다.
세 레이어를 순서대로 쌓아야 하는 이유
세 문제는 독립적으로 보이지만 실제로는 연결돼 있다. MCP 권한이 방치된 상태에서 코드 취약점까지 있으면, 에이전트가 잘못된 판단으로 운영 DB를 날릴 수 있다. 코드 감사가 없는 상태에서 시크릿이 유출되면, 유출된 키로 어떤 API가 호출됐는지 추적조차 못 한다. 각 레이어는 독립적으로 작동하지만, 하나가 빠지면 다른 두 개의 효과도 반감된다.
팀 입장에서 지금 당장 실행 가능한 시작점은 명확하다. npx policylayer로 현재 MCP 설정을 스캔하고, Claude Code에 /review-security 커맨드를 심고, 에이전트가 사용하는 시크릿을 채팅창 밖으로 꺼내는 것. 세 작업 모두 오늘 오후 안에 끝낼 수 있다. AI 코딩 에이전트를 팀에 위임하기로 결정했다면, 보안 설계는 그 결정과 동시에 내려야 할 또 다른 결정이다.