서론
AI 에이전트에게 사내 업무를 맡기는 상황이 늘어나고 있습니다. 고객 응대, 데이터 추출, 외부 API 호출 등 사람이 일일이 확인할 필요 없이 에이전트가 도구를 사용해 진행할 수 있게 되었습니다.
그러면 곧 이런 질문이 나올 것입니다.
'우리 지원 봇이 고객의 개인 정보를 외부 API로 전송하지 않았는지?'
봇의 도구 호출 로그를 조사해보니, 외부 전송(http.post)은 정책(도구 사용 규칙)에 의해 차단되어 있었습니다(deny). 이렇게 보고하면 다음과 같은 답변을 받게 됩니다.
'그 로그가 나중에 수정되지 않았다고 말할 수 있나요?'
로그는 운영자 자신이 작성하는 것입니다. 확인하는 측면에서 보면 '자기 진술'에 불과합니다. DB를 건드릴 수 있는 사람이라면, allow를 deny로 바꾸거나 곤란한 행을 지울 수도 있습니다.
이 글에서는 이 질문에 '말할 수 있다'고 답하는 과정을 코드로 재현합니다. 사용하는 것은 TRACE라는 오픈 사양과 그 Python 라이브러리입니다.
TRACE란 무엇인가
TRACE(Trust, Runtime Attestation and Compliance Evidence)는 AI 에이전트의 실행 내용을 서명된 JSON 'Trust Record'로 남기기 위한 사양입니다. 2026년 8월에 Linux Foundation의 프로젝트가 되었습니다.
Trust Record에는 어떤 모델이, 어디서, 어떤 정책 하에 움직였고, 어떤 도구를 호출했는지 정보가 담깁니다. 도구 호출에 대해서는 로그 본문 자체가 아니라 로그의 해시와 횟수만를 넣습니다. 해시는 데이터의 지문 같은 값으로, 한 글자만 바뀌어도 다른 값이 됩니다.
게다가 Trust Record 전체에 서명을 합니다. 서명은 비밀키로 찍는 도장이며, 이에 대응하는 공개키로 확인합니다. 공개키를 가진 사람이라면, '이 키로 서명되었고 그 이후 변하지 않았다'는 것을 스스로 확인할 수 있습니다.
의혹을 해소하는 절차
등장하는 것은 두 가지입니다.
- 게이트웨이: 에이전트와 도구 사이에 위치한 관문입니다. 도구 호출을 기록하고, 정책 위반은 막습니다. - 투명성 로그: 제3자가 운영하며 추가만 가능한 장부입니다.
절차는 다음과 같습니다.
- 실행 시: 게이트웨이가 로그의 해시와 도구 호출 횟수를 Trust Record에 넣어 서명하고, 투명성 로그에 등록합니다(앵커링). - 조사 시: 제출된 Trust Record의 서명과, 투명성 로그에 대한 등록 여부를 확인합니다. 다음으로, 제출된 로그로부터 해시를 다시 계산하여 기록된 값과 비교합니다. - 결론: 모든 것이 통하면, 로그는 실행했던 시점 그대로입니다. 그 로그에
deny가 남아 있다면, 외부 전송은 막혔다고 말할 수 있습니다.
직접 작동시켜 보기
agentrust-trace 0.11.0과 Python 3.12로 작동시켰습니다(agentrust-trace의 동작에는 Python 3.11 이상이 필요합니다). 게이트웨이 역할은 스크립트가 수행합니다. 투명성 로그 역시 agentrust-trace에 등록 기능이 없기 때문에, 추가만 하는 리스트로 대신합니다.
pip install agentrust-trace
import hashlib, json, time
import rfc8785
from agentrust_trace import generate_key, key_to_jwk, sign_record, verify_record
...
실행 결과입니다(시간과 키를 매번 만들기 때문에, iat・cnf.jwk.x・signature는 실행할 때마다 바뀝니다).
--- 게이트웨이가 남긴 로그 ---
[
{
...
앞부분이 게이트웨이의 로그 본문입니다. 두 번째 호출에 http.post가 deny로 차단된 기록이 있습니다.
그다음이 서명된 Trust Record입니다. 주목해야 할 곳은 3군데입니다.
tool_transcript: 로그 본문은 없고, 해시와 횟수만 있습니다. - cnf.jwk: 서명에 사용된 키의 공개키입니다. - signature: Trust Record 전체에 대한 서명입니다. 위 중 어느 한 글자라도 바뀌면 검증에 실패합니다.
마지막이 네 가지 케이스의 대조 결과입니다.
케이스 1에서는 두 해시가 같은 값(5185db14...)을 가지게 되었고, 장부에도 등록되어 있습니다. 로그는 실행했던 시점 그대로입니다. 그 로그에 http.post가 deny
줄이 삭제된 기록이 남아있기 때문에, 외부 전송은 게이트웨이에서 막혔습니다. 초반의 의혹은 이것으로 해소됩니다.
케이스 2는 줄을 하나 지웠을 뿐이고, 케이스 3은 URL을 한 곳만 바꾼 경우입니다. 그럼에도 재계산된 해시 값은 기록과 완전히 다른 값이 되었습니다.
케이스 4는 운영자가 키를 가지고 있을 때의 수법입니다. 수정된 로그에 맞춰 Trust Record를 다시 만들고, 같은 키로 다시 서명합니다. 서명도 해시도 통과해 버리지만, 새로 만든 기록은 원장(台帳)에는 없습니다. 투명성 로그(透明性ログ)에 등록되지 않으면 이 수법을 알아챌 수 없습니다. 여기서는, 새로 만든 기록을 원장에 등록하지 않는 경우를 시도하고 있습니다. 만약 등록까지 되었다면, 원장의 등록 시간과 대조하여 알아차릴 수 있습니다 (이 글에서는 다루지 않습니다).
참고로, 여기서의 로그 형식(tool
・args
・decision
)은 설명용으로 단순화된 것입니다. 실제 형식은 사용하는 게이트웨이에 따라 다릅니다.
단서: 이 결론이 성립하는 조건
전제가 두 가지 있습니다.
첫 번째는, 외부로 나가는 경로가 게이트웨이뿐이라는 것입니다. 게이트웨이를 통하지 않은 통신은 로그에 남지 않습니다.
두 번째는, 실행 시점의 로그가 정확하다는 것입니다. 투명성 로그로 막을 수 있는 것은 '나중에 바꾼 것'입니다. 키를 가진 운영자가 실행 시점에 거짓 로그를 만들고 서명하여 등록한 경우에는 알아챌 수 없습니다.
소프트웨어 키로 서명하는 방법(Level 0)으로 할 수 있는 것은 여기까지이며, 공식적으로도 제3자의 검증에는 적합하지 않다고 합니다. 운영자 자신을 포함하여 의혹을 해소하려면, 게이트웨이를 TEE(CPU가 지키는 실행 환경. 관리자조차 내용이나 수정할 수 없음)에서 구동하고 '진짜 게이트웨이가 작동했다'는 것을 하드웨어로 증명해야 합니다. TRACE로 이를 검증하는 메커니즘은 v0.3에 추가될 예정입니다. 자세한 내용은 공식 Limitations에 정리되어 있습니다.
요약
'그 로그, 나중에 바꾼 거 아니라고 말할 수 있어?'라는 질문에는, TRACE를 사용하면 '말할 수 있다'고 답할 수 있습니다. 줄을 지우거나, 값을 바꾸거나, 기록 자체를 다시 만들더라도 대조를 통해 알아챌 수 있기 때문입니다.
다만, 그것은 게이트웨이의 기록이 신뢰할 수 있는 범위 내에서의 이야기입니다. 운영자 자신까지 포함하여 증명하려면 TEE를 통한 뒷받침이 필요합니다.
참고 링크
Discussion