Skip to content
AuditKit

Sigstore Rekor · OpenTimestamps · offline verifier · AGPL

Tamper-evident audit logs your auditor can verify without trusting AuditKit.

Every event is hash-chained, signed on ingest, rolled into Merkle roots and anchored to Sigstore Rekor and OpenTimestamps. The verifier runs offline. Our servers can be gone and the proof still holds.

chain
sha256 · RFC 8785
receipts
Ed25519 signed
anchors
Rekor + OTS
verifier
@auditkit/verify · offline

Who this is for

Three people arrive here with three sentences. The sentences are the ones they actually type.

Live demo. Real server, real chain.

Log an event, get a signed receipt, watch it link to the previous one, verify the chain, then watch the root land in Rekor.

throwaway project · tenant = hash of your IP · 30 req/min · reset nightly

No events yet for this visitor. Log one; the receipt appears here as the first block of your own chain.

How an event becomes evidence

Every event hashes its predecessor into a per-tenant chain and comes back with a signed receipt. On each anchor tick, new events roll into a tenant Merkle root, tenant roots into a project root, project roots into one global root, and that one hash goes to two public logs AuditKit cannot edit.

How an event becomes publicly anchoredEach event hashes the previous one into a per-tenant chain. Chains roll into a tenant Merkle root, tenant roots into a project root, project roots into one global root, which is written to Sigstore Rekor and stamped by OpenTimestamps calendars.tenant "acme" chainevent #0prev GENESIShash 3a9f…event #1prev 3a9f…hash c21e…event #2prev c21e…hash 8d07…event_hash = sha256(JCS(header ∥ prev_hash)) · signed Ed25519 on ingesttenant "globex" chainevent #0event #1tenant rootmerkle(acme 0..2)tenant rootmerkle(globex 0..1)project rootmerkle(tenant roots)global rootone per tickRekorOTSappend-only log · inclusion proofcalendar stamp → Bitcoin
  1. 01

    Chain and sign

    event_hash = sha256(JCS(header)) with prev_hash inside the header. The receipt carries position, hashes and an Ed25519 signature; keep it and a later verify proves we never dropped or reordered what we acknowledged.

  2. 02

    Root

    Three Merkle levels keep public-log traffic to one entry per tick while every tenant gets its own root and its own inclusion path. get_proof(event_id) returns the full path.

  3. 03

    Anchor

    The global root is written to Sigstore Rekor (append-only, inclusion proof, final on write) and stamped by OpenTimestamps calendars; the Bitcoin confirmation lands within hours. Time comes from OTS; Rekor gives inclusion, not a timestamp.

Three things an audit table or an identity vendor's log does not do

Public anchoring

Roots go to two independent public logs we cannot edit. Anyone can look up the Rekor entry; the anchors page lists every root we have published, live from the server. Anchor cadence is a plan feature: daily, 5 minutes, 1 minute. Sigstore describes Rekor as "an immutable, tamper-resistant ledger" with a free public instance at rekor.sigstore.dev.

rekor hashedrekord · ots .ots proof stored per root

Offline verifier

Your auditor runs one command against an export file (until the package is published, from the repo: node packages/verify/dist/cli.js <file>; npx @auditkit/verify is the eventual command). It re-hashes every event, walks the chain, checks the signatures against the server key you pin (--pin, from /.well-known/auditkit.json), rebuilds every Merkle root and verifies the Rekor and OTS receipts. No call to AuditKit. Exit code 0 means VALID.

auditkit-verifyexample output · exit 0
# until @auditkit/verify is published, run it from the repo; later: npx @auditkit/verify …
$ node packages/verify/dist/cli.js acme-2026-10.jsonl --pin MCowBQYDK2VwAyEA…
ok   manifest    version 1, tenant ten_01j9k4, positions 0..1283, exported 2026-10-05T09:12:44.102Z
ok   chain       1284 events, prev GENESIS → head 9f3c1a…e1a7
ok   signatures  1284 server signatures verify (pinned key)
ok   payloads    1281 payload commitments verify, 3 erased
?    client_sigs 1284 client signatures present, no client keys given
ok   roots       4 of 4 roots rebuilt and chained to their global root
ok   anchors     8 of 8 anchor receipts verify
     rekor 184201337/24296fb2… for 0..311: verified
     ots alice.btc.calendar.opentimestamps.org for 0..311: verified at 2026-10-04T18:41:08.000Z
     …
ok   coverage    anchored: 0..1283

VALID

Crypto-shredding for erasure requests

Each event's payload is stored separately under a per-event salt. The chain commits to sha256(salt ∥ JCS(payload)), never the payload itself. A GDPR erasure deletes payload and salt; the event row, the chain, the roots and the anchors stay exactly as valid as before, and the erasure is appended to the same chain as a payload.erased event, so the log records that it happened. Immutable log and right-to-erasure stop being in conflict.

This is the pattern the EDPB describes in Guidelines 02/2025: "store only a salted or keyed hash of the personal data … after deletion of the secret key or salt, the hash should not be linkable to the original data". While the salt exists the hash is still personal data; erasure destroys both salt and payload.

POST /v1/erase/01J9K4…        scope: erase

before   payload_commit 7c1e…   payload {"email":"ann@…"}
after    payload_commit 7c1e…   payload null   erased: true

verify   ok  payloads  1281 payload commitments verify, 3 erased
         ok  chain     1284 events, prev GENESIS → head 9f3c…

What the controls actually say

AuditKit supports these controls. It is not a certification and we do not say "compliant". The quotes are verbatim from the linked text; the right column is what the product does about each.

Five lines to your first receipt

Clients with no third-party dependencies for TypeScript (Node 22+, depends only on @auditkit/core) and Python (3.10+, standard library). Both retry on 429 and 5xx with idempotency keys, so a retry replays the original receipt instead of double-logging. Pass a private key and every event is client-signed with a key we never see (Python signing uses the cryptography extra).

Full docs and API reference
// Until @auditkit/sdk is on npm: git clone https://github.com/AuditKitDev/auditkit && pnpm install && pnpm -r build,
// then npm install <clone>/packages/sdk. ESM ("type": "module") and Node 22+.
import { AuditKit } from "@auditkit/sdk";
const audit = new AuditKit({ apiKey: process.env.AUDITKIT_KEY!, baseUrl: process.env.AUDITKIT_URL ?? "https://api.auditkit.dev" });
const receipt = await audit.log({ tenant: "acme", actor: "u_1", action: "invoice.delete", target: "inv_42" });
console.log(receipt.position, receipt.event_hash, receipt.server_sig);

Both SDKs are in the repo and tested; the npm and PyPI packages (auditkit-sdk) publish with v2.0.0. Until then install from the clone as the first line shows. Set AUDITKIT_URL to your own instance when self-hosting.

# Until auditkit-sdk is on PyPI: pip install <clone>/packages/sdk-python  (Python 3.10+)
import os
from auditkit_sdk import AuditKit
audit = AuditKit(api_key=os.environ["AUDITKIT_KEY"], base_url=os.environ.get("AUDITKIT_URL", "https://api.auditkit.dev"))
receipt = audit.log("acme", "u_1", "invoice.delete", target="inv_42")
print(receipt["position"], receipt["event_hash"], receipt["server_sig"])

Both SDKs are in the repo and tested; the npm and PyPI packages (auditkit-sdk) publish with v2.0.0. Until then install from the clone as the first line shows. Set AUDITKIT_URL to your own instance when self-hosting.

curl -X POST https://api.auditkit.dev/v1/events \
  -H "Authorization: Bearer $AUDITKIT_KEY" -H "Content-Type: application/json" \
  -d '{"tenant":"acme","actor":"u_1","action":"invoice.delete","target":"inv_42"}'
# → {"id":"01J…","position":0,"event_hash":"…","prev_hash":"000…","server_sig":"…"}

Connect it to Claude

The MCP server is the REST API's own process at /mcp, not a wrapper. Same data, same scopes. In Claude.ai: Settings → Connectors → Add custom connector → https://auditkit.dev/mcp → sign in with your email → pick the project. Every tool declares a title and read-only / destructive hints so an agent can tell a search from a write. There is no erase tool over MCP, on purpose.

claude mcp add --transport http auditkit https://auditkit.dev/mcp
# first use opens a browser: sign in with your email, pick the project, done

OAuth 2.1 sign-in for Claude.ai and Claude Code; Bearer API keys for everything else. Keys are ak_live_ or ak_test_; the prefix is a label for your own routing and both hit your project. Every new account also gets read access to a shared Sample project, so you can run every read tool before you log anything real.

  • search_eventsSearch audit eventsread-only
  • get_eventGet one audit eventread-only
  • get_proofGet tamper-evidence proof for an eventread-only
  • verify_rangeVerify chain integrity for a tenantread-only
  • list_tenantsList tenantsread-only
  • export_evidenceExport verifier-ready evidenceread-only
  • log_eventRecord an audit eventwrites · not destructive

Pricing

Every feature is on every plan; the tiers differ only in monthly events, payload retention, anchor cadence and support. The same table is on the pricing page, in the dashboard, and in the server's plan table.

Self-host

Free AGPL

Events
Unlimited
Retention
Your disk
Anchor
You set it
Support
GitHub issues
Read the source

Free

$0 forever

Events
10k / month
Retention
30 days
Anchor
Daily
Support
Email
Start free

Pro

$49 per month

Events
500k / month
Retention
1 year
Anchor
Every 5 min
Support
Email
Start with Pro

Business

$199 per month

Events
5M / month
Retention
3 years
Anchor
Every minute
Support
Priority email
Start with Business

Every plan, including Free, has the same features

Plans differ only in monthly events, payload retention, anchor cadence and support. Nothing below is gated by plan.

  • Signed receipts
  • Rekor + OpenTimestamps anchors
  • Client-side signing
  • Crypto-shredding erasure
  • JSONL export + offline verifier
  • Viewer tokens
  • MCP connector

Retention is payload retention: hashes, signatures and anchors are kept so old exports still verify. Billing through Stripe Checkout; no seats, no metering beyond a monthly event counter. Prices in USD. [OWNER: confirm Stripe prices]

Where it sits

AuditKit is the evidence layer. Identity vendors sell retention and SIEM plumbing with no integrity claim; compliance platforms collect evidence but do not give your customers a log; cloud ledgers make the claim but the proof ends at the vendor.

AuditKitWorkOS Audit LogsDatadog Audit TrailDrata / Vantapgaudit / DIY Postgres
Integrity claimHash chain, Ed25519 receipts, roots anchored to Rekor + OpenTimestampsNone on the product or pricing pageNone; retention tiersNo customer-facing audit log; evidence bundles for your auditorA permission (REVOKE), not a proof
Verify without trusting the vendorYes: @auditkit/verify, offline (run from the repo until published)NoNoNon/a: you are the vendor, and so is your DBA
Pricing$0 / $49 / $199 per month$99/mo per 1M events retained + $125/mo per SIEM stream2–3% of spend per monthNot published for this featureYour time: 6–12 weeks for a basic build
Default retention30 days / 1 year / 3 years (payloads); hashes forever30 days by default3 to 90 daysn/aWhatever you set, until someone drops the partition
Erasure without breaking the recordCrypto-shredding per eventNot evaluatedNot evaluatedn/aDELETE breaks any chain you built
Per-tenant proofs for your customers' auditorsMerkle path + public-log receiptsNoNoNoNo
SIEM streamingNo; JSONL export API insteadYes, per-connection feeYes, it is a SIEMNoBuild it

Vendor cells from their public pricing and docs pages, fetched 2026-10-05/06 (WorkOS pricing and docs, Datadog pricing list and Audit Trail docs, Velt's build estimate). Cloud ledgers and open-source options (Azure Confidential Ledger, Google Cloud Audit Logs, immudb, Retraced) are compared on the Postgres and self-built page. We will correct any cell a vendor shows to be out of date.

Questions auditors ask

What does "verify without trusting AuditKit" mean exactly?

The export file carries every event, its signature, the Merkle roots and the public-log receipts. @auditkit/verify re-hashes everything and checks the roots against Rekor's inclusion proof and the OpenTimestamps proof. What you still trust: Rekor's log key, the Bitcoin chain, and the arithmetic. Not our database, not our staff, not our uptime.

Can a database admin at AuditKit rewrite history?

They can change rows. They cannot make the changed rows hash to the roots already written to Rekor and stamped by OpenTimestamps, and they cannot re-sign events without the server key, which lives in the environment, not the database. See the threat model.

How does erasure work with an immutable log?

The chain commits to sha256(salt ∥ payload), not the payload. Erasure deletes the payload and the salt; the commitment stays, so the chain, roots and anchors still verify. The verifier reports the event as erased.

When is an event publicly anchored?

On the next anchor tick for your plan (daily on Free, 5 minutes on Pro, 1 minute on Business). Rekor accepts the root in seconds and is final on write. OpenTimestamps calendars stamp it immediately and the Bitcoin confirmation lands within hours; the receipt upgrades from pending to final.

Does the server check my client signatures?

Only against keys you register. The SDK signs with a private key we never see. Register the public key for a tenant and the server verifies every signed event against it; turn on "require client signatures" and it refuses unsigned events for that tenant. The offline verifier checks the same signatures from the export when you pass your public key, so the server's check is a convenience, not something you have to trust.

Is there a free tier? Can I self-host?

Yes and yes. Free is 10k events a month with daily anchoring and every feature the paid plans have; paid plans buy volume, retention, cadence and support. Self-host is the same code under AGPL: one container, SQLite, the same verifier.

Is AuditKit SOC 2 compliant?

AuditKit has no SOC 2 report today. What it gives you is log integrity you can prove to your own auditor with the verifier, which is the evidence behind log-integrity controls; it is not a compliance certification.

Start logging. Verify in an hour.

Free tier, no card. The first project is created on your first sign-in.

Sign in with email