AXR/n8n/Open source · MIT

A tamper-evident audit log for your n8n workflow.

n8n runs the automation; the only record of what it did is a log you own and could edit. AXR adds a second, independent account: one Code node at the end of your workflow emits a cryptographically signed receipt of each consequential action — verifiable by anyone holding the public key, with no access to your n8n instance.

Integration One Code node Hot-path latency None (anchoring is out-of-band) Runtime dependencies Zero

n8n logs the run. It can't prove it.

An n8n execution log answers "what happened" only as long as you trust the operator who holds it. It is a record you can edit, prune, or lose — and nobody outside your infrastructure can confirm it was not altered after the fact. For a workflow that books, prices, messages, moves money, or changes records on someone's behalf, that is exactly the record an auditor, a customer, or a regulator cannot take on trust.

The EU AI Act makes automatic event logging a design requirement for high-risk systems (Article 12) and puts retention on deployers (Article 26), with obligations applying from 2 August 2026. A mutable execution log is not designed for that question. A signed receipt is.

An n8n execution you can rewrite is a story. A receipt anyone can verify is a record.

One Code node, at the end of the workflow.

AXR is not an n8n replacement or a fork — it is a thin accountability layer that sits inside the workflow you already have. The receipt generator is a single Code node placed before the response. It reads the outputs of the decision-relevant nodes and produces every receipt in one pass. Anchoring and monitoring run outside the workflow, so the live hot path gains no latency and no new dependency.

  1. Mark the decision nodes. Each decision-relevant node attaches the exact input it consumed, so the receipt hashes what the step actually saw — not a uniform proxy.
  2. Drop in the AXR Code node. One node at the end emits the step and workflow receipts, each signed with Ed25519 over a canonical (RFC 8785) serialisation. Generation is fail-open: a missing key degrades to a loud error, it never breaks the business process.
  3. Append to an immutable log. Receipts are written one per line to an append-only JSON Lines file on a bind-mounted volume — outside n8n's execution data. n8n prunes execution history by default (EXECUTIONS_DATA_PRUNE / EXECUTIONS_DATA_MAX_AGE); because the receipt chain lives on durable external storage, that pruning never touches it.
  4. Anchor and verify independently. A sidecar batches receipt hashes into a Merkle tree and commits signed tree heads to an external backend; a standalone, zero-dependency script verifies a whole chain offline, in any language, from nothing but the public key.

Illustrative step receipt from an n8n booking node

{
  "axr_version": "0.2.1",
  "agent_id":    "axr:agent:eco-clean:v5.1",
  "step": { "name": "Create Booking", "kind": "side_effecting" },
  "io": {
    "input_hash":  "sha256:9f2c…b41a",
    "output_hash": "sha256:1d7e…0c88",
    "decision":    "BOOKING_CONFIRMED"
  },
  "logic_version": "5.1",
  "logic_hash":    "sha256:a3b9…77e2",
  "previous_receipt_hash": "sha256:5c10…d9f3",
  "timestamp":  "2026-06-13T09:14:22Z",
  "signature":  "ed25519:K8f…/Qb2Aw=="
}
Signature valid Change one byte of any field and the signature no longer verifies. That is the whole principle — and it is enough.

Already running on a live n8n workflow.

AXR runs in production on a live booking workflow for ECO Clean HU, built in n8n. Six of the workflow's twenty nodes are receipt-bearing, and the log — now past 227 signed receipts — has been anchored hourly into one Merkle tree since June 2026. Standing up that accountability layer did something its operator did not expect: it surfaced four real bugs that pre-dated AXR — none of them tampering. That is the second thing a receipt buys beyond tamper-evidence: behavioral legibility, the run made readable enough that a contradiction surfaces on its own.

  • Bug B Every run fired all three response branches at once — a rejection still sent a success email. The receipt's final_status made the contradiction immediate.
  • Bug C Rejections returned "unknown_error" with the customer's own message echoed back; the real reason was lost. The receipt recorded the correct status on every run.
  • Bug D A recheck conflict produced an HTTP 200 with an empty body, while the receipt was a complete, signed 5-step SLOT_TAKEN chain — exactly the gap AXR is built to surface.
  • Bug E After a bugfix bumped the logic to v5.1, receipts kept attesting v5.0. Code-hash fingerprints now replace hand-written labels, and CI fails on drift.

Planned next: a mark node on n8n's Error Trigger path, so a hard failure — a node throw or a workflow error-out — also produces a signed, failure-state receipt. A failed run is often the one you most need evidence of. This extends generator coverage only; the frozen 1.x wire format is untouched.

Read the full design, or verify a log yourself.

This page is the n8n-shaped view of a general primitive. The full design — the threat model, the maturity layers, the EU AI Act / GDPR control mapping, and the adversarial 15/15 tamper test — lives on the main AXR page. And AXR proves its own construction: its build journal is itself a signed, anchored AXR log you can re-verify in your browser.