Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AskLedger · Receipts SDK

Open-source, vendor-neutral cryptographic trust substrate for enterprise AI. Every AI invocation produces a signed, hash-chained, tamper-evident receipt that auditors, regulators, and insurers verify independently with only the public key. No platform dependency.

Open spec · PL-RFC-001…010 · Conformance · Architecture · Integrations · Policy mapping · Security · Contributing

License Node Spec Conformance Tests Hardening


The problem

AI now makes consequential decisions: approving a loan, denying a claim, taking an autonomous action. When an auditor, regulator, or court later asks what your AI did and why, an ordinary application log is not an answer. Logs are editable, they live inside your own systems, and they prove nothing to someone who does not already trust you.

Regulation is catching up. The EU AI Act (Article 12 tamper-evident logging for high-risk AI, from 2 December 2027; Article 50 transparency from 2 August 2026), NIST AI RMF, ISO 42001, India's RBI and the UAE's CBUAE increasingly require a tamper-evident record of what a high-risk AI system decided. That record is exactly what this SDK produces.

What it does

AskLedger wraps any AI call and emits a signed, hash-chained, tamper-evident receipt for every decision: the model, the inputs (as hashes), the rule that governed it, the timestamp, and the signing key. Canonicalized (RFC 8785), signed (Ed25519), timestamped (RFC 3161), and verifiable by anyone with only the public key. Nothing confidential leaves your environment, a receipt records hashes and metadata, never raw prompts.

  • For risk, compliance and audit teams: portable evidence that maps to the frameworks you answer to and holds up independently, without trusting the vendor.
  • For engineers: one wrapper around the client you already use, application code unchanged. Five language SDKs, an open specification, Apache-2.0.

Sign and verify your first receipt in under a minute (below), or jump to how it works, performance, or examples.


Project status

v0.13 · live on npm. The cryptographic core is hardened and independently verifiable, shared conformance vectors enforce byte-identical RFC 8785 canonicalization and SHA-256 across the TypeScript, Python, Go, Rust and Java SDKs, and a documented hardening checklist is checked in CI. SDK, integrations, browser extension, console, public verifier, specification, and conformance program are publicly available. A third-party penetration test and SOC 2 Type II report are scoped for Q4 2026 - Q1 2027, and the hosted SaaS is in development. We are at the design-partner stage and welcome architectural review, pilot interest, and standards-body co-authorship.


The five layers

AskLedger is a five-layer model. Layers 1 to 4 are the cryptographic proof engine; layer 5 is the governance and ROI program built on top. Every layer below ships in this SDK and is exported from the public API.

Layer What it does Public API in this SDK
L1 · Prevent Pre-execution guardian: an independent verdict (approve / concerns / reject) before an irreversible action, signed under its own key and bound to the exact action, so "approve A, run B" fails. Supports N-of-M review. signPreVerdict, verifyPreVerdict, assertActionCleared, reviewNofM
L2 · Prove Cryptographic evidence: a signed, hash-chained receipt per AI action (Ed25519, RFC 8785 canonical JSON, RFC 3161 timestamp), independently verifiable with only a public key. signReceipt, verifyReceipt, verifyChain
L3 · Trace Execution traceability: reconstruct and verify a multi-step workflow from its receipts, and group many receipts into one Merkle evidence bundle. reconstructWorkflow, verifyWorkflow
L4 · Assure Rule-based assurance: classify each receipt on the L0–L3 ladder (Declared / Signed / Attested / Anchored) and check governing rules, computed from the evidence, not asserted. assuranceLevel, checkRules
L5 · Govern Governance & ROI: turn the evidence chain into verified savings against a signed baseline, plus compliance-ready reporting. buildBaseline, proveSavings, verifyBaseline

Layers 1 to 4 are cryptographically verifiable and open source here; layer 5's hosted governance, regulator portal, and evidence packs are the commercial layer (open-core).


How it works

The SDK sits beside your AI call. It signs and hash-chains each decision into a receipt, which anyone can later verify with the public key alone, without trusting you or reaching into your systems.

sequenceDiagram
    participant App as Your app
    participant SDK as AskLedger SDK
    participant Store as Your ledger (append-only)
    participant V as Verifier (auditor / regulator)
    App->>SDK: AI decision (event)
    SDK->>SDK: canonicalize (RFC 8785) + hash (SHA-256)
    SDK->>SDK: link previous_receipt_hash (hash chain)
    SDK->>SDK: sign (Ed25519) + timestamp (RFC 3161)
    SDK-->>App: signed receipt
    App->>Store: append receipt
    Note over V,Store: later, independently
    V->>Store: fetch receipt(s)
    V->>V: verify signature with public key only
    V->>V: recompute hash, check chain link
    V-->>V: VALID or TAMPERED, no trust in the vendor required
Loading

The receipt is the atomic signed unit. Every other layer links to it by hash rather than nesting inside the signature:

flowchart LR
    A[AI action] --> L1[L1 Prevent<br/>guardian verdict]
    L1 --> L2[L2 Prove<br/>signed receipt]
    L2 --> L3[L3 Trace<br/>workflow + Merkle bundle]
    L3 --> L4[L4 Assure<br/>assurance level + rules]
    L4 --> L5[L5 Govern<br/>baseline, savings, reporting]
    L2 -. verify with public key .-> V[(Independent<br/>verifier)]
Loading

Full detail in docs/ARCHITECTURE.md and the protocol spec.


Install

npm install @askledger/receipts-sdk

Or install from source:

git clone https://github.com/askledger/receipts-sdk
cd receipts-sdk
npm install
npm run build

Sign your first receipt

import { generateKeyPair, signReceipt, verifyReceipt } from "@askledger/receipts-sdk";

const keypair = generateKeyPair();
const receipt = signReceipt({
  event: {
    schema_version: "1.0",
    tenant_id: "acme",
    event_type: "gateway.request",
    source_system: "my-app",
    event_id: "evt-001",
    captured_at: new Date().toISOString(),
    subject: { ai_vendor: "anthropic", ai_model: "claude-sonnet-4-6" },
    payload: { input_classification: "internal", output_classification: "internal" },
  },
  keypair,
});

const result = verifyReceipt(receipt, {
  publicKeys: { [keypair.kid]: keypair.public_key },
});
console.log(result.valid); // true

That's it. Six lines and you have a regulator-verifiable receipt.

Wrap your AI vendor

import OpenAI from "openai";
import { wrapOpenAI, generateKeyPair } from "@askledger/receipts-sdk";

const client = wrapOpenAI(new OpenAI({ apiKey }), {
  tenantId: "acme",
  keypair: generateKeyPair(),       // production: HSM-backed
  onReceipt: async (r) => store.append(r),
});

// Your application code is unchanged.
const resp = await client.chat.completions.create({ model: "gpt-5", messages });
console.log(resp.x_ledger_receipt_id);   // cryptographic evidence id

Adapters available today:

  • wrapOpenAI, the OpenAI client
  • wrapAnthropic, the Anthropic client
  • withReceipts(fetch), any HTTP-based vendor at the network layer (also captures OpenAI Agents SDK and other agent frameworks' model calls, since they go over HTTP)
  • ReceiptsCallbackHandler, LangChain, and by extension LangGraph, which propagates LangChain callbacks through its graph nodes
// LangChain / LangGraph: attach the handler to any model or graph node.
import { ReceiptsCallbackHandler } from "@askledger/receipts-sdk/adapters/langchain";
const handler = new ReceiptsCallbackHandler({ tenantId: "acme", keypair, onReceipt });
const llm = new ChatAnthropic({ model, callbacks: [handler] }); // used directly or inside a LangGraph node

Also available (first-class, exported, tested):

  • attachAgentReceipts(runner, ctx), OpenAI Agents SDK: a receipt per agent turn, tool call, and handoff via the RunHooks lifecycle. Ships with a live integration test against @openai/agents.
  • plLlamaIndexHandler(ctx), LlamaIndex
  • plMastraListener(ctx), Mastra
  • plReceiptsMiddleware(ctx), Vercel AI SDK (ai@4+ middleware)

Performance

Measured on the reference TypeScript SDK (Node v22, Apple silicon, 5,000 iterations after 200 warmup). Reproduce with npm run bench.

Operation mean p50 p95 p99
Canonicalize (RFC 8785) 3.9 µs 3.4 µs 5.5 µs 7.8 µs
SHA-256 (canonical bytes) 5.3 µs 4.8 µs 6.6 µs 13.7 µs
Ed25519 sign 405 µs 387 µs 520 µs 605 µs
Ed25519 verify 1.94 ms 1.76 ms 2.45 ms 5.76 ms
signReceipt (end to end) 670 µs 603 µs 960 µs 1.43 ms
verifyReceipt (end to end) 1.76 ms 1.71 ms 1.96 ms 2.32 ms
  • Overhead is sub-millisecond CPU and never blocks the wrapped AI call (typically hundreds of ms to seconds), so the receipt is noise against model latency.
  • signReceipt end to end includes file I/O for chain state in the reference SDK; production swaps the file backend for Postgres, and signing for an HSM/KMS.
  • Receipt size ≈ 1.9 KB of JSON (measured), constant regardless of prompt or response size, because only hashes and metadata are stored, never raw content.
  • Verify is heavier than sign (Ed25519 verification cost); it runs offline, out of the request path, by whoever audits.

Try it without installing

git clone https://github.com/askledger/receipts-sdk.git && cd receipts-sdk
npm install && npm run build
node dist/cli.js demo

You'll see output like:

────────────────────────────────────────────────────────────────────────
AskLedger, Receipts SDK · Demo
────────────────────────────────────────────────────────────────────────

1. Generating Ed25519 keypair…
   kid: dev-3a7c9b2e8f4a

2. Signing a sample AI event…
   receipt_id:   01HXYZ123ABC...
   receipt_hash: 9a4f8e0c2b1d3a6c...
   chain_height: 1

3. Verifying receipt independently (no Ledger server needed)…
   ✓ canonical hash matches
   ✓ Ed25519 signature valid

✓ RECEIPT VALID

That's it. The receipt is in .ledger/last-receipt.json. The keypair is in .ledger/keys/default.json. The chain state is in .ledger/chains/. None of this required a network call to AskLedger. A regulator verifying this receipt only needs the public key.


How a receipt looks

{
  "receipt": {
    "schema_version": "1.0",
    "receipt_id": "01HXYZ123ABC...",
    "tenant_id": "demo-tenant",
    "issued_at": "2026-05-13T10:30:00.123456789Z",
    "event": {
      "schema_version": "1.0",
      "event_type": "ide.completion",
      "source_system": "vs-code-plugin",
      "captured_at": "2026-05-13T10:30:00.000Z",
      "subject": {
        "ai_vendor": "anthropic",
        "ai_model": "claude-sonnet-4-6",
        "ai_capability": "code-completion"
      },
      "payload": {
        "input_hash": "9a4f8e0c2b1d3a6c...",
        "input_classification": "internal",
        "input_token_count": 245
      }
    },
    "integrity": {
      "previous_receipt_hash": "0000...0000",
      "receipt_hash": "9a4f8e0c2b1d3a6c...",
      "chain_height": 1
    }
  },
  "signatures": [
    {
      "alg": "EdDSA",
      "kid": "dev-3a7c9b2e8f4a",
      "sig": "base64-encoded-Ed25519-signature..."
    }
  ]
}

Every field is part of the canonical hash. Any modification to any field, including reordering keys, breaks the signature.

Optional: evidence_refs

A receipt MAY carry an optional top-level evidence_refs array that references external evidence or attestation artifacts by digest (the artifact itself is never embedded). It is strictly additive, receipts without it sign and verify exactly as before, and when present it is part of the canonical bytes, so it is covered by both integrity.receipt_hash and the signature.

"evidence_refs": [
  {
    "kind": "attestation",
    "hash": "3b1f...c9",
    "alg": "sha256",
    "uri": "https://evidence.example.com/artifacts/3b1f...c9",
    "status": "pass"
  }
]

Only kind and hash are required per entry; alg, uri, and status are optional. Pass it via signReceipt({ event, keypair, evidenceRefs: [...] }).


Programmatic usage

import {
  generateKeyPair,
  signReceipt,
  verifyReceipt,
} from "@askledger/receipts-sdk";

// 1. Generate (or load) a keypair
const kp = generateKeyPair();

// 2. Sign an AI event
const signed = signReceipt({
  event: {
    schema_version: "1.0",
    tenant_id: "tenant-001",
    event_type: "ide.completion",
    source_system: "vs-code-plugin",
    event_id: "evt-123",
    captured_at: new Date().toISOString(),
    subject: {
      ai_vendor: "anthropic",
      ai_model: "claude-sonnet-4-6",
      ai_capability: "code-completion",
    },
  },
  keypair: kp,
});

// 3. Anyone can verify with just the public key
const result = verifyReceipt(signed, {
  publicKeys: { [kp.kid]: kp.public_key },
});

console.log(result.valid); // true

CLI reference

The CLI ships as a bin, so once the package is published you can run it directly with npx, no clone or build required:

# Verify a receipt against a public key (published form)
npx @askledger/receipts-sdk verify receipt.json

# ...same for every subcommand
npx @askledger/receipts-sdk keygen --out .ledger/keys/default.json
npx @askledger/receipts-sdk sign examples/event.json
npx @askledger/receipts-sdk demo

The npx @askledger/receipts-sdk … form works from the published package (this bin ships with 0.8.0). If you are working from a local clone, build first (npm run build) and use the node dist/cli.js … form below.

# Generate a keypair (HSM-backed in production; JSON file in dev)
node dist/cli.js keygen --out .ledger/keys/default.json

# Sign an event (auto-chains per tenant)
node dist/cli.js sign examples/event.json

# Verify a receipt against a public key
node dist/cli.js verify .ledger/last-receipt.json

# Verify chain continuity to a previous receipt
node dist/cli.js verify .ledger/last-receipt.json --prev .ledger/prev.json

# Full demo cycle
node dist/cli.js demo

End-to-end: keygen → sign → verify → bundle → verify-bundle

The CLI drives all three layers by hand, one keypair, a signed chain, and a single verifiable evidence bundle:

# 1) Key
node dist/cli.js keygen --out keys.json

# 2) Sign, optionally BIND an external correctness proof (Layer 4, repeatable).
#    file=<path> is read and SHA-256-hashed for you; or pass hash=<hexdigest>.
node dist/cli.js sign examples/event.json --key keys.json --out r1.json \
  --evidence-ref "kind=rule-check,file=./rule-report.json,status=pass"
node dist/cli.js sign examples/event.json --key keys.json --out r2.json

# 3) Verify a single receipt (reports any attached evidence_refs)
node dist/cli.js verify r1.json --key keys.json

# 4) Bundle many receipts into one Merkle-rooted evidence bundle.
#    Accepts multiple single-receipt files OR one array-of-receipts file.
node dist/cli.js bundle r1.json r2.json --out bundle.json --title "Q3 Evidence"

# 5) Verify the bundle: pack integrity + inclusion + (with --key) signatures.
#    Exits non-zero on any failure.
node dist/cli.js verify-bundle bundle.json --key keys.json

# 6) See what it all cost, a local, single-tenant usage & cost dashboard
#    built from your own signed receipts (scans .ledger/ by default).
node dist/cli.js dashboard
node dist/cli.js dashboard --html   # writes a self-contained HTML report

Three layers, one CLI:

  • Integrity: sign / verify (RFC 8785 hash chain + Ed25519). The receipt is authentic and untampered.
  • Traceability: bundle / verify-bundle (Merkle evidence bundle). Many receipts → one artifact with a single root hash.
  • Correctness: sign --evidence-ref binds an external proof's digest into the signed body.

Honest scope: the SDK binds an external correctness proof into the signed receipt (its digest is covered by the signature). It does not perform formal verification, the proof is produced by an external prover; the SDK makes it tamper-evident and auditable. An evidence bundle and an evidence pack are the same artifact (the buildEvidenceBundle / buildEvidencePack API names are aliases).

See your spend & savings, the free local dashboard

dashboard turns the receipts you already signed into the numbers a team wants on day one, no account, no network, no hosted service:

node dist/cli.js dashboard [paths...]   # defaults to scanning .ledger/
node dist/cli.js dashboard --html [path]
  • Spend & usage: estimated cost, requests, tokens, and per-model / per-app breakdowns, computed locally from the built-in pricing table.
  • Savings opportunities: flags over-tiered workloads (a premium model doing short, simple calls) grouped by (model × application), and quantifies each with an exact counterfactual: the same recorded calls repriced on the cheaper same-vendor tier. It nudges only light workloads, so the big model keeps the heavy, high-value calls.
  • Integrity: how many receipts are signed, the chain height, and how many carry correctness bindings.

Honest scope: cost is an estimate from your instrumented receipts and the local pricing table, not a bill. Unknown models are counted but excluded and flagged, never guessed. This is single-tenant and blind to un-instrumented ("shadow") AI; the savings figures are heuristic hints to test, not a promise. Cross-system discovery, billing ingestion, and verified savings (baseline → signed proof) are the hosted AskLedger platform.

Ask your receipts, natural-language query & alerts

Ask a question in plain English and get an answer grounded in real receipts, every result cites the receipt ids it came from, so it's checkable, never invented:

node dist/cli.js query "how much did we spend by model?"
node dist/cli.js query "show the blocked loan decisions"
node dist/cli.js query "anything with pii?"            # routes to alerts
node dist/cli.js query "gpt-5 calls over $0.05 last week" --llm   # free-form
node dist/cli.js alerts                                # flag the critical stuff
  • query: an offline, deterministic parser handles common questions for free (filter / count / aggregate over model, app, decision, time, cost and token thresholds, sensitive data, evidence and signature state). --llm handles free-form phrasing, the model only turns your words into a query; the data always comes from signed receipts. It's provider-neutral: the CLI's --llm uses @anthropic-ai/sdk (optional dep) + ANTHROPIC_API_KEY by default, but programmatically you can plug in any model by passing a complete function:

    import { parseQueryLLM, runQuery } from "@askledger/receipts-sdk";
    
    const q = await parseQueryLLM("blocked loan decisions on opus last week", {
      complete: async ({ system, prompt }) => callYourModel(system, prompt), // OpenAI, Gemini, local, …
    });
    const result = runQuery(receipts, q); // grounded + cited, as always
  • alerts: an explainable rules engine that flags what's worth a look: blocked/denied decisions, sensitive data (pii/pci/mnpi), unsigned records, high-stakes decisions with no bound evidence, over-tiering, and cost spikes. Each alert names the exact receipt ids behind it. Ships honest defaults; add your own rules programmatically via runAlerts(receipts, { extraRules }).

Honest scope: the NL layer decides which receipts to show and how to summarize them, it never asserts anything the receipts don't already say, and it reports how it interpreted the question. Local and single-tenant; hosted, real-time, cross-system query and alerting is the enterprise tier.


How it works · the cryptographic design

Layer Choice Why
Canonicalization RFC 8785 (JCS) Deterministic JSON byte representation. Independent verifiers compute identical hashes from identical data. The foundational requirement for regulator-independent verification.
Hashing SHA-256 Standard, audited, well-understood security margin.
Signing Ed25519 (EdDSA) Fast (~70µs/sig), deterministic (no random nonce reuse risk), used by Signal, WireGuard, Sigstore.
Encoding JWS base64 Standard, parseable across platforms.
Chain Per-tenant append-only hash chain Each receipt's previous_receipt_hash is SHA-256 of the prior receipt's canonical bytes. Tampering with any historical receipt breaks every subsequent one.
ID generation UUIDv7 Sortable, embedded timestamp, collision-resistant.
Post-quantum readiness Hybrid signature scheme planned for v2 (Ed25519 + Dilithium) Practical quantum threats are 8–12 years out; retention is 7–10 years. Migration plan documented.

Implementation libraries:


Standards & compatibility

This SDK composes with rather than competes against the standards already used in software supply-chain security:

Standard Relationship
Sigstore Model Signing (OMS) Used for model identity verification within receipts
in-toto Attestation Framework (ITE-6) Envelope format reference for provenance claims
SLSA Build-time attestation reference; receipts cover runtime
OpenTelemetry GenAI Semantic Conventions Event field alignment
OWASP AIBOM AI Bill of Materials populated from receipts
SPIFFE/SPIRE Workload identity for service-to-service calls

We are not reinventing the cryptographic primitives. We are composing them into a layer specifically for AI runtime accountability: which none of the existing standards target.


Roadmap

Shipped

  • Five language implementations, one wire format: TypeScript on npm; Python, Go, Rust and Java from source, all cross-verified against shared conformance vectors
  • The full five-layer model (see The five layers), prevent-first: L1 a pre-execution guardian (prevents the wrong action), L2 cryptographic evidence (proves what), L3 execution traceability (proves how), L4 rule-based assurance (proves why), and L5 governance and verified ROI (proves the value). Layers 1 to 4 are the open cryptographic proof engine; all are exported from the SDK
  • RFC 3161 timestamping, Merkle commitments and a transparency log, and HSM/KMS signing (AWS KMS, Azure Key Vault, GCP KMS, PKCS#11)
  • Verified savings (sign a baseline, prove the realized saving, verify it) and zero-instrumentation spend scan
  • Browser playground and verifier, plus SLSA provenance and a CycloneDX SBOM on every release

Next

  • Publish the Python, Rust and Java SDKs to their registries (PyPI, crates.io, Maven Central)
  • Transparency-log connector (Rekor)
  • Bridge to OpenTelemetry GenAI conventions
  • Customer-managed-key reference deployments

Toward v1.0

  • Stable wire format with versioning guarantees
  • Linux Foundation AI hosted standard
  • A third-party verifier ecosystem

Try it without installing

A browser-based playground and verifier ship in this repository at site/playground.html and site/verify.html. Open either file in a browser to generate a keypair, sign a sample event, and verify the resulting receipt, entirely client-side, no server, no install.

A hosted version is live at askledger.github.io/receipts-sdk/playground.html.


Documentation

Document What's inside
Receipts Protocol Spec v0.1 The formal envelope, schema, hashing and verification rules, IETF-style. Candidate for Linux Foundation AI hosting.
Architecture Layered overview, file-by-file walk-through, design decisions, performance numbers.
Examples folder End-to-end integration patterns.
Python SDK Wire-format compatible Python implementation.
Conformance vectors Shared cross-language test vectors. Any new SDK passes conformance by matching these byte-for-byte.
CHANGELOG Version history + roadmap to v1.0.
Contributing How to build, test, propose changes.
Security policy How to report vulnerabilities.

Auto-capture adapters, supporting any AI tool

The SDK ships drop-in capture adapters so every AI invocation in your stack emits a signed receipt without changing application code.

Adapter What it wraps One-liner
wrapOpenAI(client, ctx) The official openai SDK and any OpenAI-compatible provider (LiteLLM, Groq, Together, Mistral OpenAI-compat, DeepSeek, Anyscale) Wraps chat.completions.create + embeddings.create
wrapAnthropic(client, ctx) The official @anthropic-ai/sdk Wraps messages.create
withReceipts(ctx) Any global fetch Detects calls to OpenAI, Azure OpenAI, Anthropic, Google Gemini, Bedrock, Cohere, Hugging Face, Mistral, Groq, Together, Vercel AI Gateway. Custom endpoints via extraPatterns.
ReceiptsCallbackHandler LangChain.js and LangGraph Implements BaseCallbackHandler; drop into any chain, agent, or graph node (LangGraph propagates LangChain callbacks)
attachAgentReceipts(runner, ctx) OpenAI Agents SDK (@openai/agents) Subscribes to the RunHooks lifecycle; a receipt per agent turn, tool call, and handoff. Integration-tested against the live package
plLlamaIndexHandler(ctx) LlamaIndex Callback for llm-end; a receipt per LLM completion
plMastraListener(ctx) Mastra Telemetry listener; a receipt per agent step
plReceiptsMiddleware(ctx) Vercel AI SDK (ai@4+) wrapGenerate middleware for generateText / streamText

Pattern:

import OpenAI from "openai";
import { wrapOpenAI, generateKeyPair } from "@askledger/receipts-sdk";

const client = wrapOpenAI(new OpenAI({ apiKey }), {
  tenantId: "acme-corp",
  keypair: generateKeyPair(),
  onReceipt: async (r) => store.append(r),  // ship to durable store
});

// Application code is unchanged
const resp = await client.chat.completions.create({...});
console.log(resp.x_ledger_receipt_id);   // cryptographic evidence id

Errors from the wrapped client always propagate, receipts never take down the AI call they instrument.


Evidence export · SIEM connectors

Your SIEM stores logs your own systems wrote, mutable and self-attested. Receipts make what lands there provable. Push signed receipts into the platform your analysts and auditors already use; they remain independently verifiable after they arrive.

Ships with sinks for Splunk HEC, syslog/CEF (QRadar, ArcSight), a generic webhook (Microsoft Sentinel, Elastic, Chronicle, in-house pipelines), and a JSONL file / object-storage drop (the universal fallback every SIEM can ingest).

import {
  exportReceipts, SplunkHecSink, SyslogSink, WebhookSink, FileSink,
} from "@askledger/receipts-sdk";

const report = await exportReceipts(receipts, {
  sinks: [
    new SplunkHecSink({ url: "https://splunk.internal:8088", token: process.env.HEC_TOKEN!, index: "ai_evidence" }),
    new SyslogSink({ host: "qradar.internal", format: "cef" }),   // CEF for QRadar / ArcSight
    new WebhookSink({ url: "https://sentinel.internal/ingest" }),
    new FileSink({ path: "/var/log/askledger/receipts.jsonl" }),
  ],
  includeAssurance: true,  // attach the L0–L3 grade
  includeReceipt: true,    // embed the signed receipt so the SIEM record stays verifiable
  batchSize: 200,
});

report.results; // per-sink delivery outcome; one failing sink never blocks the others

Privacy by default: the raw event payload (business data) is excluded unless you set includePayload. Operator-configured only: there is no default endpoint and the SDK never transmits anything you have not configured.


Multi-language

SDK Language Status Conformance
@askledger/receipts-sdk TypeScript / Node 18+ / browsers live on npm · 575 tests (571 pass, 4 HSM-live skipped) Reference
askledger-receipts (Python, import askledger.receipts) Python 3.10+ From source (not yet on PyPI) · cross-verified against TS vectors Cross-verified
github.com/askledger/receipts-sdk/go-sdk Go 1.22+ go get (git-based) · cross-verified against TS vectors Cross-verified
askledger-receipts (Rust crate) Rust 1.75+ From source (git dep, not yet on crates.io) · cross-verified against TS vectors Cross-verified
org.askledger:receipts-sdk (Java) Java 17+ From source (not yet on Maven Central) · cross-verified against TS vectors Cross-verified

Wire-format compatibility is enforced by shared conformance vectors that every SDK must pass.


Production hardening modules

These are the v0.2 surface that turns the reference SDK into a production-deployable substrate.

Module What it provides When you need it
SoftwareSigningProvider In-memory Ed25519 keys Dev, browser playground, SMB
HSMSigningProvider Interface for PKCS#11 / AWS CloudHSM / Azure Key Vault / GCP KMS Regulated BFSI, FIPS-required deployments
TSAClient (RFC 3161) Real RFC 3161 TimeStampReq encoder + network client (default: FreeTSA; commercial TSAs via Basic Auth) When you need independently provable "when this was signed"
buildBatch / verifyInclusion (Merkle) SHA-256 binary Merkle tree with inclusion proofs (RFC 9162 leaf/internal prefix scheme, second-preimage safe) Batch commitment to a transparency log; prove a single receipt belonged to the committed set
PostgresChainStateStore Postgres backend for chain state with CAS concurrency, row-level security pattern SaaS multi-tenant deployments past single-process
MemoryChainStateStore In-process backend Tests, serverless
KeyRegistry Key rotation, retirement, revocation, historical-time-window-aware trusted set Long-lived issuers (key rotation every 90 days per NIST SP 800-57)

Performance

Measured numbers from npm run bench (5000 iterations after warmup, Node 22, sandboxed Linux/arm64):

Operation p50 p95 p99
canonicalize (RFC 8785) 5.4 µs 7.7 µs 13.2 µs
sha256 (canonical bytes) 6.7 µs 11.3 µs 22.5 µs
Ed25519 sign 425 µs 551 µs 662 µs
Ed25519 verify 1.78 ms 1.96 ms 2.06 ms
signReceipt end-to-end 1.64 ms 2.13 ms 2.47 ms
verifyReceipt end-to-end 1.91 ms 2.13 ms 2.26 ms

Note: Ed25519 numbers reflect pure-TypeScript @noble/ed25519 (zero native dependencies, audited). When deployed against a native libsodium binding or HSM, signing drops to ~70 µs. The dominant cost in signReceipt is canonicalization + file I/O for chain state, production deployments swap the file backend for Postgres + HSM and stay well within an enterprise gateway's latency budget.


Ecosystem · related open-source projects

AskLedger is not the only effort in cryptographic AI receipts. The following projects address overlapping problems and we acknowledge them openly:

Project Focus area
Sigstore Model Signing (OMS) Build-time model artifact signing
in-toto / SLSA Build pipeline attestation
OWASP AIBOM AI Bill of Materials
OpenTelemetry GenAI Runtime telemetry conventions
AgentMint, OrgKernel, Pipelock, ArkForge, Garl Protocol, AEGIS, Nono Independent receipts/audit SDKs (various states of completeness)

How we differentiate. This SDK focuses on the runtime AI decision receipt: the cryptographic envelope that binds a single AI event to a tenant, a policy, a model identity, and a hash-chained position. We compose with build-time attestation (Sigstore, in-toto, SLSA), with the OWASP AIBOM, and with OpenTelemetry GenAI semantic conventions. The commercial AskLedger platform layers a verifier model, a regulator portal, evidence packs, and BFSI-MENA-specific framework mappings on top, open-core, Datadog / HashiCorp / Sentry pattern.


Get involved

  • GitHub Discussions: questions, design proposals, use cases
  • Issues: bugs, enhancements, integration requests
  • Pull Requests: see CONTRIBUTING.md
  • Security disclosures: see SECURITY.md (private channel)

We are particularly interested in feedback from:

  • Bank CISOs and Chief Risk Officers preparing for CBUAE / SAMA / EU AI Act inspections
  • Auditors building AI evidence-collection methodologies
  • Standards body participants (OpenSSF, CNCF, LF AI, IETF)
  • Cryptographers reviewing the protocol design

Honest production-readiness checklist · v0.12

Capability Status
Substrate
RFC 8785 canonical JSON ✅ Shipped, conformance-tested across 5 languages
Ed25519 signing ✅ Shipped (@noble/ed25519, cryptography, stdlib, ed25519-dalek, Bouncy Castle)
SHA-256 ✅ Shipped
Per-tenant hash chain ✅ Shipped, tamper-tested + fuzzed
Independent third-party verifier ✅ Shipped
Receipts Protocol Spec v0.1 ✅ Shipped, IETF-style
Input validation + structured errors ✅ Shipped
Tests
571 TypeScript tests ✅ Passing (4 HSM-live skipped without hardware)
48 Python tests ✅ Passing (conformance vectors, parametrized)
3 Go conformance tests ✅ Passing
Rust tests ✅ Code shipped; cargo runs in CI
Java tests ✅ Code shipped; mvn runs in CI
Cross-language conformance vectors ✅ Canonicalization (43) + SHA-256 (4). Signed-receipt and chained vectors are NOT yet frozen, so CL2/CL3 are unearned
Fuzz harness (200 random mutations) ✅ Shipped
Crypto hardening
RFC 3161 timestamping client (FreeTSA + commercial TSA) ✅ Shipped
Merkle batch commitments (RFC 9162 second-preimage safe) ✅ Shipped, inclusion proofs
Key rotation, retirement, revocation, historical verification ✅ Shipped
FIPS-mode crypto path (FipsSigningProvider, requireFipsMode) ✅ Shipped
HSM / KMS
AWS KMS driver ✅ Shipped (@askledger/receipts-sdk/hsm/aws-kms)
Azure Key Vault driver ✅ Shipped
GCP KMS driver ✅ Shipped
PKCS#11 driver (Thales, Entrust, CloudHSM, YubiHSM) ✅ Shipped
Multi-language SDKs (wire-format compatible)
TypeScript ✅ Reference
Python ✅ Shipped
Go ✅ Shipped
Rust ✅ Shipped
Java ✅ Shipped
Scale + storage
Postgres chain backend with CAS + RLS pattern ✅ Shipped
Memory chain store (tests + serverless) ✅ Shipped
Multi-tenant isolation ✅ Shipped
Auto-capture
OpenAI + 8 OpenAI-compatible providers ✅ Shipped
Anthropic ✅ Shipped
Generic fetch (11 vendors) ✅ Shipped
LangChain.js ✅ Shipped
Zero Trust
ZTA reference architecture document (NIST SP 800-207 aligned) ✅ Shipped
SPIFFE workload identity helpers ✅ Shipped
OPA decision client (decisions-as-receipts) ✅ Shipped
Workflows
Receipt pipeline (capture → policy → sign → TSA → persist → notify) ✅ Shipped
Approval workflow (N-of-M, expiry) ✅ Shipped
Evidence pack builder (Merkle batch + integrity hash) ✅ Shipped
Enterprise UI
Admin console (Next.js 14, App Router) ✅ Shipped
Design system (WCAG 2.2 AA, RTL, dark mode, design tokens) ✅ Shipped
Dashboard / Receipts Explorer / Policies / Keys / Workflows / Evidence / Tenants / Audit / Settings ✅ All 9 pages shipped
Audit-ready artifacts
Threat model (STRIDE + LINDDUN) ✅ Shipped
SOC 2 Trust Services Criteria control map ✅ Shipped
Zero Trust architecture doc ✅ Shipped
Design system spec ✅ Shipped
Supply chain
CycloneDX 1.5 SBOM ✅ Shipped
npm provenance publishing ✅ Wired
Sigstore Cosign image signing ✅ Documented
Third-party gates (require external firms)
External cryptographic audit (Trail of Bits / NCC Group / Cure53) 🔴 Code + threat model ready; commissioning ~$80–120K, 4 weeks
SOC 2 Type II report 🔴 Control framework + evidence map ready; commission a CPA firm + 12 months of evidence
NIST CMVP FIPS 140-3 validation 🔴 Provider-delegated via AWS/Azure/GCP/Thales; no SDK-side certification needed
Future
Quantum-resistant hybrid signatures (Ed25519 + Dilithium) 🔴 v2.0 protocol revision
Transparency log integration (Rekor) 🟡 Merkle in place; log connector v0.4

Rows marked 🔴 require external parties (audit firms, CPA firms). The code and the audit-ready artifacts are shipped, what remains is hiring the firms and running their engagements.


Citing this work

If you reference this protocol or implementation in research or industry writing:

AskLedger. (2026). AskLedger Receipts SDK:
Cryptographic AI Decision Receipts for enterprise AI.
https://github.com/askledger/receipts-sdk

License

Apache-2.0.

The open-source license is deliberate: receipts are a moat through adoption, not lock-in. The commercial layer of AskLedger (verifier model, regulator portal, evidence packs, vendor benchmark data) is proprietary. The protocol substrate is open.


Maintainers + governance

See MAINTAINERS.md for the current maintainer list and the technical-steering-committee governance model. The project is under multi-stakeholder governance preparation; we welcome contributions from individuals and organisations who want a seat at the standards table.

Contact

About

Open-source cryptographic substrate for AI Decision Receipts. Every AI invocation produces a signed, hash-chained, regulator-verifiable receipt. Apache-2.0.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages