← Back to Learn
audit-trailexplainercompliance

Cryptographic receipt chains explained

Authensor

Authensor's audit trail uses cryptographic receipt chains to create tamper-evident logs. This article explains the technical details: how receipts are constructed, how the chain is formed, and how verification works.

Receipt structure

Each receipt is a structured record:

interface Receipt {
  id: string;              // Unique receipt identifier
  timestamp: string;       // ISO 8601 timestamp
  tool: string;            // Tool name
  args: unknown;           // Tool arguments (serialized)
  action: string;          // Policy decision: allow, block, escalate
  reason: string;          // Why the decision was made
  threats: Threat[];       // Aegis scan results
  principal: Principal;    // User and agent identity
  hash: string;            // SHA-256 hash of this receipt
  previousHash: string;    // Hash of the previous receipt
}

Hash computation

The hash is computed over a canonical serialization of the receipt data (excluding the hash and previousHash fields themselves):

function computeHash(receipt: Receipt): string {
  const data = canonicalize({
    id: receipt.id,
    timestamp: receipt.timestamp,
    tool: receipt.tool,
    args: receipt.args,
    action: receipt.action,
    reason: receipt.reason,
    threats: receipt.threats,
    principal: receipt.principal,
    previousHash: receipt.previousHash,
  });

  return 'sha256:' + sha256(data);
}

The canonicalize function produces a deterministic JSON representation (sorted keys, consistent formatting). This ensures that the same data always produces the same hash, regardless of key ordering.

Chain construction

When a new receipt is created:

  1. Set previousHash to the hash of the most recent receipt (or null for the first receipt)
  2. Serialize the receipt data
  3. Compute the SHA-256 hash
  4. Store the hash in the hash field
function createReceipt(data: ReceiptData, chain: Receipt[]): Receipt {
  const previous = chain.length > 0 ? chain[chain.length - 1] : null;

  const receipt: Receipt = {
    ...data,
    id: generateId(),
    timestamp: new Date().toISOString(),
    previousHash: previous ? previous.hash : null,
    hash: '',  // Placeholder
  };

  receipt.hash = computeHash(receipt);
  return receipt;
}

Verification

To verify the chain, walk through the receipts in order:

function verifyChain(receipts: Receipt[]): VerificationResult {
  let expectedPreviousHash: string | null = null;

  for (let i = 0; i < receipts.length; i++) {
    const receipt = receipts[i];

    // Check that previousHash matches
    if (receipt.previousHash !== expectedPreviousHash) {
      return {
        valid: false,
        breakAt: i,
        reason: 'Previous hash mismatch',
      };
    }

    // Recompute and check the hash
    const computed = computeHash(receipt);
    if (computed !== receipt.hash) {
      return {
        valid: false,
        breakAt: i,
        reason: 'Hash mismatch (data was modified)',
      };
    }

    expectedPreviousHash = receipt.hash;
  }

  return { valid: true };
}

What tampering looks like

Modifying a receipt: Changing any field (tool name, args, decision) changes the hash. The stored hash no longer matches the computed hash.

Deleting a receipt: The receipt after the deleted one has a previousHash that no longer matches any existing receipt's hash.

Inserting a receipt: The inserted receipt's hash does not match the previousHash of the next receipt.

Reordering receipts: The previousHash chain breaks at every reordered boundary.

Limitations

The chain proves that data has not been modified since the hash was computed. It does not prove that the data was correct when originally recorded. If the system records a wrong decision, the chain faithfully preserves that wrong decision.

The chain also does not prevent deletion of the entire chain. To protect against wholesale deletion, replicate the chain to immutable storage or a separate system.

Keep learning

Explore more guides on AI agent safety, prompt injection, and building secure systems.

View All Guides