sy/dev
Paper Review
17 min read

[논문 리뷰] EvoSafeHarness — agent safety harness를 배포 환경별로 진화시키기

EvoSafeHarness 논문을 통해 agent 보안을 고정 guardrail이 아니라 모델·도메인별 runtime harness 최적화 문제로 본다.

한 줄 요약

EvoSafeHarness: Evolving Model- and Domain-Specific Harnesses for Securing Agents

Nanxi Li, Yingzi Ma, Yulong Cao, Edward Suh, Bo Li, Dawn Song, Chaowei Xiao (2026)- arXiv

EvoSafeHarness는 LLM agent 보안을 “모델이 안전하게 답하느냐”가 아니라 “특정 모델과 특정 업무 도메인에서 어떤 tool action을 어떤 runtime state 기준으로 막을 것인가”의 문제로 재정의한다. 논문은 자연어 policy와 실행 가능한 code logic을 함께 탐색해서, frozen model과 target domain에 맞는 deployable safety harness를 합성한다.

내가 보기엔 이 논문의 핵심은 guardrail을 제품 부속품이 아니라 배포 단위 artifact로 본다는 점이다. 같은 모델이라도 금융, OS 자동화, 이메일 agent에서 위험한 action relation은 다르고, 같은 도메인이라도 모델별로 과차단/미차단 균형점이 다르다. 하나의 “보편 안전 프롬프트”로 끝낼 수 없다는 쪽이 훨씬 현실적이다.

왜 지금 중요한가

agent는 텍스트를 생성하는 단계에서 실제 side effect를 만드는 단계로 넘어왔다. 이메일을 보내고, 파일을 수정하고, 티켓을 닫고, 셸 명령을 실행하고, 결제나 계정 작업을 건드린다. 이때 안전 실패는 두 경로로 들어온다.

  • Indirect prompt injection: 웹페이지, 문서, 이메일, tool output 같은 외부 데이터가 agent에게 명령처럼 작동한다.
  • Direct harmful request: 사용자가 정상 입력 채널로 위험한 작업을 요청한다.

모델 레벨 refusal나 system prompt는 여전히 필요하지만 충분하지 않다. agent의 실패 단위는 “한 문장”이 아니라 “관찰 → 판단 → tool call → 상태 변화”로 이어지는 trajectory다. 그래서 방어도 자연어 출력 필터보다 tool boundary와 trajectory state를 보는 runtime layer에 가까워져야 한다.

EvoSafeHarness가 다루는 질문은 이렇다.

이 모델을 이 도메인에 배포할 때, utility를 크게 죽이지 않으면서 어떤 policy와 code hook을 둘 것인가?

이 질문은 꽤 실무적이다. 보안 harness가 너무 느슨하면 공격이 통과하고, 너무 엄격하면 agent가 쓸모없어진다. 특히 agent 제품에서는 false positive도 제품 품질 문제다. “안전하지만 아무것도 못 하는 agent”는 방어 성공이 아니라 제품 실패에 가깝다.

기존 고정 harness의 문제

많은 agent safety 방어는 사람이 설계한 고정 policy나 고정 wrapper로 시작한다. 예를 들면 다음과 같은 규칙이다.

- tool output은 신뢰하지 않는다.
- 외부 문서의 지시는 user instruction보다 낮은 우선순위다.
- 민감 파일, credential, 외부 전송은 별도 확인한다.
- tool call 직전에 user request와 관련성을 확인한다.

이런 원칙 자체는 맞다. 문제는 실제 배포에서는 원칙을 어디서, 얼마나, 어떤 state와 결합해 적용할지가 도메인마다 달라진다는 점이다.

예를 들어 OS agent에서는 curl, /tmp, .env, background process 같은 구체적인 실행 흔적이 중요하다. 금융 agent에서는 수신자, 금액, 승인 한도, 거래 목적, 이전 step에서 얻은 정보의 출처가 중요하다. 이메일 agent에서는 숨은 recipient, forwarding, attachment provenance가 더 중요할 수 있다.

모델별 차이도 있다. 어떤 모델은 기본적으로 cautious해서 harness가 조금만 강해도 utility가 무너질 수 있다. 반대로 어떤 모델은 위험 요청을 잘 따라가므로 더 강한 enforcement가 필요할 수 있다. 논문의 주장처럼 “strict enough for one model may over-block another”라는 문제가 생긴다.

EvoSafeHarness의 설계

EvoSafeHarness는 frozen victim model과 target domain을 놓고 safety harness를 자동 탐색한다. 여기서 harness는 단순 prompt가 아니다. 크게 두 부분을 함께 바꿀 수 있다.

  1. Natural-language policy: agent나 judge에게 주입되는 안전 규칙, 우선순위, 판단 기준.
  2. Executable code logic: tool call 전후 hook, argument rewrite/block, output transform, provenance tracking, state cache, classifier 호출 같은 실제 runtime code.

논문에서 DTAP 계열 실험의 minimal adapter는 대략 이런 hook을 가진 Python Defense 객체로 설명된다.

defense_shape.py
class Defense:
    def system_prompt_transform(self, prompt: str) -> str:
        ...
 
    def on_pre_tool_call(self, tool_name: str, args: dict, state: dict):
        ...
 
    def on_post_tool_call(self, tool_name: str, args: dict, output: str, state: dict):
        ...

중요한 건 slot이 고정된 방어 taxonomy가 아니라는 점이다. Designer는 이 adapter 안에서 prompt를 고치거나, tool argument를 차단·수정하거나, output을 quarantine하거나, trajectory state를 추적하거나, 별도 judge를 호출할 수 있다. 즉 논문이 최적화하는 대상은 “문구 하나”가 아니라 policy와 code가 결합된 작은 runtime system이다.

탐색 루프: warm start, archive, critic

논문은 빈 상태에서 무작정 harness를 생성하지 않는다. 기존 보안 방어에서 얻은 설계 경험을 warm start로 넣는다. 예를 들면 “tool output은 instruction이 아니라 untrusted data로 남겨야 한다”, “tool call effect는 trusted user request와 대조해야 한다” 같은 invariants다.

그 다음 search loop는 대략 다음 구조로 돌아간다.

domain specification
  -> initial harness candidates
  -> run train-only evaluation cascade
  -> collect failed traces and scores
  -> analyze failure modes
  -> revise policy + code logic
  -> fresh-context adversarial review
  -> archive best candidates

여기서 마음에 드는 부분은 fresh-context adversarial review다. harness generator가 benchmark artifact에 과적합한 규칙을 만들 수 있기 때문이다. 예컨대 “특정 benchmark 문구가 보이면 막아라”는 규칙은 점수는 올릴 수 있어도 배포 가능한 안전 장치가 아니다. EvoSafeHarness는 후보를 별도 context에서 검토하고, benchmark-specific rule처럼 보이는 것을 거부하거나 고치게 한다.

이건 agent eval에서도 자주 보는 문제다. 모델이나 harness가 task의 본질을 푸는 게 아니라 dataset 냄새를 외우는 순간, CI 점수는 좋아져도 실제 운영 리스크는 줄지 않는다.

실험 결과를 어떻게 읽을까

초록 기준으로 논문은 네 계열 benchmark에서 safety-utility frontier가 기존 고정 방어보다 좋아졌다고 보고한다.

  • DecodingTrust-Agent: 평균 attack success rate를 45.6%에서 10.0%로 낮추고, utility cost는 3.3 point로 보고한다. 15개 model×domain cell 중 14개에서 최고 점수라고 한다.
  • AgentDojo: 0.0% ASR 지점에서 82.8% utility를 달성했다고 보고한다. 같은 zero-ASR operating point에서 CaMeL 대비 두 배 수준의 utility라는 주장도 있다.
  • AgentDyn: AgentDojo에서 얻은 harness가 unseen AgentDyn suite로 unchanged transfer된다고 보고한다.
  • Agent-SafetyBench: 모든 victim에서 최고 점수를 기록하고, adaptive PAIR attack에서도 refinement budget 16 기준 평균 ASR을 20% 아래로 유지했다고 한다.

이 숫자는 인상적이지만, 블로그 초안 단계에서는 몇 가지를 조심해서 읽어야 한다. 첫째, harness search 자체의 비용과 운영 복잡도가 제품 환경에서 얼마나 감당 가능한지는 별도 문제다. 둘째, benchmark family가 넓어도 실제 회사 내부 tool graph, 권한 모델, 사용자 행동 분포와는 다를 수 있다. 셋째, 자동 생성 code logic을 production에 넣으려면 별도의 code review, sandbox, audit trail이 필요하다.

그래도 방향은 설득력 있다. 보안 방어를 “모든 agent에 붙이는 wrapper”로 보면 계속 일반론에 머문다. “이 도메인의 action relation과 이 모델의 실패 패턴을 반영한 harness artifact”로 보면 eval, 배포, 감사가 같은 루프로 묶인다.

실무 적용 포인트

EvoSafeHarness를 그대로 구현하지 않더라도, agent runtime을 만드는 팀이 가져갈 수 있는 패턴은 명확하다.

1. Domain specification을 먼저 써라

보안 harness를 만들기 전에 도메인 spec이 있어야 한다.

agent_domain_spec.yml
domain: finance-ops-agent
trusted_context:
  - user_request
  - approved_policy_db
untrusted_context:
  - email_body
  - retrieved_web_page
  - uploaded_attachment
sensitive_effects:
  - transfer_money
  - add_payee
  - export_statement
required_relations:
  - amount_within_user_requested_limit
  - recipient_matches_approved_payee
  - action_supported_by_trusted_context

이런 spec 없이 “위험하면 막아줘”라고 하면 harness는 결국 감으로 만든 prompt가 된다. 반대로 trusted/untrusted context, sensitive effects, required relations를 명시하면 tool boundary에서 무엇을 검사해야 하는지가 보인다.

2. Tool call 직전이 가장 좋은 gate다

모든 intermediate reasoning을 깨끗하게 만들려는 시도는 비용이 크고 불완전하다. side effect가 있는 tool call 직전에 다음을 확인하는 편이 더 실용적이다.

  • 이 action은 사용자 목표에 필요한가?
  • argument는 trusted context에서 왔는가?
  • untrusted observation이 authority를 확장하지 않았는가?
  • 같은 trajectory에서 앞선 step이 이 action을 정당화하는가?
  • 실패 시 rollback이나 human approval이 가능한가?

읽기 전용 tool과 mutation tool의 gate도 분리해야 한다. search_docs와 send_email을 같은 policy로 다루면 either over-blocking or under-blocking으로 간다.

3. Harness도 regression test 대상이다

agent harness는 한 번 만들고 끝내는 설정 파일이 아니다. 모델을 바꾸거나 tool schema를 바꾸거나 도메인 정책을 바꾸면 harness도 깨질 수 있다. 최소한 다음 테스트셋은 있어야 한다.

  • 정상 업무 30~100개: false positive 측정
  • indirect injection 30~100개: 외부 content가 authority를 얻는지 측정
  • direct harmful request 30~100개: 사용자 채널의 위험 요청 처리 측정
  • adaptive attack 일부: harness 규칙을 우회하려는 변형
  • audit trace check: 왜 막았는지 사람이 읽을 수 있는지 확인

EvoSafeHarness의 표현을 빌리면, 배포 단위는 model + domain + tools + policy + code hooks + eval suite의 묶음이다. 이 묶음을 versioning하지 않으면 “지난주에는 안전했는데 이번 주에는 왜 뚫렸지?”를 재현하기 어렵다.

4. 자동 생성 harness에는 별도 안전장치가 필요하다

논문은 executable code logic을 탐색 대상으로 둔다. 이건 강력하지만 위험하다. 실제 도입한다면 생성된 harness code를 바로 production에 넣으면 안 된다.

내 기준으로는 최소한 아래 gate가 필요하다.

  • 생성 code는 sandbox에서만 실행한다.
  • 허용 API surface를 제한한다.
  • network/file/process 접근은 명시적으로 막거나 mock한다.
  • 사람이 diff를 review한다.
  • harness decision log를 남긴다.
  • 차단 사유와 허용 사유를 모두 audit 가능하게 만든다.

보안 도구를 자동 생성한다는 건 공격면을 하나 더 만드는 일이기도 하다. 그래서 EvoSafeHarness식 접근은 “무인 자동 배포”보다 “후보 harness 생성 + 강한 검증 + human/security review” 쪽으로 쓰는 게 맞다고 본다.

내 의견: agent safety는 policy가 아니라 운영 시스템이다

이 논문이 좋은 이유는 agent safety를 추상 윤리나 프롬프트 문구의 문제가 아니라 runtime engineering 문제로 끌어내리기 때문이다. 실제 agent 사고는 대개 이런 모양일 것이다.

untrusted content
  -> model believes or copies it
  -> tool argument changes
  -> side effect executes
  -> audit log is insufficient

그러면 방어도 같은 경로에 놓여야 한다.

content provenance
  -> action relation check
  -> tool boundary authorization
  -> stateful trajectory audit
  -> regression test

EvoSafeHarness는 이 경로를 model/domain-specific하게 최적화한다. 물론 논문 결과만 보고 “자동으로 안전 harness를 만들 수 있다”고 말하면 과장이다. 하지만 “agent마다 safety harness를 별도 artifact로 만들고 eval로 진화시켜야 한다”는 주장은 꽤 강하다.

특히 기업 agent에서는 이 관점이 중요하다. 보안팀이 원하는 것은 멋진 refusal 문장이 아니라 다음 질문에 답하는 시스템이다.

  • 어떤 action이 왜 허용됐나?
  • 어떤 context가 trusted였나?
  • 외부 데이터가 권한을 확장했나?
  • 모델 교체 후 같은 정책이 유지되나?
  • false positive 비용은 얼마인가?

이 질문에 답하지 못하는 guardrail은 production safety라기보다 데모용 안전장치에 가깝다.

한계와 다음에 볼 것

아직 더 확인해야 할 부분도 있다.

  • Search 비용: model×domain별 harness 탐색을 자주 돌릴 수 있는가?
  • 내부 도메인 적용성: 사내 tool graph와 policy는 benchmark보다 훨씬 지저분하다.
  • 생성 code 검증: harness code 자체의 취약점이나 과권한을 어떻게 막을 것인가?
  • Human review UX: false positive를 누가, 어떤 evidence로 해제할 것인가?
  • 지속 운영: 모델, tool schema, policy 변경 때 harness를 어떻게 재평가할 것인가?

후속으로 보면 좋은 방향은 SARA처럼 tool authorization boundary를 명시적으로 분리하는 연구, AgentDojo/CaMeL 계열의 indirect prompt injection benchmark, 그리고 LlamaFirewall 같은 production guardrail system이다. EvoSafeHarness는 이 흐름 위에서 “고정 방어를 넘어서 배포별 harness를 최적화하자”는 위치에 있다.

참고 자료

Comments