
AI 에이전트용 변조 방지 런타임 증거: 해시 체인 방식의 런타임 레코드, 의존성 없음, 누구나 검증 가능.
변조 방지 AI 에이전트용 런타임 기록: 공급업체가 실행하지만 편집할 수 없는 감사 추적.
에이전트가 수행하는 모든 작업(도구 호출, 모델 호출, 데이터 접근, 승인)은 추가 전용 구조의 해시 체인 로그에서 하나의 레코드가 됩니다. 체인의 체크포인트를 보유한 누구든, 해당 레코드를 생성한 주체를 신뢰할 필요 없이 그 뒤의 레코드가 변경된 적 없음을 검증할 수 있습니다. 고객의 보안 팀이 "에이전트가 우리 데이터로 무엇을 했나요?"라고 묻는다면, 한 단락 대신 링크 하나를 건네면 됩니다. 보안 검토는 이미 SOC 2 체크리스트 옆에 AI 관련 질문을 포함하고 있으며, 오늘날에는 서면 보증서로도 통과합니다. 이 프로젝트의 배경에는 그 서면 보증이 곧 통과되지 못할 것이라는 베팅이 있습니다.
레코드 형식은 공개되어 있으며 누구나 자유롭게 구현할 수 있습니다. 이 패키지는 레코더(recorder), 검증기(verifier), 증인 클라이언트(witness client), 리포트 서버(report server)를 제공하는 참조 구현입니다.
여러분은 에이전트 내부에 레코더를 설치해야 합니다. 그것을 맹신해서는 안 됩니다:
pip install halo-record는 정확히 하나의 패키지만 설치합니다.에이전트가 필요 없습니다. uv가 있으면 설치할 것도 없습니다:
uvx --from halo-record halo demo --serve
또는 전통적인 방법:
pip install halo-record
halo demo --serve
둘 중 하나는 두 고객을 둔 가상의 지원 에이전트 공급업체를 스캐폴딩하고, 체인을 증인 처리하며, 고객별 접근 통제된 런타임 리포트를 제공하고, 브라우저에서 운영자 콘솔을 엽니다. 그런 다음 변조 테스트를 해보세요: .jsonl 파일 중 하나에서 한 줄을 삭제하고 새로고침하면 리포트가 이를 감지합니다.
경계에서 한 줄이면 됩니다:
from halo import trace
agent = trace(run_my_agent, profile="my-agent", log="audit.jsonl") # wraps your entrypoint; records every tool call to ./audit.jsonl
log= 없이 사용하면 레코드는 ~/.halo/my-agent.jsonl에 저장됩니다(에이전트당 하나의 체인). 또는 이미 실행 중인 도구용 어댑터를 사용하십시오(아래 매트릭스 참조). 그런 다음 리포트를 렌더링합니다:
halo report audit.jsonl -o report.html # one chain -> self-verifying HTML
halo serve ./records --port 8721 # all tenants, gated per customer
퀵스타트는 브라우저에서 자신의 에이전트 런타임 리포트를 보는 순간 끝납니다. JSONL 파일은 얻었는데 리포트가 없다면 뭔가 잘못된 것입니다: 이슈를 열어주세요.
| 경계에서 캡처 | 기존 텔레메트리에서 수집 |
|---|---|
네이티브 레코더 (from halo import trace) |
모든 레코드에는 source 태그가 포함되어, 리포트는 각 증거가 어떻게 수집되었는지를 공개합니다. 캡처된 레코드와 수집된 레코드는 같은 체인에 있습니다.
OpenTelemetry GenAI 스팬을 내보내는 모든 것(CrewAI, LlamaIndex, 그리고 OTel 계측이 적용된 대부분의 에이전트 프레임워크)은 OTel 어댑터를 통해 체인에 들어옵니다. 또한 TypeScript 패키지는 Vercel AI SDK 및 JS 에이전트 생태계용 네이티브 어댑터를 제공합니다. 여러분의 스택에 맞는 어댑터가 없나요? 이슈를 열어주세요. 대부분의 어댑터는 약 100줄입니다.
Claude Code는 모든 도구 호출 후 PostToolUse 훅을 실행합니다. 이를 halo hook에 연결하면 파일 쓰기, 셸 명령, MCP 커넥터 호출 같은 각 작업이 로컬 체인의 레코드가 됩니다. 코드 변경은 없고 설정 항목 하나만 추가하면 됩니다:
{
"hooks": {
"PostToolUse": [
{"matcher": "*", "hooks": [{"type": "command", "command": "halo hook"}]}
]
}
}
이것을 ~/.claude/settings.json에 추가하면 레코드는 ~/.halo/audit.jsonl에 저장됩니다($HALO_LOG로 재정의 가능). 데이터, 네트워크 또는 외부 상태를 건드리지 않는 순수 오케스트레이션 도구는 건너뜁니다. 체인은 신뢰 경계(trust-boundary) 작업을 기록하지 사고 과정을 기록하지 않습니다. HALO_HASH_ONLY=1로 설정하면 요약 없이 콘텐츠 해시만 기록합니다. HALO_AGENT_VERSION(선택적으로 HALO_AGENT_MODEL)을 설정하면 모든 레코드를 생성한 에이전트 빌드에 바인딩합니다. 감사자가 특정 기간에 실행된 버전을 물어볼 때, 내보내기는 기억에 의존하는 대신 열(column) 단위로 답합니다.
리포트가 "이 실행은 어떤 규칙 하에 이루어졌나요?"에 답해야 한다면, HALO_AUTHORITY_FILE을 세션의 유효 권한(authority) JSON 스냅샷으로 설정하십시오. 프라이버시에 안전하게 유지하세요: 원시 프롬프트, 비공개 정책 텍스트, 비밀, 전체 도구 스키마가 아닌 해시와 참조(ref)만 포함합니다.
{
"snapshot_id": "auth_2026_07_08T1100Z",
"captured_at": "2026-07-08T11:00:00Z",
"scope": "session",
"workspace": {"path_hash": "sha256:...", "git_commit": "abc1234"},
"refs": [
{"kind": "project_rules", "id": "CLAUDE.md", "hash": "sha256:...", "loaded": true, "truncated": false},
{"kind": "mcp_tool_registry", "id": "filesystem", "hash": "sha256:..."}
],
"omissions": [{"kind": "private_policy", "reason": "customer_secret", "hash": "sha256:..."}],
"stale_if": ["project_rules_hash_changed", "mcp_tool_registry_hash_changed"]
}
HALO_AUTHORITY_FILE=./authority.json halo hook
스냅샷은 작업 레코드와 동일한 해시 체인에 봉인됩니다. 좋은 기본값은 시작 시 세션 수준 스냅샷 하나, 그리고 규칙, Skills, 훅, MCP 도구 레지스트리 또는 컴팩션 정책이 변경될 때마다 새 스냅샷을 추가하는 것입니다. 긴 세션을 가볍게 유지하기 위해, 첫 전체 스냅샷 이후 동일한 authority.snapshot_id를 가진 연속 레코드는 컴팩션됩니다: 이후 레코드는 {"snapshot_id": "...", "same_as_previous": true}만 유지합니다. 포인터는 해시 체인에 계속 연결되지만, 부피가 큰 refs/omissions/stale-if 블록이 모든 작업에 반복되지는 않습니다. 그런 다음 평소처럼:
halo verify ~/.halo/audit.jsonl
halo report ~/.halo/audit.jsonl -o report.html
사후 작업 훅을 노출하는 모든 에이전트 런타임은 동일한 명령을 사용할 수 있습니다. 훅은 stdin에서 JSON 이벤트 하나를 읽고 레코드 하나를 추가합니다.
각 계층이 무엇을 증명하는지 정확히 구분해야 합니다. 그것들은 서로 다른 주장이며, 그 차이가 핵심입니다:
자체 보유 체인은 기존 헤드에 대한 무결성을 증명합니다: 누군가 이미 보유하고 있는 체인 헤드가 주어지면, 그 뒤 레코드의 편집, 재정렬 또는 삭제는 모두 감지 가능해집니다. 단독으로는 — 운영자 외부의 누군가가 헤드를 보기 전에는 — 체인은 내부 일관성을 증명할 뿐 역사를 증명하지 않습니다: 운영자가 레코드를 버리고 다시 봉인할 수 있으며 새 파일도 검증을 통과할 것입니다. 체인은 헤드가 운영자의 통제를 벗어나는 순간 역사적으로 커밋(historically committed) 됩니다.
그것이 바로 증인입니다: 운영자 외부의 주체가 체인의 주기적 지문(개수와 헤드 해시, 그 외에는 없음)을 보유합니다. 체크포인트는 커밋된 기록의 재작성을 감지 가능하게 만들며, 놓친 체크포인트 자체도 가시적인 사건입니다:
halo anchor audit.jsonl witness.jsonl # anchor a checkpoint to a local witness
halo anchor audit.jsonl witness.jsonl --check # completeness verdict against it
한 가지 더 경계를 분명히 하겠습니다: 체인도 증인도 모든 실제 작업이 레코더를 통과했음을 증명하지 않습니다. 그것은 캡처 완전성(capture completeness) — 레코더가 스택의 어디에 위치하는지(네이티브 계측, 훅, 게이트웨이 수집)의 속성이며, 어떤 해시의 속성도 아닙니다. 레코드가 source 태그를 갖는 이유가 정확히 이것입니다.
누구나 증인을 실행할 수 있습니다. 직접 실행하는 증인은 여러분에게 역사를 커밋합니다. 고객에게 커밋하려면 고객이 신뢰할 이유가 있는 증인이 필요합니다. 프로토콜은 어느 쪽이든 공개되어 있습니다.
이 프로젝트는 호스팅되어 인정받는 증인으로 지속될 것입니다. 얼리 액세스: [email protected].
halo-record는 증거 계층(evidence layer)이지 인증(certification)이 아닙니다. 평가 프레임워크가 여러 다른 말로 계속 요구하는 아티팩트를 생성합니다:
AARM.md를 참조하세요.ATC.md를 참조하세요.이 중 어느 것도 그 자체로 무엇을 인증하지는 않습니다. 평가자에게 검증할 수 있는 무언가를 제공할 뿐입니다. 경계 — halo-record가 의도적으로 하지 않는 일과 검토자가 물을 때 어떻게 답해야 하는지 — 는 LIMITS.md에 문서화되어 있습니다.
halo verify validate schema + hash chain (non-zero exit on failure; CI-friendly)
halo report render a chain as a self-verifying HTML Runtime Report
(--from/--to: a date-windowed report covering only the review period)
halo serve serve per-tenant reports over HTTP, access-scoped per customer
halo grant designate a report recipient (email or domain)
halo anchor witness a chain head, or --check completeness
halo demo scaffold the full vendor demo (record -> witness -> gated report)
halo export date-bounded evidence export: CSV + manifest tied to the chain head
halo sample emit a valid example log
halo hash canonical sha256 of a JSON value
halo hook Claude Code PostToolUse hook
레코드의 해시를 계산하려면: integrity.hash를 제외한 레코드에서 integrity.prev_hash를 이전 레코드의 해시로 설정하고, RFC 8785(JSON Canonicalization Scheme)로 정규화한 다음 바이트를 SHA-256으로 해시합니다. 첫 번째 레코드의 prev_hash는 64개의 0입니다. 검증은 모든 해시를 다시 계산하고 모든 링크를 확인합니다. 비밀이 필요 없습니다. 그것이 핵심입니다.
검증자가 알아차리지 못하고 체인을 변조할 수 있다고 생각하시나요? 시도와 결과는 여기 있습니다.
전체 필드 참조: halo-record.schema.json.
동일한 레코더가 Node용으로 제공됩니다: halo-record-ts. 동일한 체인 형식, 동일한 증인 프로토콜. 두 언어 중 하나로 작성된 레코드는 두 검증기 중 하나로 검증할 수 있습니다.
이슈, 토론, 풀 리퀘스트를 환영합니다 — 기본 규칙은 CONTRIBUTING.md를 참조하세요(요약: 테스트 필수, 작은 PR, 스키마 변경은 먼저 논의).
Apache-2.0
| OpenTelemetry GenAI 스팬 |
| MCP 인터셉터 | LiteLLM 콜백 |
| LangChain / LangGraph 콜백 | Langfuse 내보내기 |
| OpenAI Agents SDK 훅 | 모든 게이트웨이 / 리버스 프록시 로그 |
| Claude Code / Claude Agent SDK 훅 |
| 주장 | 자체 보유 체인 | + 외부 체크포인트 | + 신뢰할 수 있는 캡처 |
|---|
| 기존 아티팩트의 편집 감지 | ✔ | ✔ | ✔ |
| 커밋된 기록의 재작성 감지 | — | ✔ | ✔ |
| 누락/지연 체크포인트 감지 | — | ✔ (합의된 주기) | ✔ |
| 모든 작업이 기록되었음을 증명 | — | — | 캡처 경계에 따라 다름 |