关于 Aileron Journal
Aileron Journal 是面向 AI Agent 审计的只读 MCP 服务,可验证日志完整性并查询工具调用记录。它以哈希链和签名检查点保存防篡改证据,并支持按条件检索事件。
主要功能
- 01验证哈希链日志与签名检查点
- 02按工具、状态或时间查询事件
- 03说明策略规则的匹配内容
- 04只读访问并限制日志路径
适用场景
- 01核验 Agent 操作记录是否被篡改
- 02查找指定时段内的工具调用
- 03向助手询问某条规则的含义
MCP 相关
Aileron 的 MCP 服务模式以只读方式公开日志,提供 verify_journal、query_events 和 explain_rule 工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| journal | string | 是 | 日志文件名,相对于所提供的根目录。 |
详细介绍
Aileron
Aileron 是 AI Agent 的飞行记录仪。
它不是又一个追踪器。Aileron 会为 Agent 的每次工具调用生成防篡改、可重放的记录——你可以离线验证这些证据,而不必盲目信任遥测数据。
- 防篡改审计追踪。 每个 Agent 操作都会追加到采用 SHA-256 哈希链的 JSONL 日志中,并附带 Ed25519 签名检查点。只需编辑、删除或重排其中一行,
aileron verify就会准确指出哈希链从哪里断开。 - 对工具调用实施策略。 采用类似 Sigma 的 YAML 规则,支持
allow/alert/block操作,并通过 MCP stdio 代理或 SDK 装饰器在执行前应用规则。被阻止的工具调用不会执行;但尝试仍会记录。 - 取证式事件重放。 只需一条命令,就能将日志转换为独立的 HTML 事件报告,其中包含验证徽章和可筛选时间线——由此回答“Agent 实际操作了什么?”
60 秒快速入门
$ pip install aileron
$ aileron demo # scripted fake-agent session (no network, no keys needed)
demo: wrote 8 events to demo.chain.jsonl
demo: chain VERIFIED (8 events)
demo: blocked shell call by rule aileron-001
demo: 2 anomaly alert(s) emitted
$ aileron verify demo.chain.jsonl
OK: 8 events verified in demo.chain.jsonl
$ aileron report demo.chain.jsonl -o incident.html # open it in a browser
$ aileron serve --root . # or ask an assistant instead
该演示以默认的仅摘要模式运行:破坏性 Shell 调用会被内容规则阻止,并被行为基线标记,但磁盘上的日志只包含参数摘要,绝不包含原始命令。
功能
| 功能 | 提供的能力 |
|---|---|
| 哈希链日志 | 仅追加的 JSONL;每个事件的 prev_hash 都链接到前一个事件的 SHA-256 哈希;创世哈希为 0x00…00 |
| 签名检查点 | 对链尾进行 Ed25519 签名,可使用公钥离线验证(aileron sign-checkpoint / verify-checkpoint)。检查点覆盖一个前缀:之后追加事件不会使检查点失效;截断或改写已签名前缀则会 |
| 策略规则 | 32 条内置规则,涵盖凭据窃取、云元数据滥用、数据外泄、供应链、持久化、反取证、数据库破坏和提示词注入产物。采用类似 Sigma 的 YAML;支持子字符串、正则表达式和点分键匹配器。规则会在内存中针对完整调用进行评估,因此即使处于仅摘要模式,内容规则也能触发 |
| 行为异常检测 | 滚动基线会标记首次出现的工具、速率激增(> 基线的 3 倍)和新颖的工具调用序列——可通过 SDK(baseline=)实时检测,或通过 aileron detect 离线检测 |
| MCP stdio 代理 | 位于任意 MCP 客户端和服务之间;在每个 tools/call 到达子进程前进行记录和中介。已通过官方 filesystem 和 memory 服务验证,不只是使用测试替身 |
| Claude Code 钩子 | aileron hook 接入 Claude Code 的 PreToolUse 和 PostToolUse 钩子:每次工具调用都会在执行前及返回后记录;匹配的阻止规则会停止调用(退出码为 2,并在会话中显示原因,即使处于 bypassPermissions 模式也是如此);如果日志无法写入,也会阻止调用,而不是丢失记录。一段 settings.json 配置即可用于一个项目。参见 docs/claude-code.md |
| MCP 服务模式 | aileron serve 以只读方式公开日志,让助手可以根据记录回答“Agent 操作了什么?”。已在官方 MCP Registry中列出,名称为 io.github.aileron-sh/aileron |
| OTel GenAI 导出 | 事件会导出为与 gen_ai.* 对齐的 span 字典(aileron export),供现有的收集器使用 |
| HTML 事件报告 | 单文件,内嵌 CSS,无外部资源,并带有验证徽章(VERIFIED / TAMPERED at seq N) |
| 默认保护隐私 | 工具参数和结果仅记录摘要,除非你选择使用 --capture-content |
用法
SDK:@track 装饰器
from aileron import ChainLog, track, PolicyBlocked, bundled_rules_dir
from aileron.policy import load_rules
log = ChainLog("run.chain.jsonl") # capture_content=False by default
rules = load_rules(bundled_rules_dir()) # or load_rules("rules") after `aileron init`
@track(log=log, rules=rules)
def shell(cmd: str) -> str:
... # your tool implementation
shell("ls /tmp") # -> tool_call event, status=ok, args recorded as digest
shell("rm -rf /") # -> PolicyBlocked raised; blocked attempt is logged
规则会在决策时查看内存中的完整参数;日志仍只存储摘要。仅当你希望将原始参数持久化以供取证时,才启用 capture_content=True。
SDK:track_agent 会话
from aileron import track_agent
with track_agent("research-agent", framework="langchain", log=log):
shell("ls /tmp") # inherits the session's agent identity and session_id
# agent_start / agent_end events bracket the run automatically
MCP 代理:与框架无关的拦截
包装任意 MCP 服务。每次 tools/call 都会被记录并进行策略检查,然后才会交给子进程处理:
$ aileron init # seeds a ./rules directory with starter rules
$ aileron proxy --log run.chain.jsonl --rules rules -- \
npx -y @modelcontextprotocol/server-filesystem /tmp
$ AILERON_SESSION_ID=run-4821 aileron proxy --log run.chain.jsonl --rules rules \
--agent researcher --framework crewai -- npx -y @modelcontextprotocol/server-filesystem /tmp
代理标志必须放在 -- 前面;其后的所有内容都属于子进程。每次启动时,测试框架可以设置 AILERON_AGENT、AILERON_FRAMEWORK 和 AILERON_SESSION_ID,而无需传递标志;如果同时设置了标志和环境变量,则以标志为准。日志会记录你提供的身份信息,因此像 agent.name: researcher 这样的规则会在代理路径上匹配。跨运行重复使用会话 ID 会将它们归为一组:detect 会将其视为同一会话,OTel 导出则会将它们放入同一条追踪中。
被拦截的调用会向客户端返回 JSON-RPC 错误(-32000: blocked by aileron rule <id>);子进程不会被调用。
已通过真实 MCP 服务验证,而不只是测试替身。Aileron 已在官方 @modelcontextprotocol/server-filesystem(secure-filesystem-server 0.2.0,14 个工具)和 @modelcontextprotocol/server-memory(0.6.3,9 个工具)前运行:握手顺利完成,工具列表正常显示,真实调用正常运行,被拦截的写入操作不会到达服务,并且日志验证通过。这项检查作为测试提供(tests/test_real_mcp_server.py,使用 AILERON_LIVE_MCP=1 运行)。
代理本身每次 tools/call 的开销远低于 1 毫秒。针对大型负载匹配内容规则的开销更高,具体开销由你决定:有关经过测量的细分数据,请参阅性能。
代理同时支持以换行符分隔和以 Content-Length 分帧的 JSON-RPC。内容规则(tool.arguments_contains、_regex)在默认的仅摘要模式下也能生效——--capture-content 会改变持久化的内容,而非强制执行的内容。子进程退出时仍在进行的调用会以 status=error 写入日志,因此崩溃不会抹去调用记录。
Claude Code:记录并监管每次工具调用
Claude Code 自带的工具(Bash、Edit、Write、MCP 工具)会通过其钩子系统运行,而 aileron hook 是专为它设计的命令钩子。只需一个条目,注册到 PreToolUse、PostToolUse 和 PostToolUseFailure;PreToolUse 的条目还会设置 "onFailure": "block":
{"type": "command", "command": "aileron",
"args": ["hook", "--log", "${CLAUDE_PROJECT_DIR}/aileron.chain.jsonl",
"--rules", "${CLAUDE_PROJECT_DIR}/rules"],
"timeout": 30}
每次调用都会在运行前和返回后分别写入日志,默认只记录摘要。匹配到拦截规则时,调用会以退出码 2 停止,Claude 会在会话中看到原因:
PreToolUse:Bash hook error: [aileron hook ...]: blocked by aileron rule
local-001 (Block destructive shell commands from Claude Code); recorded as
seq 3 in /home/me/my-project/aileron.chain.jsonl
该钩子采用故障时默认拒绝策略:如果无法写入日志或加载规则,就会拦截调用,而不会让它在未记录的情况下运行;它也绝不会写入标准输出或发出 allow,因此只会收紧 Claude Code 原本允许的操作范围。钩子进程会并行运行,并通过 <log>.lock 进行串行化。aileron verify 和 aileron report 同样适用于此日志。完整设置说明、事件结构和限制(超时钩子的含义、@ 文件读取、mods)请参阅 docs/claude-code.md。
MCP 服务:询问你的助手 Agent 做了什么
Aileron 位于 MCP 服务之前,它本身也是一个 MCP 服务。将它指向一个日志目录,助手就能为你读取记录:
$ aileron serve --root ./journals
三个工具,全部为只读:verify_journal(记录是否完整)、query_events(发生了什么,可按工具、状态或时间筛选),以及 explain_rule(aileron-130 会捕获什么)。
这里没有写入、删除或签名工具,也绝不应该有。被记录的 Agent 是不可信方,因此若让它能够编辑日志,就等于把证物柜的钥匙交给嫌疑人。
由此带来四点,这也是它不只是 aileron verify 的一层包装的原因:
- 路径仅限于
--root范围内,并且只会打开.jsonl文件。否则,verify_journal(path)就会变成任意文件读取。 - 每个答复都附带自身的完整性状态。 路径限制可以阻止 Agent 读取不应读取的文件,但无法阻止它在根目录内写入一份看似可信的日志,再把编造的历史交给你。因此,每条答复都会说明哈希链是否通过验证,以及相邻的签名检查点是否一致。
- 记录的值一律视为恶意内容。 工具名称和规则 ID 是由受调查的 Agent 选定的,因此传给助手时会标记为不可信数据、剔除控制字符并截断。名为
IGNORE PREVIOUS INSTRUCTIONS...的工具是需要报告的证据,而不是需要遵循的指令。 - 仅摘要模式始终只返回摘要。
capture_content决定日志存储什么,但绝不会扩大此服务返回的内容范围,错误信息也绝不会回显文件内容。
策略规则
# a policy rule (see the bundled rules/examples/destructive-shell.yml)
id: aileron-001
title: Block destructive shell commands
severity: high
match:
type: tool_call
tool.name: shell
tool.arguments_contains: ["rm -rf", "DROP TABLE", ":(){ :|:& };:"]
action: block
针对已记录的会话试运行规则:aileron rules test rules/ run.chain.jsonl
工作原理
agent ──tool call──► [ SDK @track ] ──┐
[ MCP proxy ] ──┼─► policy decide (allow/alert/block)
│ │ block? ──► call never executes,
MCP client ──JSON-RPC──► proxy ───────┘ │ attempt still logged
▼
append to chain log (JSONL)
event 0 event 1 event N
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ seq: 0 │ │ seq: 1 │ │ seq: N │
│ prev: 0000… │─►│ prev: H(e0) │─► … ──►│ prev: H(eN-1)│
│ hash: H(e0) │ │ hash: H(e1) │ │ hash: H(eN) │──► Ed25519 checkpoint
└──────────────┘ └──────────────┘ └──────────────┘ signature over tip
H(e) = sha256(canonical_json(e \ hash))
aileron verify → recompute every hash + link (exit 2 on tamper)
aileron verify-checkpoint → re-verify chain tip against Ed25519 signature
篡改任何事件都会在首个被修改的序列处破坏哈希链接;verify 会报告 first_bad_seq 并以非零状态码退出。日志仅存于本地且自包含——验证无需网络,也不依赖可信第三方。
独立验证
你不必只听 Aileron 对日志内容的一面之词。另一个用 Go 编写、仅依赖标准库的验证器位于 verifiers/go/,它仅依据 SPEC.md 重新实现了 verify 和 verify-checkpoint:
$ cd verifiers/go && go build ./cmd/aileron-verify
$ ./aileron-verify verify demo.chain.jsonl
OK: 8 events verified in demo.chain.jsonl
$ ./aileron-verify verify-checkpoint demo.chain.jsonl --key aileron_ed25519.pub
之所以提供它,是因为如果防篡改工具只有一个由作者用一种语言编写的验证器,就等于要求你信任作者两次。两个只共享规范的实现,可以证明规范是完整的,而且两者都没有容易利用的盲点。tests/conformance/ 下的测试样例确保每次测试运行中,两者都得出相同的结论,并生成相同的规范字节。
性能
每次 tools/call 中,代理增加的延迟远低于 1 毫秒。将完整的 32 条内置规则包与负载进行匹配,带来的是另一项开销,会随负载大小而增长;下文会单独报告,因为这两项开销的变化规律不同,而且你可以自行选择规则。
所有数字都可以通过一条命令复现:
$ python scripts/benchmark.py
测试方法。 scripts/benchmark.py 以三种方式驱动同一个 stdio MCP 子服务:直接调用、通过没有规则的 aileron proxy 调用,以及通过带有全部 32 条内置规则的 aileron proxy 调用,然后计算差值。这些差值就是真实的代理开销,因此你无需盲信绝对数值。旁边也会打印绝对基准值,以便核对差值。每种配置依次调用 2,000 次,并先运行 200 次预热调用后丢弃结果;日志仅记录摘要。开销涵盖 JSON-RPC 解析、策略评估、哈希链追加、重新序列化以及额外的进程跳转。
关于负载。 工具参数是固定文本,内容看起来像真实的工具参数:英文单词、路径、标志、引号和标点。这一点的重要性可能超出你的想象。这个基准测试过去会发送一串重复字符,这对正则表达式引擎和下文所述的字面量预筛选器来说都是最友好的输入:前者在所有位置都能在首个字符处失败,后者则完全找不到匹配项。这让结果看起来好了约 3 倍。有一项测试会断言没有内置规则匹配填充文本,因此这些数字反映的是常规路径,而非告警路径。
每次 tools/call 增加的延迟(毫秒)
Linux x86_64 - GitHub Actions ubuntu-latest(2 个共享 vCPU),Python
3.12.14。CI 在每次推送时重新测量:
| 工具参数 | 直接调用 | 通过代理 | + 32 条规则 | 代理增加 | 规则增加 | 总计增加 |
|---|---|---|---|---|---|---|
| 64 B | 0.077 | 0.305 | 0.546 | 0.228 | 0.242 | 0.469 |
| 4 KB | 0.078 | 0.348 | 0.740 | 0.270 | 0.392 | 0.662 |
| 32 KB | 0.241 | 0.799 | 3.030 | 0.558 | 2.231 | 2.789 |
共享 CI 运行器的测量结果会因运行而异,小负载这一行的差异最高可达 1.6 倍。本表采用连续两次测量中较慢的结果。回归基准采用较快的结果,因此运行器变慢时不会悄悄放宽阈值。
macOS arm64 - Apple M2 Pro,Python 3.13.7,机器空闲。取三轮测试中的最差结果,并按原值列出,因此在该轮测试中,added = (proxy & rules) - direct 完全成立:
| 工具参数 | 直接调用 | 通过代理 | + 32 条规则 | 代理增加 | 规则增加 | 总计增加 |
|---|---|---|---|---|---|---|
| 64 B | 0.016 | 0.089 | 0.195 | 0.073 | 0.105 | 0.178 |
| 4 KB | 0.034 | 0.157 | 0.507 | 0.123 | 0.350 | 0.474 |
| 32 KB | 0.156 | 0.457 | 2.604 | 0.300 | 2.147 | 2.447 |
这些数字的含义
代理开销低且几乎恒定。 在测试过的最慢硬件上,拦截、日志记录和重新序列化在小型调用中耗时约 0.23 ms,在 32 KB 的调用中耗时约 0.56 ms。
大载荷上的规则开销更高,具体成本由你选择。 内容规则会针对载荷进行匹配,因此开销会随载荷大小增长。加载全部 32 条内置规则时,小型调用耗时 0.24 ms,32 KB 的调用耗时 2.23 ms。
大部分工作在开始前就会被跳过。 查找 auditctl 的规则不会在不含 auditctl 的载荷上触发。每个模式只读取一次,并提取出其必需的字面值;随后通过低成本的子串搜索判断是否需要运行正则表达式。要求条件是合取关系,因此,需要在 disable 附近查找 systemctl、并在 auditd 附近查找 disable 的规则,会在普通文本中被跳过,即使文本中仅包含“service”一词也是如此。在无害的 32 KB 调用中,原本会扫描整个载荷的 19 个模式里,有 17 个不会运行。这只影响速度,不影响其他任何行为;如果你想在调查期间排除这一因素,可以设置 AILERON_NO_PREFILTER=1 将其关闭。
结合实际来看。 一次真实的 MCP 服务调用通常耗时 10 到 1000 ms。对于加载全部规则时带有 32 KB 参数的调用,中介处理耗时 2.8 ms;对于普通的小型调用,则耗时 0.47 ms。与其所中介的调用相比,这只是很小的一部分。
明确说明注意事项。 这些是顺序执行的 stdio 往返,一次只处理一个调用,这正是 Agent 实际调用工具的方式。这不是多客户端基准测试;多客户端测试已列入规划。该工具会报告平均值、中位数、p95 和 p99;这些表格列出的是中位数,因为中位数在多次运行中较为稳定,而 p95 并不稳定——调度会导致尾延迟波动。Linux 上的速度较慢,是因为共享 vCPU 的 CI 运行器比空闲笔记本电脑慢;CI 强制执行的正是这些保守数据。在引用数字之前,请先在自己的硬件上测量。
CI 会强制执行这项要求:如果中位数开销相较于 scripts/benchmark_baseline.json 回退超过 2 倍,作业就会失败,以防性能悄然下降。失败前会重新测量一次,避免单个运行缓慢的运行器误报。基线会记录规则包大小和测量所用的载荷形态,因为两者任一发生变化都会增加工作量,而不是说明代码变慢;守护机制会明确指出这一点,而不会报告并不存在的性能回退。
集成与生态
- OpenTelemetry GenAI -
aileron export会输出gen_ai.operation.name/gen_ai.tool.name/gen_ai.agent.namespan 属性,以及aileron.event.hash,因此 Aileron 会作为证据层配合你现有的追踪 技术栈,而不是取而代之。 - LangChain / CrewAI / 任意 Python 框架 -
@track是普通的 装饰器;track_agent接受自由格式的framework=标签。无需依赖 任何框架。参见examples/langchain_tool_tracking.py。 - LiveKit Agents(语音和视频) -
@track也能包装async def工具, 因此 LiveKit 的@function_tool可以在运行前被记录并检查;整个AgentSession也可以置于track_agent(..., framework="livekit")中。LiveKit 是被记录的框架,而不是传输层:Aileron 不会发起网络调用,也不会因此依赖 LiveKit。 参见examples/livekit_agent_tracking.py;未安装 LiveKit 时,仅使用标准库也能运行。 - MCP - 无论由哪个客户端或框架驱动,代理都可以包装任何 stdio MCP 服务。
- Claude Code -
aileron hook通过 Claude Code 自身的钩子系统记录并检查其工具 (Bash、Edit、Write、MCP 工具);无需 SDK、代理或网络,也不会改变 Claude Code 的启动方式。参见 docs/claude-code.md。 - 社区规则 - 规则贡献是预期的贡献形式(参见 Roadmap)。
遥测与隐私
- Aileron 不发送任何遥测数据。 整个库或 CLI 中都没有分析功能、自动回连或网络调用。如果这一点将来发生变化,也只会采用自愿选择加入的方式,并遵循有文档记录的 RFC——对于安全工具而言,任何低于这一标准的做法都不可接受。
- 默认不捕获内容。 工具参数和结果会以 SHA-256 摘要的形式记录;只有在传入
capture_content=True/--capture-content时,才会存储原始内容。这样,你能获得一份可验证的事件记录,又不会意外持久化机密或个人身份信息。 策略规则和异常检测器仍会在决策时于内存中查看完整调用内容——捕获设置只控制哪些内容会被持久化,绝不影响哪些内容会被强制执行策略。
如实说明局限
- SDK 插桩可以绕过。
@track会包装你所装饰的函数;未插桩的代码路径不会被记录。若要确保 Agent 代码无法绕过强制执行,请使用 MCP 代理——它会在工具调用路径上的独立进程中进行中介。 - 策略规则是模式匹配,而非意图分类。 它们可以捕获已知的恶意模式(
rm -rf、id_rsa、数据外泄模式),但无法可靠检测新型恶意推理。效果检测可与意图检测工具(garak、PromptGuard)互补,但不能取代它们。 - 防篡改不等于无法篡改。 这条链可以证明事后发生过修改;但拥有写入权限的攻击者可以截断或重写整个日志并伪造后续内容。签名检查点能让伪造行为需要私钥——请勿将密钥保存在被记录的主机上;如需不可否认性,请将检查点锚定到外部(参见路线图)。
- Claude Code 钩子的强度取决于 Claude Code 的钩子契约。 它通过退出代码 2 阻止操作,Claude Code 在所有权限模式下都会遵守该代码;但如果钩子超时或崩溃,除非设置
onFailure: "block"(Claude Code 2.1.295 或更高版本),否则会默认放行;通过@引入的文件不会触发工具钩子;处理tool.check的 mod 可以覆盖未纳入托管设置的钩子;工作区信任对话框获得接受前,钩子不会运行;而且钩子以与 Agent 相同的 OS 用户身份运行,因此它只能让日志删除和钩子移除变得显而易见,而无法让这些操作变得不可能。
路线图
aileron-rules社区规则仓库——面向 Agent 的 Sigma:由社区维护的检测规则,映射到 OWASP Agentic Security Initiative 的威胁分类法,并通过 CI 对记录的事件轨迹进行验证。- Sigstore/Rekor 检查点锚定——现为配套软件包
aileron-anchor,并保持独立,以确保此软件包不会发起网络调用。它会将签名检查点推送到公开透明日志,并根据已锚定的内容检查本地日志,从而检测尾部截断。 - OCSF 导出——生成 Open Cybersecurity Schema Framework 事件,供 SIEM 直接摄取(Splunk/Elastic 快速入门)。
- v1 范围之外:eBPF / 内核级拦截。 Aileron 将继续专注于 MCP 代理和 SDK 层,以保留工具调用的语义信息;系统调用级追踪属于 Falco/Cilium 的范畴,而且会以 Agent 语义换取数据量。
贡献
欢迎贡献——请参阅 CONTRIBUTING.md。适合入门的方向:在 src/aileron/rules/examples/ 下新增检测规则,以及在 examples/ 下新增框架适配器。需要进行 DCO 签署,无需 CLA。安全问题请参阅 SECURITY.md。
许可证
Apache License 2.0——请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。