Tamper-evident flight recorder for AI agents - hash-chained, signed audit log of every tool call, with MCP proxy policy enforcement and anomaly detection.
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/aileron-sh/aileron && cp aileron/*.md ~/.claude/agents/Subagents overview
# Aileron
<!-- mcp-name: io.github.aileron-sh/aileron -->
[](LICENSE)
[](https://github.com/Aileron-sh/aileron/actions/workflows/ci.yml)
[](pyproject.toml)
**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 verify` says exactly where
the chain broke.
- **Policy enforcement on tool calls.** Sigma-like YAML rules with
`allow` / `alert` / `block` actions, 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
```console
$ 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
```
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
| Feature | What you get |
|---|---|
| Hash-chained journal | Append-only JSONL; each event's `prev_hash` links to the previous event's SHA-256 hash; genesis is `0x00…00` |
| Signed checkpoints | Ed25519 signature over the chain tip, verifiable offline against the public key (`aileron sign-checkpoint` / `verify-checkpoint`). Checkpoints cover a *prefix*: appending later events never invalidates them; truncating or rewriting the signed prefix does |
| Policy rules | **32 bundled rules** covering credential theft, cloud metadata abuse, exfiltration, supply chain, persistence, anti-forensics, database destruction, and prompt-injection artifacts. Sigma-like YAML; substring, regex, and dotted-key matchers. Rules are evaluated against the full call **in memory**, so content rules fire even in digest-only mode |
| Behavioral anomaly detection | Rolling baselines flag first-seen tools, rate spikes (>3x baseline), and novel tool-call sequences - live via the SDK (`baseline=`) or offline via `aileron detect` |
| MCP stdio proxy | Sits between any MCP client and server; logs and mediates every `tools/call` before it reaches the child process. Verified against the official filesystem and memory servers, not just test doubles |
| MCP server mode | `aileron serve` exposes your journals read-only, so an assistant can answer "what did the agent touch?" from the record. Listed in the [official MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.aileron-sh/aileron` |
| OTel GenAI export | Events export as `gen_ai.*`-aligned span dicts (`aileron export`) for your existing collector |
| HTML incident reports | Single file, inline CSS, no external assets, verification badge (`VERIFIED` / `TAMPERED at seq N`) |
| Privacy by default | Tool arguments/results are recorded as digests only, unless you opt in with `--capture-content` |
## Usage
### SDK: `@track` decorator
```python
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
```
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
```python
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 proxy: framework-agnostic interception
Wrap any MCP server. Every `tools/call` is logged and policy-checked *before*
the child process sees it:
```console
$ aileron init # seeds a ./rules directory with starter rules
$ aileron proxy --log run.chain.jsonl --rules rules -- \
npx -y @modelcontextprotocol/server-filesystem /tmp
```
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](#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.
### 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:
```console
$ aileron serve --root ./journals
```
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 `--root`** and only `.jsonl` opens. Otherwise
`verify_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_content` governs what the journal
stores. It never widens what this server hands back, and errors never echo
file contents.
### Policy rules
```yaml
# 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
```
Dry-run rules against a recorded session: `aileron rules test rules/ run.chain.jsonl`
## How it works
```
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
```
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.
## Performance
The proxy adds **well under a millisecond** per `tools/call`. Matching the full
32-rule bundled pack against the payload is What people ask about aileron
What is aileron-sh/aileron?
+
aileron-sh/aileron is subagents for the Claude AI ecosystem. Tamper-evident flight recorder for AI agents - hash-chained, signed audit log of every tool call, with MCP proxy policy enforcement and anomaly detection. It has 1 GitHub stars and its last recorded update is dated 2026-08-25.
How do I install aileron?
+
You can install aileron by cloning the repository (https://github.com/aileron-sh/aileron) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is aileron-sh/aileron safe to use?
+
Our security agent has analyzed aileron-sh/aileron and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains aileron-sh/aileron?
+
aileron-sh/aileron is maintained by aileron-sh. The last recorded GitHub activity is dated 2026-08-25, with 1 open issues.
Are there alternatives to aileron?
+
Yes. On ClaudeWave you can browse similar subagents at /categories/agents, sorted by popularity or recent activity.
Deploy aileron to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/aileron-sh-aileron)<a href="https://claudewave.com/repo/aileron-sh-aileron"><img src="https://claudewave.com/api/badge/aileron-sh-aileron" alt="Featured on ClaudeWave: aileron-sh/aileron" width="320" height="64" /></a>More Subagents
The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
The agent that grows with you
Java 面试 & 后端通用面试指南,覆盖计算机基础、数据库、分布式、高并发、系统设计与 AI 应用开发
Build Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.
The agent engineering platform.
Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.