![[심층분석] AI 에이전트에게 보안 감사를 맡긴다면? Cloudflare가 공개한 '6단계 보안 감사 스킬' 뜯어보기](/newsimg/Abpj1RozzLj1EEXr.png)
들어가며: 코드 리뷰를 넘어 보안 감사까지 맡기는 시대
요즘 코딩 에이전트 많이 쓰시죠? Claude Code나 Cursor 같은 도구한테 '이 함수 리팩토링해줘'라고 시키는 건 이제 일상이 됐어요. 그런데 한 걸음 더 나아가서 '이 저장소 전체를 보안 감사해줘'라고 시키면 어떻게 될까요?
솔직히 지금까지는 결과가 그다지 믿음직스럽지 않았어요. 에이전트가 코드를 쓱 훑어보고는 'SQL 인젝션 가능성이 있습니다', 'XSS 취약점이 의심됩니다' 하고 그럴듯한 목록을 뽑아주는데, 막상 확인해보면 절반은 오탐(false positive, 실제로는 문제가 없는데 문제라고 잘못 짚은 것)이고 정작 진짜 위험한 부분은 놓치는 경우가 많았거든요. 게다가 '어디까지 봤고 어디는 안 봤는지'를 알 수가 없어서, 결과를 받아도 '그래서 이제 안전한 거야?'라는 질문에 답을 못 했어요.
Cloudflare가 공개한 security-audit-skill은 바로 이 문제를 정면으로 다룬 프로젝트예요. Cloudflare는 전 세계 인터넷 트래픽의 상당 부분을 처리하는 회사라 보안에 대한 압박이 엄청난데요, 이들은 내부적으로 '취약점 발견 하네스(vulnerability discovery harness)'라는 시스템을 만들어 자기네 코드베이스 전체를 AI로 훑고 있다는 이야기를 '나만의 취약점 하네스 만들기(Build your own vulnerability harness)'라는 글로 공개한 적이 있어요. 이번에 오픈소스로 풀린 스킬은 그 거대한 시스템의 '씨앗'이 된 단일 저장소 버전이에요. 즉, 여러분이 자기 프로젝트 하나에 바로 적용해볼 수 있는 출발점인 거죠.
이 스킬이 뭐냐면: 에이전트를 '보안 감사관'으로 바꾸는 매뉴얼
먼저 '스킬(skill)'이라는 개념부터 짚고 갈게요. 코딩 에이전트에서 스킬이라는 건, 쉽게 말해서 에이전트한테 주는 업무 매뉴얼이에요. SKILL.md 같은 마크다운 파일에 '이런 상황에서는 이렇게 일해라'라는 절차와 원칙을 적어두면, 에이전트가 그걸 읽고 그대로 따라 하는 거예요. 신입사원한테 온보딩 문서를 주는 것과 비슷하죠.
그런데 이 스킬은 그냥 '취약점 찾아봐'라고 한 줄 적어둔 게 아니에요. 여섯 단계로 나뉜 정교한 워크플로가 있고, 각 단계마다 별도의 프롬프트 문서(RECONNAISSANCE.md 등)가 붙어 있어요. 그리고 핵심은 오케스트레이션이에요. 오케스트레이션이라는 건, 쉽게 말해서 하나의 에이전트가 모든 일을 다 하는 게 아니라 지휘자 역할의 '부모 에이전트'가 여러 '자식 에이전트'를 따로따로 띄워서 각자 맡은 일을 시키고 결과를 모으는 방식이에요.
왜 이렇게 나누느냐면, AI 모델에는 '확증 편향' 비슷한 문제가 있거든요. 하나의 에이전트가 취약점을 찾고 같은 에이전트가 '이거 진짜 맞아?'라고 검증하면, 자기가 찾은 걸 부정하기가 어려워요. 사람도 자기가 쓴 코드의 버그를 잘 못 찾잖아요. 그래서 이 스킬은 찾는 에이전트와 검증하는 에이전트를 철저히 분리해요. 검증 에이전트는 앞선 대화 맥락을 전혀 모르는 '깨끗한(fresh)' 상태로 시작해서, 오히려 '이 발견을 반박해보라'는 임무를 받아요.
6단계 워크플로 하나씩 뜯어보기
1단계: 정찰(Reconnaissance) — 지도부터 그린다
보안 감사를 시작하자마자 취약점을 찾으러 뛰어드는 게 아니에요. 먼저 코드베이스의 지도를 그려요. 아키텍처는 어떻게 생겼는지, 신뢰 경계(trust boundary, 믿을 수 있는 영역과 믿을 수 없는 외부 입력이 만나는 지점)는 어디인지, 사용자 입력이 들어오는 입구는 어디인지를 정리해서 architecture.md 파일로 남겨요.
그리고 중요한 게 하나 더 있는데, coverage-ledger.json이라는 '커버리지 장부'를 만들어요. 이게 뭐냐면, '이 코드베이스에서 감사해야 할 단위가 총 몇 개이고 각각 어떤 상태인지'를 기록하는 체크리스트예요. 건물 안전 점검할 때 '1층 전기실, 2층 배관, 옥상 방수' 하고 점검 항목을 미리 다 적어두는 것처럼요. 이 장부가 있어야 나중에 '여기는 봤고 여기는 안 봤다'를 정직하게 말할 수 있어요.
2단계: 커버리지 주도 헌팅 — 장부 기준으로 나눠서 뒤진다
이제 실제로 취약점을 찾는 '헌터(hunter)' 에이전트들이 투입돼요. 헌터들은 커버리지 장부에서 자기 담당 단위를 배정받고 그 영역만 집중적으로 파요. 그리고 자기가 뭘 확인했는지 기록을 남겨요.
여기서 재미있는 건 '커버리지 비평가(coverage critic)'라는 역할이에요. 헌터들이 작업을 마치면 비평가 에이전트가 '너희들 여기 빼먹었잖아'라고 구멍을 찾아내요. 헌터가 '다 봤어요'라고 해도 그 말을 그대로 믿지 않고 교차 검증하는 거죠.
3단계: 후보 검증 — 반박 전문가에게 넘긴다
헌터들이 '이거 취약점 같은데요?' 하고 후보를 올리면, 각 후보는 새로운 검증자(verifier) 에이전트에게 넘어가요. 이 검증자의 임무는 '이 후보가 틀렸다는 걸 증명하라'예요. 실제 코드를 따라가면서 '여기서 입력값이 이미 검증되고 있는데?', '이 경로는 인증 없이는 도달할 수 없는데?' 같은 반론을 찾는 거예요.
법정에서 검사와 변호사가 나뉘어 있는 것과 같은 원리예요. 한 사람이 기소도 하고 변호도 하면 공정한 판단이 나오기 어렵잖아요. 서로 반대 입장에서 다투게 해야 진짜 문제만 남아요.
4단계: 구조화된 출력 — 사람이 아니라 기계가 읽을 수 있게
검증을 거친 결과는 findings.json이라는 파일에 기록돼요. 여기서 각 발견은 세 가지 판정 중 하나를 받아요.
- confirmed(확인됨): 소스 코드에서 문제가 발생하는 경로를 완전히 추적했고, 실제로 어떤 결과가 나오는지 범위가 명확히 관찰된 경우
- needs_validation(검증 필요): 확정하지 못한 '정확한 미해결 사실'이 하나 남아 있는 경우. 이 상태에서는 심각도(severity)를 아예 매기지 않아요
- rejected(기각됨): 검증자가 반박에 성공해서 취약점이 아니라고 판명된 경우
- 비용: 여섯 단계에 걸쳐 에이전트를 여러 개 띄우니 토큰 사용량이 만만치 않아요. 처음엔 작은 모듈 하나로 시험해보고 비용을 가늠하세요.
- 코드 유출: 소스 코드가 외부 AI API로 전송된다는 뜻이에요. 사내 보안 정책상 허용되는지 먼저 확인해야 해요. 금융이나 공공 쪽이라면 특히요.
- 결과 해석: confirmed라고 나와도 최종 판단은 사람이 해야 해요. 이 스킬은 '검증된 후보 목록'을 주는 거지, 보안 담당자를 대체하는 게 아니에요.
- needs_validation을 무시하지 마세요: 심각도가 없다고 넘기면 안 돼요. 오히려 'AI도 확신을 못 한 미묘한 부분'이라서 사람이 봐야 할 가치가 가장 높은 항목이에요.
특히 needs_validation에 심각도를 안 매긴다는 점이 인상적이에요. 보통 보안 도구들은 확실하지 않은 것도 '중간 위험' 같은 딱지를 붙여서 내보내는데, 이 스킬은 '모르는 건 모른다'고 정직하게 표시해요. 그리고 이 JSON은 report-schema.json이라는 스키마(데이터가 어떤 형식을 따라야 하는지 정의한 규칙)로 자동 검사돼요. validate-findings.cjs 스크립트가 형식이 어긋난 기록을 걸러내는 거죠.
5단계: 독립 기록 검증 — 한 번 더 의심한다
4단계에서 정리한 최종 기록을 또다시 새로운 에이전트가 검증해요. '이 기록에 적힌 소스 코드 주장이 실제 코드와 일치하는가?'를 확인하는 거예요. 만약 검증 과정에서 기록이 크게 바뀌면(material replacement), 그 바뀐 기록에 대해 또 다른 독립 검증자가 붙어요. 검증이 검증을 낳는 구조죠. 조금 과하다 싶을 수도 있는데, 보안 보고서에서 잘못된 주장 하나가 팀 전체의 신뢰를 무너뜨릴 수 있다는 걸 생각하면 이해가 돼요.
6단계: 타깃 중립 보고 — 사람이 읽을 보고서
마지막으로 검증된 기록과 커버리지 장부를 바탕으로 세 개의 문서를 만들어요. REPORT.md(요약 보고서), FINDINGS-DETAIL.md(발견 상세), NEEDS-VALIDATION.md(추가 확인이 필요한 항목)예요. '타깃 중립(target-neutral)'이라는 건, 보고서가 특정 프로젝트에 편향되지 않고 어떤 코드베이스에 적용하든 같은 기준으로 작성된다는 뜻이에요.
설계 철학: '많이 찾기'가 아니라 '믿을 수 있게 찾기'
이 스킬의 진짜 가치는 개별 단계보다 전체를 관통하는 철학에 있어요.
첫째, 결정론적 검증을 곳곳에 심어놨어요. AI가 만든 결과물을 AI로만 검사하면 끝이 없잖아요. 그래서 커버리지 장부와 발견 기록은 .cjs 스크립트(Node.js로 실행되는 일반 자바스크립트)로 검사해요. 장부를 만들 때와 갱신할 때마다 validate-coverage-ledger.cjs를 돌리고, 4단계와 5단계 교체 때마다 validate-findings.cjs를 돌려요. AI의 유연함과 기계의 엄격함을 섞은 거죠.
둘째, 누적 실행이 가능해요. 같은 저장소에 여러 번 감사를 돌리면 이전 장부와 발견 기록을 읽어서 '지난번에 못 본 곳'을 우선 타깃으로 잡고, 코드가 바뀐 부분은 다시 검증하고, 바뀌지 않은 부분의 증거는 그대로 가져와요. 다만 오래되거나 미해결인 작업은 절대 '이미 봤음'으로 치지 않아요. CI/CD(코드를 자동으로 빌드하고 배포하는 파이프라인)에 붙여서 정기적으로 돌리기에 딱 맞는 설계예요.
셋째, 안티패턴을 명시했어요. SKILL.md에는 '감사할 때 이렇게 하지 마라'는 목록이 있어요. 에이전트가 빠지기 쉬운 함정, 예를 들면 코드를 실제로 따라가지 않고 패턴만 보고 취약점이라 단정하는 행동을 미리 막는 거예요.
기존 도구와 비교하면 어디쯤일까
정적 분석 도구(SAST) — Semgrep, CodeQL, SonarQube 같은 도구들이에요. 정해진 규칙(rule)으로 코드를 기계적으로 검사하죠. 비유하자면 공항 금속 탐지기예요. 빠르고 일관적이고 저렴하지만, 규칙에 없는 새로운 유형의 문제는 못 잡고 오탐도 많아요. '여기 금속 있음!' 하고 삑삑거리는데 벨트 버클인 경우가 태반이죠.
LLM 단발 리뷰 — 그냥 에이전트한테 '취약점 찾아줘' 하고 시키는 방식이에요. 비유하자면 눈썰미 좋은 경비원 한 명이에요. 맥락을 이해하고 규칙에 없는 문제도 찾지만, 그날 컨디션에 따라 결과가 달라지고, 자기가 뭘 봤는지 기록을 안 남기고, 가끔 없는 걸 봤다고 우기기도 해요.
security-audit-skill — 이건 경비 '팀'이에요. 지도 그리는 사람, 구역별로 순찰하는 사람, 순찰 빠진 곳 지적하는 사람, 신고 들어온 걸 반박해보는 사람, 최종 보고서 검토하는 사람이 다 따로 있어요. 느리고 비싸지만(에이전트를 여러 개 띄우니까 토큰 비용이 꽤 나가요), 결과에 '어디까지 봤는지'와 '왜 이렇게 판단했는지'가 붙어 나와요.
결국 이 셋은 대체 관계가 아니라 보완 관계예요. SAST로 매 커밋마다 빠르게 걸러내고, 이 스킬은 릴리스 전이나 주요 기능 추가 후에 심층 감사용으로 돌리는 게 현실적인 조합이에요.
특히 주목할 부분은 Cloudflare가 이걸 '단일 저장소 출발점'이라고 명시했다는 거예요. 그들의 실제 하네스는 여러 단계에 걸쳐 회사 전체 저장소를 훑는 시스템으로 진화했는데, 그 시작이 이 스킬이었다는 거죠. 앞으로 '에이전트 기반 보안 감사'가 어떤 방향으로 갈지에 대한 힌트이기도 해요.
한국 개발자에게 주는 시사점
당장 써볼 수 있는 시나리오부터 볼게요.
작은 스타트업에서 백엔드 API를 운영하고 있다고 해볼게요. 보안팀은 따로 없고, 외부 모의해킹(펜테스트)은 비용 때문에 1년에 한 번 받을까 말까예요. 이런 팀이라면 이 스킬을 Claude Code 같은 에이전트에 붙여서 주요 릴리스 전에 한 번씩 돌려보는 것만으로도 큰 도움이 돼요. 결과로 나오는 NEEDS-VALIDATION.md는 '사람이 직접 확인해야 할 것' 목록이라서, 외부 감사를 받을 때 '이 부분 집중적으로 봐주세요'라고 넘기기에도 좋아요.
레거시 코드를 물려받은 상황에도 유용해요. 이전 담당자가 퇴사해서 아무도 전체 구조를 모르는 코드가 있다면, 1단계 정찰에서 나오는 architecture.md만으로도 값어치가 있어요. 취약점 발견은 덤이고요.
도입할 때 고려할 점도 있어요.
1. 먼저 저장소를 클론해서 SKILL.md와 각 단계 문서를 그냥 읽어보세요. 코드를 안 돌려도 '보안 감사를 어떤 순서로 어떤 관점에서 해야 하는지'를 배우는 교재로 훌륭해요.
2. 개인 토이 프로젝트에 한 번 돌려보고, 생성되는 architecture.md, coverage-ledger.json, findings.json을 열어보세요. 구조를 이해하는 게 목적이에요.
3. report-schema.json을 읽어보세요. '좋은 보안 발견 기록에는 어떤 필드가 있어야 하는가'에 대한 Cloudflare의 답이 담겨 있어요.
4. 익숙해지면 팀 프로젝트에 적용하고, 두 번째 실행에서 누적 기능이 어떻게 작동하는지 관찰해보세요.
마무리: 에이전트에게 '책임'을 요구하는 시대
이 스킬이 던지는 메시지는 단순해요. AI 에이전트한테 일을 시킬 때 '결과물만 내놔'가 아니라 '네가 뭘 봤고, 뭘 안 봤고, 왜 그렇게 판단했는지 증거를 남겨라'고 요구해야 한다는 거예요. 이건 보안 감사뿐 아니라 코드 리뷰, 테스트 작성, 문서화 같은 다른 에이전트 워크플로에도 그대로 적용할 수 있는 원칙이에요.
앞으로는 이런 '검증 가능한 에이전트 워크플로'가 표준이 될 가능성이 높아요. 에이전트 하나가 뚝딱 만들어내는 시대에서, 여러 에이전트가 서로를 견제하며 증거를 쌓는 시대로 넘어가는 거죠. 그리고 그 결과물은 사람이 읽는 보고서가 아니라 기계가 읽고 다음 파이프라인으로 넘길 수 있는 구조화된 데이터가 되고요.
여러분은 어떠세요? 코딩 에이전트한테 보안 검토를 맡겨본 경험이 있으신가요? 결과를 얼마나 신뢰하셨나요? 그리고 여러분 팀이라면, 토큰 비용을 감수하고 이런 다단계 감사를 돌릴 만한 가치가 있다고 보시나요? 댓글로 경험 나눠주세요.
🔗 출처: GitHub