
halo-record v0.2.8
面向 AI 智能体的防篡改运行时证据:基于哈希链的运行时记录,零依赖,人人可验证。
halo-record
防篡改的 AI 代理运行时记录:供应商运行但无法编辑的审计追踪。
你的代理执行的每一个动作(工具调用、模型调用、数据访问、审批)都会成为追加式结构、哈希链日志中的一条记录。任何持有该链检查点的一方都可以验证其背后的记录从未被改动过,而无需信任生成这些记录的人。当客户的安全团队问"你们的代理对我们的数据做了什么?"时,你交给他们的是一个链接,而不是一段文字。安全审查已经在 SOC 2 检查清单之外提出了 AI 相关问题,而如今一份书面保证仍然能够过关。这个项目背后的赌注是:这种情况不会持续太久。
记录格式是开放的,可以自由实现。本包是参考实现:记录器、验证器、见证客户端和报告服务器。
为什么你可以信任这段代码
你被要求将记录器放入你的代理中。你不应该只凭信任就接受这一点:
- 零运行时依赖。 仅使用标准库。
pip install halo-record只安装一个包。 - 无网络调用,见证(witness)除外——它是可选功能,只接收记录计数和链指纹。记录内容永远不会离开你的基础设施。
- 原始输入永远不会进入记录。 参数经过哈希处理,仅以脱敏摘要的形式存储——绝不存储原始值。脱敏是尽力而为的(对常见机密和 PII 格式进行正则匹配):应将其视为纵深防御,而非保证。
- 小到足以审计。 约 4,300 行 Python 代码。一个下午即可全部读完。
- Apache-2.0。
60 秒演示
无需代理。使用 uv,无需安装任何东西:
uvx --from halo-record halo demo --serve
或者用传统方式:
pip install halo-record
halo demo --serve
任一方式都会搭建一个虚构的、拥有两个客户的支持代理供应商,见证各条链,提供受门控的运行时报告(Runtime Report),并在浏览器中打开操作员控制台。然后试试篡改测试:从某个 .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 文件却没有报告,那说明有问题:请提交 issue。
连接到已在运行的系统
| 在边界处捕获 | 从现有遥测中摄取 |
|---|---|
原生记录器(from halo import trace) | OpenTelemetry GenAI spans |
| MCP 拦截器 | LiteLLM 回调 |
| LangChain / LangGraph 回调 | Langfuse 导出 |
| OpenAI Agents SDK 钩子 | 任何网关 / 反向代理日志 |
| Claude Code / Claude Agent SDK 钩子 |
每条记录都带有 source 标签,因此报告会说明每条证据是如何收集的。捕获和摄取的记录位于同一条链中。
任何会发出 OpenTelemetry GenAI spans 的系统(CrewAI、LlamaIndex,以及大多数带有 OTel 插桩的代理框架)都可以通过 OTel 适配器进入链中,而 TypeScript 包 为 Vercel AI SDK 和 JS 代理生态系统提供了原生适配器。缺少适合你技术栈的适配器?请提交 issue。大多数适配器只有大约一百行代码。
记录你的编码代理
Claude Code 在每次工具调用后都会触发 PostToolUse 钩子。将其指向 halo hook,每个动作——文件写入、shell 命令、MCP 连接器调用——都会成为本地链中的一条记录。无需修改代码;只需一条设置:
{
"hooks": {
"PostToolUse": [
{"matcher": "*", "hooks": [{"type": "command", "command": "halo hook"}]}
]
}
}
将其添加到 ~/.claude/settings.json,记录就会写入 ~/.halo/audit.jsonl(可用 $HALO_LOG 覆盖)。不接触数据、网络或外部状态的纯编排工具会被跳过——链记录的是信任边界动作,而不是思考过程。设置 HALO_HASH_ONLY=1 可仅记录内容哈希而不记录摘要。设置 HALO_AGENT_VERSION(以及可选的 HALO_AGENT_MODEL)可将每条记录绑定到生成它的代理构建版本——当审计员问及某个时间段内运行的是哪个版本时,导出结果会按列作答,而非靠回忆。
如果你需要报告回答"这次运行是在什么规则下发生的?",请将 HALO_AUTHORITY_FILE 设置为会话有效权限的 JSON 快照。注意保护隐私:只包含哈希和引用,而非原始提示词、私有策略文本、机密或完整的工具模式。
{
"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
任何提供动作后钩子的代理运行时都可以接入同一条命令——钩子从标准输入读取一个 JSON 事件,并追加一条记录。
完整性 vs. 完备性(请阅读此部分)
请准确理解每一层证明的是什么——因为它们是不同的主张,而差异正是关键:
自持链证明的是相对于既有链头的完整性:给定一个某人已经持有的链头,其背后记录中的任何编辑、重排或删除都会变得可检测。单独来看——在操作者之外的任何人看到链头之前——一条链证明的是内部一致性,而非历史:操作者可以丢弃一条记录并重新封链,新文件依然能通过验证。链在其链头离开操作者控制的那一刻起,才成为历史已提交状态。
这正是见证(witness)的作用:操作者之外的一方持有链的定期指纹(一个计数和一个链头哈希,仅此而已)。检查点使得重写已提交历史变得可检测,而错过的检查点本身就是一个可见事件:
halo anchor audit.jsonl witness.jsonl # anchor a checkpoint to a local witness
halo anchor audit.jsonl witness.jsonl --check # completeness verdict against it
还有一个边界需要直说:无论是链还是见证,都无法证明每个真实世界的动作都经过了记录器。这就是捕获完备性——它取决于记录器在技术栈中的位置(原生插桩、钩子、网关摄取),而非任何哈希。记录带有 source 标签正是出于这个原因。
| 主张 | 自持链 | + 外部检查点 | + 可信捕获 |
|---|---|---|---|
| 检测对既有产物的篡改 | ✔ | ✔ | ✔ |
| 检测对已提交历史的重写 | — | ✔ | ✔ |
| 检测缺失/迟到的检查点 | — | ✔(约定节奏) | ✔ |
| 证明每个动作都被记录 | — | — | 取决于捕获边界 |
任何人都可以运行见证。你自己运行的见证会把历史提交给你;而要提交给你的客户,则需要一个他们有理由信任的见证。无论哪种方式,协议都是开放的。
本项目将通过托管且公认的见证服务来自我维持。早期访问:[email protected]。
这在合规体系中的位置
halo-record 是一个证据层,而非认证。它产出的工件,正是评估框架们用不同措辞反复要求的东西:
- 安全问卷和 SOC 2 审查: 用可验证的运行时报告回答 AI 部分,而不是截图和文字描述。
- AIUC-1: 生成该标准问责(Accountability)控制项所要求的防篡改日志(E015.4)和包含授权事件的完整执行链记录(E015.2)——持续不断的运行时证据,而非在审计时才重建。
- OWASP(GenAI 安全项目): 为 OWASP 2026 代理应用 Top 10 和 LLM Top 10 中的代理行为风险——目标劫持、工具滥用、身份与权限滥用——提供运行时证据,记录代理实际做了什么、使用了哪些工具和数据。
- AARM(CSA): 生成 AARM 所规范的防篡改动作回执(R5/R6)——经过哈希链链接并独立见证。halo-record 是回执层;将其与执行网关搭配使用,即可构成完整的 AARM 系统。参见
AARM.md。 - Agentic Trust Controls(ATC): ATC 证据控制项背后的运行时记录——防篡改动作日志(RBM-03)和权限证明(AID-05)合并在同一条链式记录中,见证层则凌驾于两者之上。参见
ATC.md。 - 欧盟《人工智能法案》(EU AI Act): 高风险 AI 系统的日志记录与记录保存义务。
- ISO 42001 / NIST AI RMF: 管理体系控制项背后的运营证据。
这些本身都不能认证任何东西。它只是给你的评估人员一些可验证的内容。边界——halo-record 刻意不做什么,以及当审查者问起时该如何回答——都记录在 LIMITS.md 中。
CLI
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,即 JSON 规范化方案)进行规范化;然后对字节进行 SHA-256。第一条记录的 prev_hash 是 64 个零。验证会重新计算每个哈希并检查每个链接。无需任何密钥;这正是关键所在。
认为你可以篡改链而不被验证器发现?尝试与结果在此。
完整字段参考:halo-record.schema.json。
TypeScript
相同的记录器也已面向 Node 发布:halo-record-ts。相同的链格式,相同的见证协议。用任一语言写入的记录,都可以用任一验证器进行验证。
贡献
欢迎提交 issue、参与讨论和提交拉取请求——基本规则请参阅 CONTRIBUTING.md(简而言之:需要测试、小规模 PR、schema 变更需先讨论)。
许可证
Apache-2.0