← 블로그로 돌아가기

AI 에이전트 보안은 왜 차단보다 사건 리플레이로 검증해야 하는가

AI 에이전트가 도구를 호출하고 결과를 관찰하며 다시 행동하는 시대에는 성공 여부만으로 실행을 설명하기 어렵다. 무엇을 했는지, 어디서 실패했는지, 어떤 경계를 넘었는지를 다시 재생할 수 있어야 보안과 품질을 함께 검증할 수 있다.

TL;DR

  • 에이전트의 기본 단위는 한 번의 답변이 아니라 컨텍스트·추론·도구 실행·관찰을 반복하는 루프다.
  • 보안 사고는 “차단됐다”는 결과보다 어떤 명령과 권한이 어떤 순서로 실행됐는지 재생할 수 있을 때 더 잘 검증된다.
  • 로그가 사건의 존재를 남긴다면, 리플레이는 사건의 순서와 분기를 사람이 다시 따라가게 한다.
  • 작은 팀도 로컬 실행 로그를 타임라인으로 보여주는 리플레이 유틸부터 시작할 수 있다.

왜 지금 중요한가

에이전트는 이제 텍스트만 생성하지 않는다. 저장소를 읽고 파일을 바꾸며, 외부 도구를 호출하고, 실패 결과를 보고 다음 행동을 고른다. Oracle은 이 구조를 컨텍스트 조립, 모델 추론, 행동, 관찰이 반복되는 agent loop로 설명한다.

따라서 에이전트의 사고도 한 번의 출력이 아니라 연쇄 실행으로 발생한다. “위험한 요청을 막았는가”만 확인하면 재시도, 우회 호출, 권한 상승, 예상 밖 파일 접근을 놓칠 수 있다.

보안의 질문은 이제 두 가지가 됐다.

  1. 위험한 행동을 실행 전에 막았는가?
  2. 막지 못했거나 우회됐을 때, 실제 경로를 다시 검증할 수 있는가?

두 번째 질문에 답하려면 차단 로그보다 풍부한 실행 증거가 필요하다.

핵심 흐름

에이전트의 실제 제품은 루프다

사용자는 최종 답변만 보지만 시스템은 그 전에 여러 단계를 거친다.

요청
  → 컨텍스트 조립
  → 모델 판단
  → 도구 호출
  → 결과 관찰
  → 재시도 또는 종료

이 중 한 단계가 잘못되어도 마지막 문장이 그럴듯하면 문제는 숨겨진다. 품질 검증은 마지막 답변의 문장 평가와 실행 루프의 경로 평가를 분리해야 한다.

로그와 리플레이는 다르다

로그는 사건이 일어났다는 사실을 남긴다. 리플레이는 사건의 순서와 분기, 재시도, 종료 이유를 사람이 다시 따라가게 한다.

좋은 리플레이에는 최소한 다음이 보여야 한다.

  • 작업별 실행 신원
  • 모델이 선택한 도구와 입력
  • 접근한 파일·네트워크·비밀의 범위
  • 실패와 재시도 횟수
  • 최종 종료 조건과 미완료 항목

여기서 리플레이는 공격을 다시 실행한다는 뜻이 아니다. 저장된 사건 타임라인을 안전한 읽기 전용 화면에서 재생해 판단을 검증한다는 뜻이다.

보안 사건은 타임라인으로 이해된다

Hugging Face의 침해 기술 타임라인은 공격 경로를 단계별 인터랙티브 리플레이로 보여준다. 사건을 한 문단으로 요약하는 대신 초기 접근, 경계 이동, 명령 실행, 조사 단계를 시간축으로 나누면 어디서 통제가 실패했는지가 분명해진다.

이 방식은 에이전트 보안에도 적용된다. “샌드박스가 있었다”는 선언보다 샌드박스 안에서 어떤 신원으로 어떤 리소스에 접근했고, 실패 후 어디로 이동했는지를 확인하는 편이 재현 가능한 증거에 가깝다.

실제 사례 / 신호

Oracle의 agent loop 설명과 Hugging Face의 침해 리플레이는 서로 다른 글이지만 같은 설계 결론으로 이어진다. 에이전트는 단일 호출이 아니라 관찰과 행동의 연쇄이며, 복잡한 연쇄는 최종 결과가 아니라 경로를 검증해야 한다.

Microsoft의 Flint는 데이터의 의미 타입을 구조화해 시각화 설정을 자동화한다. 실행 이벤트도 마찬가지다. 단순한 문자열 로그보다 tool_call, secret_access, network_request, retry, stop_reason처럼 의미가 있는 이벤트 타입을 남겨야 리플레이와 자동 검사가 가능하다.

이 신호들을 합치면 실행 증거의 최소 조건이 나온다.

무엇이 일어났는지를 남기는 것에서, 왜 그렇게 됐는지를 다시 따라가는 것으로 이동해야 한다.

실전 활용 팁: 실행 리플레이 최소 스키마 만들기

에이전트 작업 하나를 다음 JSON 형태로 기록해본다.

{
  "run_id": "local-demo-001",
  "events": [
    {"type": "tool_call", "tool": "read_file", "target": "README.md"},
    {"type": "retry", "reason": "test_failed"},
    {"type": "stop", "reason": "verification_passed"}
  ]
}

처음부터 완전한 보안 관측성 플랫폼을 만들 필요는 없다. 이벤트 타입 세 가지와 시간순 타임라인, 위험 이벤트 강조 표시만 있어도 최종 답변만 볼 때 발견하지 못한 문제를 찾을 수 있다.

다음 원칙을 적용하면 된다.

  • 신원을 고정한다. 한 실행마다 run ID와 작업 주체를 붙인다.
  • 의미 타입을 남긴다. 문자열 한 줄 대신 도구 호출, 네트워크 접근, 재시도, 종료 이유를 구분한다.
  • 경계를 표시한다. 파일·네트워크·비밀 접근은 값이 아니라 범위와 정책 판정 중심으로 기록한다.
  • 종료를 기록한다. 성공뿐 아니라 중단, 미완료, 검증 실패를 별도 상태로 남긴다.

바로 해볼 실험

1~3일 안에 다음 실험을 진행한다.

  1. 파일 읽기·테스트 실행·재시도·종료가 있는 에이전트 작업을 하나 고른다.
  2. 도구 호출과 결과를 로컬 JSON 이벤트로 저장한다.
  3. 이벤트를 시간순으로 재생하는 단일 HTML 화면을 만든다.
  4. 예상하지 못한 호출, 권한 범위, 종료 이유를 표시한다.
  5. 리플레이 전후에 사람이 판단한 위험 항목의 차이를 기록한다.

성공 기준은 보안 사고를 완벽히 예방하는 것이 아니다. 사용자가 최종 답변만 읽었을 때 놓친 실행 경로를 리플레이에서 하나 이상 발견하면 첫 번째 신호다.

리스크 / 반론

리플레이는 예방 통제를 대체하지 않는다. 최소 권한, 샌드박스, 짧은 수명 자격증명, 네트워크 제한이 먼저 필요하다. 리플레이는 그 통제가 실제로 작동했는지와 실패했을 때 어디까지 번졌는지를 확인하는 층이다.

또한 모든 이벤트를 무제한 저장하면 개인정보와 비밀이 로그에 복제될 수 있다. 비밀 값은 마스킹하고, 로컬 보관 기간과 공유 권한을 분리해야 한다. 사건 타임라인을 만든다는 이유로 공격 명령이나 민감한 자격증명을 그대로 재현해서는 안 된다.

리플레이 화면이 너무 복잡해져 운영자가 읽지 못하는 문제도 있다. 첫 버전에서는 모든 이벤트를 보여주기보다 위험 이벤트, 경계 이동, 종료 이유를 우선 노출하는 편이 낫다.

결론

AI 에이전트의 신뢰 기준은 “위험한 행동을 차단했다”에서 끝나지 않는다. 어떤 실행 경로가 일어났고, 실패했을 때 어디까지 번졌으며, 그 판단을 다시 검증할 수 있는가까지 보여줘야 한다.

차단은 예방의 언어이고, 리플레이는 학습과 책임의 언어다. 둘 중 하나를 고르는 것이 아니라, 차단을 통과한 실행도 나중에 설명할 수 있도록 설계해야 한다.

당신이 오늘 만든 에이전트는 최종 답변 말고 실행 경로를 다시 재생할 수 있는가?

Sources