
Aileron Journal
io.github.aileron-sh由 GitHub 帳號 aileron-sh 發布v0.1.6更新於 Oct 28, 2026
Read-only queries over Aileron audit journals: verify integrity, search recorded tool calls
概覽
以唯讀方式存取 Aileron 稽核日誌的 MCP 伺服器,讓助理驗證雜湊鏈完整性、檢索已記錄的工具呼叫並解釋政策規則。
- 可以做什麼
- 驗證日誌的雜湊鏈,並檢查相鄰的簽章檢查點是否一致
- 依工具、狀態或時間篩選並查詢已記錄的事件
- 解釋某條 Aileron 政策規則會攔截什麼
- 每個回覆都附帶自身的完整性狀態,並把記錄中的工具名稱與規則 ID 當作不可信資料處理
- 適用情境
- 適合已用 Aileron 記錄代理活動、想讓助理回答「代理實際動了什麼」或「日誌是否遭竄改」的情況,同時不給助理任何修改記錄的手段。
- 執行需求
- 以本機 Python 套件(aileron)透過 uvx 執行,用 serve 指令指向存放日誌的目錄。不需帳號、API 金鑰或網路存取,驗證可離線完成。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Aileron Journal,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Aileron
[License: Apache-2.0] [Tests] [Python]
Aileron is a flight recorder for AI agents.
Not another tracer. Aileron produces a tamper-evident, replayable record of every tool call your agents make - evidence you can verify offline, not telemetry you have to trust.
- Tamper-evident audit trail. Every agent action is appended to a
SHA-256 hash-chained JSONL journal with Ed25519-signed checkpoints. Edit,
delete, or reorder a single line and
aileron verifysays exactly where the chain broke. - Policy enforcement on tool calls. Sigma-like YAML rules with
allow/alert/blockactions, applied before execution via the MCP stdio proxy or the SDK decorator. A blocked tool call never runs; the attempt is logged anyway. - Forensic incident replay. One command turns a journal into a self-contained HTML incident report with a verification badge and a filterable timeline - the answer to "what did the agent actually touch?"
60-second quickstart
The demo runs in the default digest-only mode: the destructive shell call is blocked by a content rule and flagged by the behavioral baseline, yet the journal on disk contains only argument digests - never the raw command.
Features
Usage
SDK: @track decorator
Rules see the full arguments in memory at decision time; the journal still
stores digests only. Turn on capture_content=True only when you want raw
arguments persisted for forensics.
SDK: track_agent session
MCP proxy: framework-agnostic interception
Wrap any MCP server. Every tools/call is logged and policy-checked before
the child process sees it:
Proxy flags go before --; everything after it belongs to the child. A
harness can set AILERON_AGENT, AILERON_FRAMEWORK and AILERON_SESSION_ID
per spawn instead of passing flags, and a flag wins over the environment. The
journal records the identity you give it, so a rule such as
agent.name: researcher matches on the proxy path. Reusing a session id
across runs groups them: detect treats them as one session and the OTel
export puts them in one trace.
A blocked call returns a JSON-RPC error (-32000: blocked by aileron rule <id>) to the client; the child is never invoked.
Verified against real MCP servers, not just test doubles. Aileron has been
run in front of the official @modelcontextprotocol/server-filesystem
(secure-filesystem-server 0.2.0, 14 tools) and @modelcontextprotocol/server-memory
(0.6.3, 9 tools): the handshake completes, tools list normally, real calls work,
a blocked write never reaches the server, and the journal verifies. That check
ships as a test (tests/test_real_mcp_server.py, run with
AILERON_LIVE_MCP=1).
The proxy itself costs well under a millisecond per tools/call.
Matching content rules against large payloads costs more, and how much is
yours to choose: see Performance for the split, measured.
The proxy speaks both newline-delimited and Content-Length-framed
JSON-RPC. Content rules
(tool.arguments_contains, _regex) work in the default digest-only mode -
--capture-content changes what is persisted, not what is enforced. Calls
still in flight when the child dies are journaled with status=error, so a
crash never erases the attempt.
Claude Code: record and police every tool call
Claude Code's own tools (Bash, Edit, Write, MCP tools) go through its
hook system, and aileron hook is a command hook for it. One entry,
registered under PreToolUse, PostToolUse and PostToolUseFailure; the
PreToolUse copy also gets "onFailure": "block":
Every call is journaled before it runs and again when it returns, digests only by default. A matching block rule stops the call by exit code 2 and Claude sees the reason in the session:
The hook fails closed: a journal that cannot be written or rules that cannot
be loaded block the call rather than let it run unrecorded, and it never
writes to stdout or emits an allow, so it can only narrow what Claude Code
would have permitted. Hook processes run in parallel and serialise on
<log>.lock. aileron verify and aileron report work on the journal as on
any other. Full setup, the event shapes and the limits (what a timed-out hook
means, @ file reads, mods) are in docs/claude-code.md.
MCP server: ask your assistant what the agent did
Aileron sits in front of MCP servers. It is also one. Point it at a directory of journals and an assistant can read the record for you:
Three tools, all read only: verify_journal (is this record intact),
query_events (what happened, filtered by tool, status, or time), and
explain_rule (what does aileron-130 catch).
There is no write, delete, or sign tool, and there should never be. The agent being recorded is the untrusted party, so giving it a way to edit the journal would hand the suspect the evidence locker.
Four things follow from that, and they are the reason this is more than a
wrapper around aileron verify:
- Paths are confined to
--rootand only.jsonlopens. Otherwiseverify_journal(path)is an arbitrary file read. - Every answer carries its own integrity status. Confinement stops an agent reading files it should not; it does not stop one writing a plausible journal inside the root and handing you an invented history. So each reply says whether the chain verifies and whether an adjacent signed checkpoint agrees.
- Recorded values are treated as hostile. Tool names and rule ids were
chosen by the agent under investigation, so they reach an assistant labelled
as untrusted data, stripped of control characters, and truncated. A tool
named
IGNORE PREVIOUS INSTRUCTIONS...is evidence to report, not an instruction to follow. - Digest-only stays digest-only.
capture_contentgoverns what the journal stores. It never widens what this server hands back, and errors never echo file contents.
Policy rules
Dry-run rules against a recorded session: aileron rules test rules/ run.chain.jsonl
How it works
Tampering with any event breaks the hash link at the first modified
sequence; verify reports first_bad_seq and exits non-zero. The journal
is local-only and self-contained - verification needs no network and no
trusted third party.
Independent verification
You do not have to take Aileron's word for what the journal says. A second
verifier, written in Go with nothing but the standard library, lives in
verifiers/go/ and reimplements verify and
verify-checkpoint from SPEC.md alone:
It exists because a tamper-evidence tool whose only verifier was written by
its author, in one language, asks you to trust the author twice. Two
implementations that share only the specification are evidence that the
specification is complete and that neither has a convenient blind spot. The
fixtures under tests/conformance/ hold both to the same verdicts and the
same canonical bytes on every test run.
Performance
The proxy adds well under a millisecond per tools/call. Matching the full
32-rule bundled pack against the payload is a separate cost that grows with
payload size, and it is reported separately below, because the two scale
differently and you choose your own rules.
Every number is reproducible with one command:
Method. scripts/benchmark.py drives an identical
stdio MCP child server three ways - directly, through aileron proxy with no
rules, and through aileron proxy with all 32 bundled rules - and subtracts.
The deltas are the proxy's true cost, so you never have to trust an absolute
figure. The absolute baseline is printed alongside so the subtraction can be
checked. 2,000 sequential calls per configuration after 200 discarded warmup
calls; digest-only journaling. Overhead covers JSON-RPC parsing, policy
evaluation, hash-chain append, re-serialization, and the extra process hop.
About the payload. The tool arguments are fixed text that looks like real tool arguments: English words, paths, flags, quotes and punctuation. That matters more than it sounds. This benchmark used to send a run of one repeated character, which is the friendliest possible input both to the regex engine, which fails on the first character everywhere, and to the literal prefilter described below, which finds nothing anywhere. It was flattering the result by about 3x. A test asserts no bundled rule fires on the filler, so these numbers are the ordinary path and not the alert path.
Added latency per tools/call (milliseconds)
Linux x86_64 - GitHub Actions ubuntu-latest (2 shared vCPU), Python
3.12.14. Re-measured by CI on every push:
[Benchmark]
Shared CI runners vary between runs, by as much as 1.6x on the small-payload row. This table quotes the slower of two consecutive measurements. The regression baseline uses the faster one, so a slow runner cannot quietly widen the guard.
macOS arm64 - Apple M2 Pro, Python 3.13.7, idle machine. The worst of three
passes, quoted whole, so added = (proxy & rules) - direct holds exactly
within the run:
What these numbers mean
The proxy is cheap and nearly flat. Interception, journaling, and re-serialization cost about 0.23 ms on a small call and about 0.56 ms on a 32 KB one, on the slowest hardware tested.
Rules cost more on big payloads, and the cost is yours to choose. Content rules are matched against the payload, so their cost grows with payload size. With all 32 bundled rules loaded that is 0.24 ms on a small call and 2.23 ms at 32 KB.
Most of that work is skipped before it starts. A rule looking for
auditctl cannot fire on a payload with no auditctl in it. Each pattern is
read once and reduced to the literals it requires, and cheap substring searches
decide whether the regex runs at all. Requirements are conjunctions, so a rule
needing systemctl near disable near auditd is skipped on ordinary prose
that merely contains the word "service". On a benign 32 KB call, 17 of the 19
patterns that would otherwise scan the whole payload never run. It changes
speed and nothing else, and AILERON_NO_PREFILTER=1 turns it off if you want
it ruled out during an investigation.
In context. A real MCP server call is typically 10 to 1000 ms. At 2.8 ms for a 32 KB argument with every rule loaded, and 0.47 ms for an ordinary small one, mediation is a small fraction of the call it is mediating.
Caveats, stated plainly. These are sequential stdio round-trips, one call in flight at a time, which is how an agent actually calls tools. This is not a concurrent-client benchmark; a many-client run is on the roadmap. The tool reports mean, median, p95 and p99; these tables quote medians, because medians are stable across runs and p95 is not - tail latency swings with scheduling. Linux is the slower machine because a shared-vCPU CI runner is slower than an idle laptop, and those are the conservative figures CI enforces. Measure on your own hardware before quoting a number.
CI enforces this: a job fails if median overhead regresses more than 2x against
scripts/benchmark_baseline.json, so
performance cannot decay silently. It re-measures once before failing, so a
single slow runner does not cry wolf. The baseline records both the rule-pack
size and the payload shape it was measured against, because a change to either
is more work rather than slower code, and the guard says so instead of
reporting a regression that is not there.
Integrations & ecosystem
- OpenTelemetry GenAI -
aileron exportemitsgen_ai.operation.name/gen_ai.tool.name/gen_ai.agent.namespan attributes plusaileron.event.hash, so Aileron sits beside your existing tracing stack as the evidence layer, not instead of it. - LangChain / CrewAI / any Python framework -
@trackis a plain decorator;track_agentaccepts a free-formframework=label. No framework dependency is required. Seeexamples/langchain_tool_tracking.py. - LiveKit Agents (voice and video) -
@trackwrapsasync deftools too, so a LiveKit@function_toolcan be recorded and policed before it runs, and the wholeAgentSessionsits insidetrack_agent(..., framework="livekit"). LiveKit is the framework being recorded, not a transport: Aileron makes no network calls and gains no dependency on it. Seeexamples/livekit_agent_tracking.py, which runs with the standard library alone when LiveKit is not installed. - MCP - the proxy wraps any stdio MCP server regardless of which client or framework drives it.
- Claude Code -
aileron hookrecords and polices Claude Code's own tools (Bash, Edit, Write, MCP tools) through its hook system; no SDK, no proxy, no network, no change to how Claude Code is launched. See docs/claude-code.md. - Community rules - rule contributions are the intended contribution unit (see Roadmap).
Telemetry & privacy
- Aileron sends no telemetry. No analytics, no phone-home, no network calls anywhere in the library or CLI. If that ever changes, it will be opt-in only, behind a documented RFC - for a security tool, anything less is disqualifying.
- Content capture is off by default. Tool arguments and results are
recorded as SHA-256 digests; raw content is only stored when you pass
capture_content=True/--capture-content. You get a verifiable record of what happened without persisting secrets or PII by accident. Policy rules and the anomaly detector still see the full call in memory at decision time - capture only controls what is persisted, never what is enforced.
Honest limitations
- SDK instrumentation is bypassable.
@trackwraps the functions you decorate; code paths you don't instrument are not recorded. For enforcement that agent code cannot skip, use the MCP proxy - mediation happens in a separate process on the tool-call path. - Policy rules are pattern matching, not intent classification. They
catch known-bad shapes (
rm -rf,id_rsa, exfil patterns); they will not reliably detect novel malicious reasoning. Detection-of-effect complements detection-of-intent tools (garak, PromptGuard); it does not replace them. - Tamper-evidence is not tamper-proof. The chain proves modification after the fact; an attacker with write access can truncate or rewrite the whole log and forge it forward. Signed checkpoints make forgery require the private key - keep keys off the host being recorded, and anchor checkpoints externally (see Roadmap) if you need non-repudiation.
- The Claude Code hook is as strong as Claude Code's hook contract. It
blocks by exit code 2, which Claude Code honours in every permission mode,
but a timed-out or crashed hook fails open unless
onFailure: "block"is set (Claude Code 2.1.295 or later), files pulled in with@never fire a tool hook, a mod handlingtool.checkcan override a hook that is not in managed settings, hooks do not run until the workspace trust dialog is accepted, and the hook runs as the same OS user as the agent, so it makes journal deletion and hook removal evident rather than impossible.
Roadmap
aileron-rulescommunity rule repo - Sigma-for-agents: community detection rules mapped to the OWASP Agentic Security Initiative's threat taxonomy, CI-validated against recorded incident traces.- Sigstore/Rekor checkpoint anchoring - now a companion package,
aileron-anchor, kept separate so this package keeps making no network calls. It pushes signed checkpoints to a public transparency log and checks the local journal against what was anchored, which is what makes tail truncation detectable. - OCSF export - emit Open Cybersecurity Schema Framework events for direct SIEM ingestion (Splunk/Elastic quickstarts).
- Out of scope for v1: eBPF / kernel-level interception. Aileron stays at the MCP-proxy and SDK layer where the semantic meaning of a tool call is still visible; syscall-level tracing is Falco/Cilium territory and would trade agent semantics for volume.
Contributing
Contributions are welcome - see CONTRIBUTING.md. Good
starting points: new detection rules under src/aileron/rules/examples/ and new
framework adapters under examples/. DCO sign-off, no CLA. Security
issues: see SECURITY.md.
License
Apache License 2.0 - see LICENSE.
來源:README.md,提交 b75f0f5
工具
0版本歷史
2- v0.1.6最新Oct 19, 2026
- v0.1.5Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
