Best Practice · Discovery Pattern

Storing Receipt References in Your Own System

Signatrust holds the evidence. You hold the subject. This page explains how customers keep the link between their internal records (a patient, a loan applicant, a claim, an employee) and the cryptographic Decision Receipts we sign — so that years later, an authorised party can retrieve and independently verify those receipts without Signatrust ever needing to know who the person was.

Applies to all sectors· SDK: JavaScript, Python· Retention horizon: multi-year

1 · The problem

A hospital's clinical AI recommends a triage decision. Signatrust seals a Decision Receipt over the local hashes of the input and output, and returns a Receipt ID. Five years later a patient, an insurer, or a court asks:

“Which AI decision receipt corresponds to this specific patient encounter, and can you prove it hasn't been altered?”

The naive answer would be to let Signatrust hold a map from patient identity to receipt. We deliberately do not do that. Instead, subject identity stays inside the customer's environment and only cryptographic commitments travel to Signatrust. This page explains the mechanics.

2 · Who holds what

PartyHoldsDoes NOT hold
Customer (e.g. hospital, bank, insurer) Raw input · raw output · subject identity (patient ID, applicant ID, claim ID) · the Receipt ID attached to that subject · the metadata of who did what, when, and how
Signatrust Evidence Service Decision Receipt: SHA-256 commitments (input_hash, output_hash) · non-sensitive metadata (model id, timestamp, policies) · Ed25519 signature · hash chain link Patient / customer / applicant identity · raw prompt · raw model output · PAN / DOB / medical text · the map from subject → Receipt ID
Independent verifier (auditor, court expert, insurer) Nothing persistent — needs only the Receipt ID (from the customer), the Signatrust public key, and a verifier binary (or the public /verify page) Any customer data — verification uses only receipt + public key

3 · The flow

Hospital internal record system
        │
        │  raw input · raw output · subject identity
        │
        ▼
Local Signatrust SDK
        │  hash locally · never sends raw content
        │
        ▼
Signatrust Evidence Service
        │  canonicalise · SHA-256 · Ed25519 · chain link
        │
        ▼
Decision Receipt · Receipt ID returned
        │
        ▼
Hospital stores Receipt ID beside its own record
   ┌──────────────────────────────────────────────┐
   │  Patient PT-84721                            │
   │  Encounter E-2027-551                        │
   │  AI decisions:                               │
   │    R-8f3a…  (triage_recommendation)          │
   │    R-c012…  (medication_check)               │
   └──────────────────────────────────────────────┘

… five years later …

Patient / insurer / court request
        │
        ▼
Hospital looks up Receipt IDs by internal record
        │
        ▼
Independent verifier: receipt + public key + rules
        │
        ▼
Cryptographic verification result
(signature valid · chain intact · commitments match if re-hashed)

4 · Retrieval scenarios

4.1 · The patient asks

The patient contacts the hospital's records office. The hospital pulls up encounter E-2027-551, sees the list of Receipt IDs attached to it, and can share them (subject to consent policy). The patient — or their lawyer — pastes each Receipt ID into /verify, or uses the offline verifier binary with the archived Signatrust public key. Signatrust is never queried about the patient by name.

4.2 · An insurer or third party asks (with consent)

The insurer receives, from the patient or hospital, the specific Receipt ID that relates to the claim. They verify it the same way. No blanket access to a patient index is possible — because there is no such index at Signatrust.

4.3 · A court order

A court can compel the hospital to disclose the Receipt IDs linked to a case. Because Signatrust receipts are append-only and tamper-evident, once a Receipt ID is produced the court can independently confirm the signed evidence has not changed since the moment it was sealed. If required, the original content held by the hospital can be re-hashed and compared with the historical commitment inside the receipt.

5 · What the customer must store

A minimum reference row on the customer side looks like this:

{
  "receipt_id":     "R-8f3a...",
  "receipt_hash":   "sha256:...",
  "signed_at":      "2027-06-01T09:14:22.113Z",
  "subject_ref":    "PT-84721",             // internal subject id
  "case_ref":       "E-2027-551",           // internal case id
  "label":          "triage_recommendation",
  "actor":          "TriageBot v4",
  "action":         "STEMI fast-track routing",
  "method_note":    "protocol=stemi-fast-track; prompt_id=triage-2027-Q3",
  "recorded_at":    "2027-06-01T09:14:22.190Z",

  // Human reviewer — WHO reviewed it, WHAT is their specialty.
  // These fields stay LOCAL. Only the commitment enters the receipt.
  "human_reviewer": {
    "id":           "STAFF-7734",
    "role":         "attending_physician",
    "specialty":    "cardiology",
    "reviewed_at":  "2027-06-01T09:20:00.000Z",
    "note":         "STEMI protocol confirmed"
  },
  "human_review_attestation_hash": "sha256:..."   // copy of what is in the receipt
}

This row lives entirely inside the customer's environment — a database, an EHR, a JSONL file, whatever the customer's compliance and retention rules require. Signatrust never receives it.

6 · Built-in SDK helper — ReceiptReferenceStore

Both the JavaScript and Python SDKs ship with a small, dependency-free helper that writes these rows to a local append-only JSONL file with restrictive permissions. It is optional — most customers will plug this into their existing record system instead — but it gives a working reference for the exact discovery pattern above.

6.1 · JavaScript / TypeScript

import { Signatrust, ReceiptReferenceStore } from 'signatrust';

const str = new Signatrust({ apiKey: process.env.SIGNATRUST_API_KEY! });

const store = new ReceiptReferenceStore({
  filePath: '/var/lib/hospital/signatrust-refs.jsonl',
});

const result = await str.sign({
  decision: {
    type: 'triage_recommendation',
    business_event: 'CLINICAL_DECISION',
    input: rawPrompt,     // hashed locally, never sent
    output: rawOutput,    // hashed locally, never sent
    risk_level: 'high',
    human_review: true,
    policies: ['triage-protocol-v4'],
  },
});

// Attach the Receipt ID to the hospital's own record.
store.attach(result, {
  subject_ref: 'PT-84721',
  case_ref:    'E-2027-551',
  label:       'triage_recommendation',
  actor:       'TriageBot v4',
  action:      'STEMI fast-track routing',
  method_note: 'protocol=stemi-fast-track; prompt_id=triage-2027-Q3',
});

// Five years later, retrieve by internal record:
const refs = store.findByCase('E-2027-551');
// -> [{ receipt_id: 'R-...', receipt_hash: 'sha256:...', ... }]

6.2 · Python

from signatrust import Signatrust, ReceiptReferenceStore

client = Signatrust(api_key=os.environ["SIGNATRUST_API_KEY"])

store = ReceiptReferenceStore(file_path="/var/lib/hospital/signatrust-refs.jsonl")

result = client.sign(
    decision={
        "type": "triage_recommendation",
        "business_event": "CLINICAL_DECISION",
        "input": raw_prompt,
        "output": raw_output,
        "risk_level": "high",
        "human_review": True,
        "policies": ["triage-protocol-v4"],
    },
)

store.attach(
    result,
    subject_ref="PT-84721",
    case_ref="E-2027-551",
    label="triage_recommendation",
    actor="TriageBot v4",
    action="STEMI fast-track routing",
    method_note="protocol=stemi-fast-track; prompt_id=triage-2027-Q3",
)

# Later:
refs = store.find_by_case("E-2027-551")

File format: newline-delimited JSON, append-only, mode 0600. Every row is a self-contained reference — if the file grows large you can archive segments, replicate them, or ingest them into a warehouse. The helper never removes or rewrites past rows.

7 · Human-review attestation

Every Decision Receipt records a boolean human_review flag. Optionally, the SDK can also compute a SHA-256 commitment to the reviewer's identity and specialty and place that commitment inside the signed receipt as decision.human_review_attestation_hash. The reviewer's actual name, role, and specialty stay on the customer side (typically stored in ReceiptReferenceStore) and are never transmitted to Signatrust.

Customer supplies to the SDK:                 Sent to Signatrust:
──────────────────────────────                ──────────────────────────
{                                             {
  id: "STAFF-7734",                             human_review: true,
  role: "attending_physician",                  human_review_attestation_hash:
  specialty: "cardiology",                        "sha256:<64 hex>"
  reviewed_at: "2027-06-01T09:20:00Z",        }
  note: "STEMI protocol confirmed"            (no reviewer name, role,
}                                              specialty, or note travels)

Years later, given the reviewer's original details (held by the customer), any party can recompute the same commitment and match it against the historical value inside the signed receipt — proving which reviewer signed off, without Signatrust ever having held that information.

JavaScript / TypeScript

const result = await str.sign({
  decision: { type: 'triage_recommendation', input: rawPrompt, output: rawOutput,
              risk_level: 'high', policies: ['triage-protocol-v4'] },
  humanReviewer: {
    id: 'STAFF-7734',
    role: 'attending_physician',
    specialty: 'cardiology',
    reviewed_at: '2027-06-01T09:20:00.000Z',
    note: 'STEMI protocol confirmed',
  },
});
// Reviewer info is echoed back on the SDK result and can be persisted locally:
store.attach(result, { subject_ref: 'PT-84721', case_ref: 'E-2027-551' });

Python

result = client.sign(
    decision={"type": "triage_recommendation",
              "input": raw_prompt, "output": raw_output,
              "risk_level": "high", "policies": ["triage-protocol-v4"]},
    human_reviewer={
        "id": "STAFF-7734",
        "role": "attending_physician",
        "specialty": "cardiology",
        "reviewed_at": "2027-06-01T09:20:00.000Z",
        "note": "STEMI protocol confirmed",
    },
)
store.attach(result, subject_ref="PT-84721", case_ref="E-2027-551")

The Verify page shows both facts: whether a human review was performed, and — when a commitment is present — a short display of sha256:xxxx… with an explicit note that the reviewer's identity is held by the issuing organization, not by Signatrust.

8 · Independent verification years later

A receipt does not depend on Signatrust being reachable to be verifiable. It contains everything a verifier needs, given the archived public key that was in force when the receipt was sealed:

If a third party later wants to confirm that a specific piece of hospital-held content is what was signed, the hospital re-hashes that content with the same deterministic hashing rules — and the result must match the commitment inside the receipt. Any single-byte change flips the fingerprint.

9 · What this does not claim

This pattern gives you evidence integrity: cryptographic authenticity of the recorded decision receipt, plus a clean way to retrieve it years later through the customer's own record system. It does not claim to establish that the underlying AI decision was correct, fair, lawful, safe, or complete. Those remain research and organisational questions. Signatrust intentionally separates the evidence layer from any judgment about the decision itself.

10 · See also