


샌드박스에서 보안 취약점을 찾아 고치는 AI 파이프라인 운영하기
신뢰할 수 없는 코드를 실제로 실행해 크래시를 찾는 자율 파이프라인을 운영할 때 사용하세요. 실행을 컨테이너에 격리하고, 발견 결과를 나오는 즉시 알리며, 모든 패치는 사람의 검토에 맡깁니다.
이 AI 규칙을 사용하려면
## 읽기 전용 작업은 분석 스킬로, 코드 실행은 샌드박스로 보내기
이런 종류의 시스템에는 서로 다른 두 가지 표면이 있으므로, 사용자를 올바른 쪽으로 안내해야 한다.
- 대화형 분석 스킬은 저장소의 파일을 읽고 쓰며 현재 세션 안에서 실행된다. 대상 코드를 직접 실행하는 일은 없다. 범위 설정, 위협 모델링, 정적 취약점 검토, 기존 발견 목록의 분류, 후보 패치 초안 작성, 파이프라인을 다른 스택으로 이식하는 작업에 이 표면을 사용한다. 질문이나 읽기 전용 작업은 모두 이쪽으로 보낸다.
- 자율 파이프라인은 대상을 실제로 실행해 크래시를 찾고 검증한다. 공격자의 영향을 받는 신뢰할 수 없는 코드를 실행하는 만큼, 계측된 빌드를 대상으로 반드시 샌드박스 안에서 돌려야 한다. 사용자가 정적인 의견이 아니라 실행으로 검증된 실제 결과를 원할 때만 이쪽으로 보낸다.
두 표면을 명확히 구분한다. 읽기/쓰기 표면은 코드에 대해 추론하고, 실행 표면은 코드를 실제로 돌린다. 하나는 판단 근거를 제공하고, 다른 하나는 증거를 만든다. 실행 쪽의 산출물은 재현 가능한 입력 파일이지 산문이 아니다.
## 작은 시험 실행으로 시작하고 전체 실행은 백그라운드에서 돌리기
파이프라인은 던져놓고 잊어버리는 일괄 작업이 아니라 실시간 대시보드처럼 운영한다.
- 먼저 사용자와 함께 대화형으로 정찰 과정을 진행한다. 발견된 주요 영역을 보여주고, 무엇이든 실행되기 전에 사용자가 분할 구성을 조정할 수 있게 한다.
- 새 대상을 처음 실행할 때는 소규모 웨이브(적은 수의 병렬 실행, 낮은 턴 한도)로 먼저 돌려서, 본격적으로 규모를 키우기 전에 사용자가 토큰 소모량과 프롬프트 보정 감각을 익히게 한다. 뭔가 이상해 보이면 함께 트랜스크립트를 살펴본다.
- 그다음 더 큰 규모의 실행을 백그라운드에서 시작해, 막힘없이 로그를 추적하고 발견 사항이 쌓이는 것을 지켜보며 질문에 답할 수 있게 한다. 검증된 결과가 나올 때마다 전체 배치가 끝나길 기다리지 않고 그때그때 짧은 요약과 함께 바로 알려준다.
첫 검증된 발견은 보통 몇 시간이 아니라 몇 분 안에 나온다. 느린 러너 하나가 늦어져도 그 자신만 늦어질 뿐 전체 배치를 막지 않는다.
## 실행이 멈춰도 잃지 않도록 트랜스크립트를 바로바로 디스크에 쓰기
모든 실행에는 항상 켜져 있는 두 가지 관측 계층을 둔다.
- 일정 턴마다 찍히는 하트비트는 긴 침묵 구간에도 프로세스가 여전히 살아 있음을 보여준다.
- 액션별 진행 라인은 각 에이전트가 무엇을 하고 있는지, 도구 호출 하나 또는 텍스트 블록 하나당 한 줄씩 보여준다.
모든 에이전트 트랜스크립트는 메시지가 도착하는 즉시 디스크에 스트리밍하고, 그때그때 확실히 플러시한다. 중요한 내용을 메모리에만 버퍼링해 두지 않으므로, 실행 도중 강제 종료되더라도 나중에 확인할 수 있는 완전하고 읽기 가능한 트랜스크립트가 남는다.
사용자가 상태를 물으면 디스크에 남은 산출물을 근거로 답한다: 아직 살아 있는 발견 건수, 채점이 끝난 건수, 작성된 리포트 수를 센 다음 가장 최신 것을 보여준다. 각 결과는 자신이 속한 실행이 끝나는 순간 바로 기록되므로, 뒤처지는 하나가 나머지의 반영을 막는 일은 없다.
## 레이트 리밋에 걸린 에이전트를 멈춘 지점부터 다시 이어 가기
일시적인 용량 초과 오류가 실행을 죽이게 두면 안 된다. 긴 작업이 순간적인 폭주를 버텨낼 수 있도록 복구 사다리를 구축한다.
- 각 에이전트는 하나의 장기 세션으로 동작한다. 실행 도중 발생한 레이트 리밋이나 서버 오류는 먼저 에이전트 자체 클라이언트 안에서 재시도된다.
- 그래도 실패하면 오케스트레이터가 백오프(상한을 둔 지수 백오프)를 적용한 뒤, 해당 세션을 이어서 에이전트를 재실행한다. 이렇게 하면 전체 대화 맥락이 복원되고, 실패했던 바로 그 턴부터 이어서 진행된다.
- 에이전트당 재실행 횟수에 상한을 둬서, 정말로 막혀버린 에이전트는 결국 멈추게 한다.
사용자에게는 프로비저닝된 용량에 가깝게 실행해도 괜찮으며, 순간적인 폭주는 백오프가 흡수해 주니 작업 손실을 피하려고 스스로 속도를 늦출 필요가 없다고 알려준다. 단 한 가지 예외는 턴 소진 오류다. 이는 종결 오류로 간주해 의도적으로 재실행하지 않는다. 재실행하면 턴 한도가 배가되기 때문이며, 이 경우에는 한도를 올려서 다시 돌려야 한다. 에이전트가 한도에 걸리기 전에 이미 제출한 발견은 실행이 중단되더라도 버려지지 않고 그대로 구제되어 채점된다.
## 새 버그는 자동으로 보고서를 쓰고 네트워크를 쓰기 전에 묻기
스트리밍 모드에서는 보고가 자동으로 이루어진다. 각 크래시가 채점을 통과하면, 판정 에이전트가 이를 새로운 버그인지, 이미 알려진 버그의 더 깔끔한 대표 사례인지, 아니면 건너뛸 중복인지 판단한다. 새로운 버그로 판정되면 배치가 끝나길 기다리지 않고 즉시 리포트 에이전트가 실행된다. 별도의 일괄 리포트 경로도 복구용이나 스트리밍 없이 산출된 결과를 위해 계속 사용할 수 있다.
각 리포트는 구조화된 익스플로잇 가능성 분석이다. 해당 프리미티브가 어떻게 동작하는지, 실제 공격 표면에서 도달 가능한지, 어떤 확대 경로를 거치는지, 어떤 제약이 있는지를 다루며, 여기에 에이전트가 판단한 심각도가 더해진다. 별도의 채점 에이전트가 키워드 스캔이 아니라 의미 기반 루브릭에 맞춰 리포트 점수를 매긴다.
외부 네트워크에 접근하는 단계를 켜기 전에는 반드시 먼저 사용자에게 물어본다. 예를 들어 대상의 업스트림 저장소를 클론해 해당 버그가 이미 수정됐는지 확인하는 참신성 검사 같은 기능이 그렇다. 이런 기능은 기본적으로 꺼둔다. 에어갭 환경이나 아웃바운드가 제한된 환경에서는 파이프라인이 외부로 나가는 것을 원치 않기 때문이다. 네트워크에 접근하는 것은 오직 오케스트레이터 호스트뿐이며, 에이전트 컨테이너는 어느 경우에도 모델 엔드포인트로만 접근이 제한된다.
## 크래시가 사라졌는지 확인하고 패치 채택은 사람에게 맡기기
패치 단계는 리포트 이후에 이어서 실행할 수도 있고, 단독으로 실행할 수도 있다. 고유한 크래시마다 새로 격리된 컨테이너 안의 패치 에이전트가 수정안을 작성해 diff를 내놓고, 별도의 채점 컨테이너가 검증 사다리를 밟는다.
- diff를 적용하고 다시 빌드한다.
- 원래의 재현 입력이 더는 크래시를 일으키지 않는지 확인한다.
- 대상 자체의 테스트 스위트가 여전히 통과하는지 확인한다.
- 새로 시간 제한을 둔 탐색 에이전트로 패치된 바이너리를 다시 공격해 본다.
어느 단계에서든 검증에 실패하면 그 증거를 패치 에이전트에 되돌려주고, 정해진 횟수만큼 반복 시도하게 한다. 마지막 단계로 선택적인 자문 성격의 리뷰를 추가할 수도 있다.
이 과정이 무엇을 증명하는지 사용자에게 분명히 밝혀야 한다. 이 사다리는 크래시가 사라졌음을 검증할 뿐, 그 diff를 상위 프로젝트에 반영해도 안전하다는 것을 검증하지는 않는다. diff는 사람의 검토를 위해 드러내고, 리뷰 가이드를 함께 안내한다. 파이프라인 자체의 컨테이너 밖 어디에도 diff를 대신 적용해 주겠다고 제안하지 않는다. 생성된 수정안은 사람이 승인해야 할 제안일 뿐, 자동으로 반영될 변경 사항이 아니다.
## 중복 크래시는 글자가 아니라 원인으로 에이전트가 판단하게 하기
크래시 중복 제거는 문자열 매칭이 아니라 두 단계에 걸친 에이전트 판단으로 이루어진다.
- 제출 시점에 탐색 에이전트는 이미 공유 발견 파일에 기록된 것과 왜 다른 크래시인지에 대한 자기 나름의 근거를 반드시 함께 첨부해야 한다. 이 근거가 빠진 제출은 파이프라인이 거부한다. 판단은 근본 원인을 아는 에이전트가 내리고, 파이프라인은 그 판단이 실제로 이루어졌는지만 강제한다. 정확한 텍스트 대조가 아니라 원시 새니타이저 발췌문을 의미 기준으로 비교한다.
- 리포트 게이트 단계에서는 판정 에이전트가 채점이 끝난 각 크래시를 현재의 리포트 명세와 대조해, 새로운 것인지, 더 깔끔한 중복인지, 건너뛸 것인지 판단한다. 같은 근본 원인이 다른 줄이나 다른 프레임에서 나타나도 여전히 중복으로 처리된다. 더 깔끔한 중복은 재리포트를 유발하며, 이어지는 비교 단계에서 대표 사례를 하나 선정한다.
알려진 버그를 기록할 때는 줄 번호가 아니라 함수 이름을 키로 삼는다. 같은 버그라도 입력에 따라 인접한 줄에서, 혹은 다른 종류의 새니타이저로 크래시가 발생할 수 있기 때문이다.
## 발견과 채점을 제한을 건 별도의 컨테이너에서 실행하기
격리 모델이야말로 실행으로 검증된 결과를 신뢰할 수 있게 만드는 근간이다. 이를 타협 불가능한 전제로 다뤄야 한다.
- 탐색과 채점은 같은 이미지에서 빌드된 별도의 컨테이너에서 실행한다. 이 둘 사이를 오가는 것은 오직 개념 증명(PoC) 바이트뿐이다. 탐색 쪽은 채점 쪽을 절대 건드리지 않으며, 이렇게 함으로써 미리 심어둔 상태를 이용한 보상 해킹을 원천 차단한다.
- 각 에이전트는 강화된 런타임을 갖춘 자기 컨테이너 안에서 실행되며, 아웃바운드 접근은 설정된 허용 목록으로만 제한된다. 이는 호스트가 아니라 샌드박스 안에서 이루어진다. 파일 및 셸 도구도 그 컨테이너 안으로만 국한된다.
- 에이전트를 생성하는 명령은 명시적인 위험 감수 오버라이드를 전달하지 않는 한 샌드박스 밖에서는 시작을 거부한다.
- 에이전트가 쓸 수 있는 도구 세트는 고정되어 있고 최소한이다. 실행을 담당하는 에이전트는 읽기, 쓰기, 셸만 가지며, 판정 에이전트와 비교 에이전트는 아무 도구도 갖지 않고 단일 프롬프트 호출 안에서 모든 것을 처리한다. 플러그인 도구도, 웹 접근도 없다.
## 시작을 망가뜨리는 설정을 피하고 대상은 코드 변경 없이 추가하기
미리 알아두면 좋을, 깨지기 쉬운 몇 가지 운영상의 세부 사항이 있다.
- 일부 환경 설정은 핵심 전제 조건이다. 하나는 컨테이너 내부 도구의 중첩 세션 가드를 해제하고, 다른 하나는 샌드박스 안에서 권한 우회 모드를 허용한다. 둘 중 하나라도 제거하면 에이전트 기동이 깨진다.
- "사용 가능한 도구 세트를 제한한다"와 "권한 허용 목록"은 구분해야 한다. CLI가 두 플래그를 모두 받아들이더라도 의미가 다르므로, 허용 여부가 아니라 실제로 존재하는 도구 자체를 좁히는 쪽을 사용한다.
- 어떤 모델을 쓸지는 정적 설정이 아니라 런타임 인자이므로, 같은 타겟 정의를 어떤 모델로도 구동할 수 있다.
- 새니타이저가 계측된 파서는 no-inline 속성이 필요할 수 있다. 그렇지 않으면 컴파일러의 인라인화가 크래시 시그니처를 바꿔버릴 수 있다.
새 타겟을 추가하는 일은 빌드 정의와 새니타이저 설정을 담은 디렉터리를 그대로 끼워 넣는 것으로 끝나며, 파이프라인 코드는 전혀 바꾸지 않는다. 태그·출력 파싱, 아티팩트 직렬화, 시그니처 추출, 중복 제거, 패치-채점 사다리 같은 핵심 동작은 단위 테스트로 커버하고, 엔드투엔드 스모크 경로로 빠르게 도는 픽스처 타겟 하나를 항상 유지한다.
## 정답이 보이지 않는 컨테이너에서 로그 속 공격자의 흔적 찾기
침해 사후 대응 버전은 문제 자체를 뒤집는다. 공격자는 이미 로그 안에 있고, 할 일은 바이너리를 크래시시키는 것이 아니라 그들의 캠페인을 찾아내는 것이다.
- 로그 코퍼스는 무엇이든 실행되기 전에 먼저 생성해 둬야 한다. 규모가 크고 시드마다 결정적으로 정해지므로, 같은 시드는 같은 머신에서 같은 증거를 재현한다.
- 헌트 에이전트는 애플리케이션 소스와 읽기 전용 로그를 받아 자신의 침해 조사 결과를 제출한다. 구조상 그 컨테이너 안에는 정답지가 존재하지 않는다.
- 새 컨테이너 안의 채점 에이전트가 제출물을 채점하고, 확인된 개념 증명(PoC)을 모두 독립적으로 다시 실행해 본다. 경계를 넘어오는 것은 오직 제출물뿐이다.
평가의 무결성을 지킨다. 정답 파일, 채점기, 로그 생성기 소스는 모두 스포일러다. 헌트 쪽에는 절대 마운트하거나 읽게 해서는 안 된다. 크래시 파이프라인과 동일하게 대화형으로 시작해 자율 실행으로 넘어가는 형태를 여기서도 그대로 따른다.
