Aira

Cryptographic Receipts

Receipts are minted by notarize(), not by authorize(). They commit to both the agent's original intent and the real-world outcome.

When receipts are minted

Receipts are minted at notarize() time, not at authorize() time. The two-step flow is deliberate:

  1. authorize() captures the agent's intent and the policy decision. No receipt yet. The agent has not done anything in the real world.
  2. The agent executes the action.
  3. notarize() captures the actual outcome and mints the receipt. Both the original intent (from step 1) and the real-world outcome (from step 3) are part of the signed payload.

The receipt is therefore a commitment to a complete, end-to-end record. It proves what the agent intended, what the policy engine decided, and what actually happened.

If the agent's execution fails, call notarize(outcome="failed", ...). A receipt is still minted, recording the failure cryptographically.

Universal receipts — every state gets a receipt

Every terminal action state produces a signed Ed25519 receipt. There are no gaps in the audit trail.

StatusWhen it happensWhat the receipt proves
notarizedAction completed successfully.The receipt seals the outcome — both the original intent and the real-world result are committed to the signed payload.
deniedA policy blocked the action at authorize() time.The receipt proves the system caught it. The denial reason and the policy that fired are part of the signed payload.
failedThe agent executed the action but it failed.The receipt records the failure. The failure details are hashed and signed just like a successful outcome.
denied_by_humanA human reviewer rejected a held action.The receipt records who denied it and when. The human's identity is part of the signed payload.

Zero audit gaps. A regulator can verify any decision Aira made, including the ones it blocked.

Previously, only successful actions (notarized) produced receipts. Denied and failed actions were recorded in the audit log but had no cryptographic proof. Now every terminal state mints a receipt with the same Ed25519 signature and RFC 3161 timestamp, so every decision is independently verifiable.

The notarize() response

A successful notarize() call returns the minted receipt as a flat object. This is the exact shape returned by POST /api/v1/actions/{action_uuid}/notarize:

{
  "action_uuid": "act_01J9B...",
  "status": "notarized",
  "receipt_uuid": "rcpt_01J9B...",
  "payload_hash": "sha256:...",
  "signature": "ed25519:...",
  "timestamp_token": "...",
  "created_at": "2026-04-07T14:31:15.000Z",
  "request_id": "req_01JAB...",
  "warnings": null
}
FieldDescription
action_uuidThe action that was notarized.
statusReceipt status. One of: notarized, denied, failed, denied_by_human. Every terminal state produces a signed receipt.
receipt_uuidID of the minted receipt. Present for all terminal states.
payload_hashSHA-256 hash of the canonical receipt payload. Present for all terminal states.
signatureEd25519 signature over payload_hash. Present for all terminal states.
timestamp_tokenRFC 3161 timestamp token from an independent TSA. Present for all terminal states.
created_atWhen the receipt was minted (or the failure was recorded).
request_idAira request ID for correlation.
warningsOptional list of non-fatal warnings.

The canonical payload that gets signed commits to both the original intent (from authorize()) and the reported outcome (from notarize()). It is serialized with sorted keys and no whitespace (json.dumps(payload, sort_keys=True, separators=(",", ":"))) to ensure deterministic hashing. The SHA-256 hash of this payload is signed with Ed25519 and timestamped via RFC 3161.

Cryptographic Primitives

ComponentAlgorithmPurpose
Payload hashSHA-256Integrity. Detect any tampering.
SignatureEd25519Authenticity. Prove Aira signed it.
TimestampRFC 3161 (TSA)Non-repudiation. Independent proof of when.

Why Ed25519?

  • 64-byte signatures (compact).
  • Fast verification, no RSA overhead.
  • No known vulnerabilities.
  • Used by SSH, Signal, and most modern signing systems.

Why RFC 3161?

An RFC 3161 trusted timestamp is obtained from an independent Timestamp Authority (TSA). This proves the receipt existed at a specific point in time. Aira cannot backdate it. The TSA response is stored alongside the receipt.

Intent Privacy

By default, Aira stores only the SHA-256 hash of the agent's intent details and the outcome details, not the raw text. This means:

  • Your raw action details never touch Aira's database.
  • The hash is sufficient for receipt verification.
  • No PII storage liability for Aira.

If you need the raw details stored (for your own audit trail), opt in on the authorize() call:

{
  "store_details": true
}

When store_details is true, the details are encrypted with AES-256-GCM before storage.

Immutability

Receipts are stored in an append-only database table. Updates and deletes are blocked at the PostgreSQL level:

CREATE OR REPLACE FUNCTION prevent_receipt_mutation()
RETURNS TRIGGER AS $$
BEGIN
  RAISE EXCEPTION 'Receipts are immutable.';
END;
$$ LANGUAGE plpgsql;

Any attempt to modify a receipt raises an exception. There is no way to alter a receipt after creation, even with direct database access.

Verifying a Receipt

Anyone can verify a notarized action's receipt without authentication:

curl https://api.airaproof.com/api/v1/verify/action/act_01J9B...
{
  "valid": true,
  "action_uuid": "act_01J9B...",
  "outcome": "completed",
  "verified_at": "2026-04-07T16:00:00.000Z",
  "public_key_id": "aira-signing-key-v1",
  "message": "Action exists and receipt signature is valid."
}

The verify endpoint checks the Ed25519 signature against the stored payload and confirms the RFC 3161 timestamp. Share the verify URL with auditors, regulators, or a court.

On this page