Applied Research · Architecture Alignment

Zero-Data-Access Evidence Architecture

Signatrust is an active applied research project investigating whether AI decisions can be accompanied by cryptographically verifiable evidence — Decision Receipts — that enables independent verification without claiming decision correctness. This page describes what the architecture does, what it deliberately does not do, and the current implementation status of every capability.

Ed25519 · SHA-256· Receipt spec v1.0 (open)· License: CC BY 4.0 (this document)
Cryptographic verification confirms evidence integrity and authenticity. It does not confirm that the underlying decision was correct, fair, lawful, safe, or complete.

What Signatrust provides

Cryptographically verifiable receipts
Signed evidence with Ed25519 and SHA-256, verifiable online or offline.
Data-minimized evidence
Raw subject data remains in the customer environment. Only commitments cross the boundary.
Independent verification
Receipts can be verified without trusting the Signatrust server that issued them.
Explicit evidence boundaries
Decision Boundary Disclosure and Deployment Evidence Profiles declare what was and was not covered.

What Signatrust does not claim

  • Correctness — a signed receipt does not prove the underlying decision was right.
  • Fairness — cryptography cannot decide whether a decision was fair.
  • Legal compliance — policy binding proves a reference, not lawfulness.
  • Real-world completeness — coverage is declared by DBD/DEP, not by us.

Architecture at a glance

Customer Environment
    ↓ raw input/output stays local
Local Hashing (SHA-256 profile)
    ↓
Sector Schema
    ↓
Deployment Evidence Profile
    ↓
Decision or Action Event
    ↓
Evidence Composition
    ↓ input/output commitments · DBD · policy bindings
      human-review commitment · attestations · metadata
Canonical Signed Body
    ↓ SHA-256 → receipt_hash
    ↓ Ed25519 → signature
Decision Receipt
    ↓
Ledger Epoch (append-only, epoch-anchored)
    ↓
Online Verification  /  Offline Verification
Trust Bundle · Historical Keys · Recovery Manifest

Detailed sections follow. Each system property in the status matrix declares whether it is IMPLEMENTED, DOCUMENTED, RESEARCH, or FUTURE — no hidden limitations.

1. Framing

Signatrust is an Evidence Architecture. It is not:

  • an AI Governance platform
  • an AI auditor
  • an AI judge
  • an AI correctness validator
  • a fairness engine
  • an explainability framework
  • a legal certification system

The single research premise:

Can AI decisions be accompanied by cryptographically verifiable evidence that enables independent verification without requiring trust in the party that issued the receipt, and without requiring that party (Signatrust) to receive or retain the underlying raw decision content or direct subject identity?

Signatrust protects the evidence that describes a decision. It does not prove that the decision itself was correct, fair, lawful, complete, safe, or free from bias.

2. Zero-Data-Access, not Zero-Knowledge

We deliberately do not use the term Zero-Knowledge Architecture. "Zero-Knowledge" is a well-defined term in cryptography (ZKP) with a specific meaning that we do not implement.

The property Signatrust does provide is:

Signatrust is designed so that cryptographic evidence can be generated and verified without requiring Signatrust to receive or retain the underlying raw decision content or direct subject identity.

We call this Zero-Data-Access Evidence Architecture. The engineering objective is: verify without unnecessary disclosure.

3. End-to-end data flow

The target model (already implemented in the JavaScript and Python SDKs):

Customer Environment
        │
        │  raw input
        │  raw output
        │  subject / patient / customer identity
        │  raw prompts, model output, PII, PHI, PAN, medical record
        ▼
Local Signatrust SDK
        │
        │  local SHA-256 hashing (hashLocally: true is the default)
        ▼
input_hash    (sha256:<hex>)
output_hash   (sha256:<hex>)
metadata required for evidence (business_event, risk_level, permissions)
optional scope_declaration (Decision Boundary Disclosure)
        │
        │  HTTPS → /api/v1/receipts
        ▼
Signatrust Evidence Service
        │
        │  RFC 8785–style deterministic canonicalization
        │  receipt_hash = SHA-256(canonical(body))
        │  Ed25519 signature over receipt_hash
        │  chain linkage to previous_hash
        ▼
Decision Receipt (signed, chained)
        │
        ▼
Receipt ID returned to customer
        │
        ▼
Customer stores Receipt ID in their own system
alongside their internal Patient / Case / Transaction record.

The customer's internal system holds the mapping Subject → Receipt ID. Signatrust does not need — and by design does not receive — that mapping.

4. What Signatrust does not receive by default

Under the data-minimized default (SDK hashLocally: true), the following never leave the customer's environment:

  • Raw model prompt / raw model output
  • Patient name, medical record, diagnosis text
  • Customer name (of the customer's own end-customer), phone, address
  • Email addresses of decision subjects
  • Banking details, PAN / card details
  • Full application content (loan, insurance, employment)
  • Personally identifying case content

What Signatrust does receive is limited to:

  • input_hash and output_hash (SHA-256 commitments)
  • Non-sensitive decision metadata: business_event, risk_level, human_review (boolean), optional human_review_attestation_hash (SHA-256 commitment to reviewer identity/specialty; the reviewer's actual name and role never travel to Signatrust), permissions, policies, optional scope_declaration
  • Agent identity (the system that made the decision, not the subject of the decision)
  • Model provider/name/version (if the customer chooses to disclose)
  • Optional metadata chosen by the customer (customer decides what to include)

Note. Any regulatory scope (GDPR, HIPAA, PCI-DSS, DNB) depends on the deployment and applicable legal context. Data-minimization is an engineering property of the receipt payload and not, on its own, a certification claim.

5. Local hashing contract

Local hashing is a first-class, documented pathway in both official SDKs.

  • Algorithm: SHA-256 (FIPS 180-4).
  • Encoding: UTF-8 bytes of the string content.
  • Serialization: the caller passes a string; if the payload is a structured value the caller is responsible for producing a stable string encoding (typically JSON.stringify with fixed key ordering, or a canonicalizer).
  • Wire format: hashes are transmitted as sha256:<lowercase-hex> (the prefix identifies the algorithm so future algorithm agility does not silently mis-verify).
  • Recomputation: feeding the same original content through the same SDK produces the same sha256:<hex>. Recomputation later — even years later — must produce a byte-identical fingerprint to match the historical commitment.

SDK reference:

// TypeScript / JavaScript SDK
const str = new Signatrust({ apiKey: process.env.SIGNATRUST_API_KEY });
// hashLocally defaults to true — the following two lines do NOT send raw content
const receipt = await str.sign({
  decision: {
    type: 'loan_rejection',
    input: sensitivePrompt,
    output: sensitiveModelOutput,
    business_event: 'CREDIT_DECISION',
    risk_level: 'high',
  },
});
// Also available: pre-computed hashes
const receipt2 = await str.sign({
  decision: {
    input_hash:  Signatrust.fingerprint(sensitivePrompt),
    output_hash: Signatrust.fingerprint(sensitiveModelOutput),
    business_event: 'CREDIT_DECISION',
  },
});

6. What a Receipt contains

The signed body of a Decision Receipt includes only:

  • version, id, type, sequence, timestamp
  • agent — the issuing system, not the subject
  • model — provider/name/version (optional)
  • decisioninput_hash, output_hash, business_event, risk_level, human_review, human_review_attestation_hash (optional), permissions, policies
  • scope_declaration — Decision Boundary Disclosure (optional, sector-schema-pinned)
  • metadata — customer-chosen non-sensitive attributes
  • previous_hash — link into the append-only chain

Attached to (but not part of) the signable body:

  • receipt_hash — SHA-256 of the canonicalized body
  • signature.algorithmed25519
  • signature.public_key — base64 SPKI/DER of the Ed25519 verification key, embedded in the receipt for immediate self-contained verification
  • signature.value — the Ed25519 signature over receipt_hash

A separate signature.key_id field for explicit historical-resolution / rotation is on the research list — see LONG_TERM_VERIFICATION_AND_CRYPTO_AGILITY.md. Today the embedded public key already lets an offline verifier check the signature; long-term rotation and revocation are handled through the external trust bundle rather than a receipt-side identifier.

The SDK returns to the customer:

{
  "receipt": { ... },
  "verify_url": "https://signatrust.net/api/v1/receipts/STR-.../verify",
  "share_url":  "https://signatrust.net/verify?id=STR-..."
}

7. Storing Receipt References in Your Own System

Signatrust does not maintain a central patient / customer discovery index. The subject identity belongs to the customer's domain; the evidence identity belongs to the Signatrust evidence domain.

The recommended pattern for any sector — healthcare, credit, insurance, employment, government benefits, industrial safety — is symmetric:

Customer Internal System
──────────────────────────────────────────────
Internal Subject ID   84721
Case / Encounter ID   E-2027-551
AI Decisions
    receipt_id: STR-A1B2C3...
    receipt_id: STR-D4E5F6...
    receipt_id: STR-G7H8I9...

Do not send Patient 84721 to Signatrust merely to locate a Receipt later. The customer's own system is the discovery layer.

Sector examples (all follow the same pattern):

SectorInternal recordField the customer stores the Receipt ID in
HealthcareEHR encounterencounter.ai_decisions[].receipt_id
Credit / lendingLoan applicationapplication.credit_decision.receipt_id
InsuranceClaim fileclaim.underwriting.receipt_id
Employment / HRCandidate recordcandidate.screening.receipt_id
Public benefitsCase recordcase.benefit_decision.receipt_id
Industrial safetyWork orderwork_order.ai_check.receipt_id
Payments / fraudTransactiontx.fraud_decision.receipt_id
Content moderationCasecase.moderation.receipt_id

Both SDKs ship with a small, dependency-free ReceiptReferenceStore helper that persists these rows locally with restrictive permissions and offers attach, findBySubject, findByCase, and findByReceiptId. It's optional — most customers plug the same fields into their existing record system — but it gives a working reference for the exact multi-year retrieval story: Storing Receipt References in Your Own System →

8. Discovery vs Verification

DiscoveryVerification
QuestionWhich receipts belong to this subject / case?Is this receipt cryptographically authentic and intact?
ResponsibilityCustomer or integration layerSignatrust verifier (or any third party with the public key)
Data requiredCustomer's own record systemThe receipt itself and the archived public key

These functions are deliberately separated. Signatrust never merges them into a "receipt lookup by patient name" API.

9. Decision Boundary Disclosure (DBD)

DBD is an independent architectural feature that pins each receipt to a versioned sector schema and declares, per receipt:

  • domains_evaluated — the schema domains the system actually considered
  • domains_excluded — the schema domains the system did not consider, with a machine-readable reason and excluded_by classification

The server enforces a hard union rule:

domains_evaluated ∪ domains_excluded = all domains defined by the referenced sector schema.

If any schema domain is present in neither list, the server refuses to sign. This eliminates silent omission: a developer must actively say not evaluated — they cannot leave a domain out and hope nobody notices.

DBD data is part of the signed envelope:

scope_declaration → canonicalization → receipt_hash → Ed25519 signature

Tampering with domains_excluded after signing breaks verification.

DBD does not prove:

  • that every factor relevant in reality was considered — only every factor in this version of this schema was addressed;
  • that the evaluation of any given domain was correct — only that the domain was reported to have been evaluated;
  • that the sector schema itself is complete or fair — the schema is a living, versioned, human-authored artifact.

10. Integrity ≠ Correctness

The single most important boundary in this project:

Decision Integrity ≠ Decision Correctness.

Cryptographic verification of a Signatrust receipt can prove:

  • the receipt was signed by the stated key,
  • the signed body has not been altered since,
  • the receipt is properly linked into the append-only chain.

It cannot prove that the underlying AI decision was:

  • correct
  • fair or unbiased
  • lawful under a specific jurisdiction
  • medically, financially, or ethically safe
  • complete with respect to reality

The verification page makes this boundary explicit in the result panel.

11. Completeness (open research)

Hash chaining and signing prove that a given receipt has not been altered and is linked to its predecessors. They do not automatically prove that the issuing organization submitted every relevant decision — the receipts we can see are only the ones we were shown.

We treat selective omission / completeness verification as an open research question. It is not implemented and is not claimed as a property of the current system.

12. Long-term retention

A receipt carries what it needs for later verification: schema version, algorithm identifier (ed25519), signing public key, chain identifier, timestamp, receipt hash, signature, and previous hash. However, long-term verification also depends on infrastructure we have not yet productionised: an archived public-key registry, a key-rotation history, and versioned canonicalization profiles. We are aware of the dependency and are not claiming it is solved.

13. Architecture status matrix

Each capability is placed in exactly one status category. Categories are:

  • IMPLEMENTED — present in production code and covered by tests;
  • DOCUMENTED — designed and specified but not fully proven end-to-end;
  • RESEARCH — open question or active study;
  • FUTURE — on the roadmap, not started.
CapabilityStatusLocation / notes
Decision Receipt format (v1.0)IMPLEMENTEDADR spec, src/ledger.ts, src/types.ts
Ed25519 signing (software keys)IMPLEMENTEDsrc/crypto.ts, src/ledger.ts
Receipt verification (id + JSON + full-ledger)IMPLEMENTED/api/v1/receipts/:id/verify, /api/v1/verify, /api/v1/verify/ledger
Append-only tamper-evident hash chainIMPLEMENTEDsrc/ledger.tsprevious_hash linkage, write-time enforcement of both previous_hash === head and monotonic sequence
Same-host multi-process ledger safetyIMPLEMENTEDsrc/ledgerLock.ts — deterministic cross-process advisory lock: each contender writes its payload ({pid, time}) to a per-process temp file, then fs.linkSync(temp, lockPath). link(2) on POSIX / CreateHardLinkW on NTFS both guarantee the target either does not exist or already contains the full payload — no observable empty-lock window (deterministic, not probabilistic). Stale-holder reclaim via PID probe or 30s TTL. Verified by scripts/multiprocess-concurrency-test.ts (100 seals across 4 processes on the production host).
Graceful shutdown on SIGTERMIMPLEMENTEDNew seals are refused with 503, in-flight seals drain, HTTP server closes, process exits cleanly. Systemd unit configured with KillMode=mixed, KillSignal=SIGTERM, TimeoutStopSec=15s. This closes the "SIGTERM mid-write during systemctl restart" pattern that is consistent with the historical break at sequence 730.
Combined chaos test — load + restartIMPLEMENTEDscripts/chaos-restart-under-load.ts spawns an isolated instance (fresh SIGNATRUST_DATA_DIR, port 3001), fires a paced burst of seals, sends SIGTERM mid-burst simulating systemctl restart, respawns the server, and re-verifies. 5-of-5 clean runs on the production host: ledger intact, no duplicate sequences, no missing sequences, HTTP 200 count equal to test-added disk rows (503s during drain are retried and succeed).
Ledger filesystem hardeningIMPLEMENTEDProduction ledger.jsonl is chmod 600 and set append-only at the filesystem layer (chattr +a); overwrite/truncate is refused even for root. Baseline hash + line count pinned in data/.integrity/ and exposed via GET /api/v1/verify/ledger/integrity.
Local hashing (SDK-side, on by default)IMPLEMENTEDsdk/js/signatrust.ts, sdk/python/signatrust.py
Server-side hashing (convenience fallback)IMPLEMENTEDRaw content is hashed then discarded — never stored in the receipt.
DBD — Decision Boundary DisclosureIMPLEMENTEDsrc/dbd.ts, 8 sector schemas in /schemas
DBD union-rule enforcementIMPLEMENTEDsrc/dbd.ts — silent omission is rejected
DBD signature coverageIMPLEMENTEDscope_declaration is inside toBody() → signed
Sector schema registryIMPLEMENTED/api/v1/schemas, admin CRUD via /admin
Sector schema hash pinned in receiptIMPLEMENTEDscope_declaration.sector_schema_hash
Data-minimized indicator on verify pageIMPLEMENTEDpublic/assets/verify.jsrenderEvidenceMode
Verify UI: Integrity ≠ Correctness statementIMPLEMENTEDResult panel on /verify
Trace / chain-of-custody per tool callIMPLEMENTEDsrc/trace.ts, SDK trace() helper
Multi-sector reference examplesDOCUMENTEDexamples/data-minimized/
Archived public-key registryIMPLEMENTEDscripts/export-trust-bundle.ts emits a signatrust-trust-bundle-v1 file — see the live export at /architecture-evidence/trust-bundle.json. Observed keys are reconstructed by scanning the append-only ledger; explicit rotation / revocation windows can be supplied via --key-history. The bundle is what the offline verifier anchors trust against, so multi-year re-verification does not depend on signatrust.net being reachable.
Canonicalization test suite vs RFC 8785DOCUMENTEDProject-defined deterministic canonicalization; formal RFC 8785 conformance suite is not yet published.
Hashing Profile v1 (reference module)DOCUMENTEDsrc/hashingProfile.ts, HASHING_PROFILE_V1.md — profile fields are additive on the receipt (decision.input_profile, decision.output_profile); legacy receipts without a profile still verify but expose a "content re-verification not possible" indicator on the verify page.
Policy binding (historical policy pinning)DOCUMENTEDPOLICY_BINDING_SPEC.md — optional policy_bindings[] on the signed body; verifier semantics documented (PASS/FAIL/UNKNOWN); policy documents are customer-held, not stored by Signatrust.
Deployment Evidence Profile (DEP) — per-deployment specialisation of the sector schemaIMPLEMENTEDsrc/deploymentProfile.ts + additive fields on scope_declaration (deployment_profile_id, deployment_profile_hash); registry under profiles/; core domains cannot be silently downgraded; conditional / deployment_specific domains must be classified with a structured reason; coverage classification is evaluated against the pinned profile's applicable set rather than the raw sector schema. Full spec: DEPLOYMENT_EVIDENCE_PROFILE_SPEC.md. Backward compatibility is guaranteed: receipts without a profile pin canonicalise identically to legacy receipts and are validated by the original schema-only rule.
Offline reference verifierIMPLEMENTEDscripts/verify-offline.mjs — zero-network Node script; verifies body integrity, Ed25519 signature, trust-bundle anchor, chain linkage against a supplied tail, content re-verification under the declared hashing profile, sector-schema pin, policy-binding hashes, and independent attestations. Full spec in OFFLINE_VERIFICATION_SPEC.md.
Reproducible micro-benchmark harnessIMPLEMENTEDscripts/bench-receipt.ts — measures canonicalize / SHA-256 / Ed25519-sign / append / pipeline / sustained / burst phases with commit-hash-pinned reports. Full plan reference: PERFORMANCE_BENCHMARK_PLAN.md. Live single-process run on the deployment host (AMD EPYC 7543P, 2 vCPU) is published as bench-sp-20260827T115640Z.json; same-host multi-process ceiling estimates: 2 workers and 4 workers. These are reference numbers, not a customer SLA.
Pilot readiness packageIMPLEMENTEDSelf-contained kit for a 30-day evaluation: offline verifier + trust bundle + JS/Python SDK samples + bench reports + success-criteria template. Download: pilot-package.tar.gz. Base checklist: PILOT_READINESS_CHECKLIST.md.
Regression matrix runnerIMPLEMENTEDscripts/regression-matrix.ts — cryptographic tamper checks, hashing-profile invariants (Unicode NFC, JSON-order, salt), policy-binding hash checks, DBD schema arithmetic, Deployment Evidence Profile rules (core-domain integrity, structured-reason vocabulary, silent-omission guard, adequacy warnings, pin-hash mismatch), DEP backward-compat gates (legacy schema + legacy receipt → pre-DEP wording preserved byte-for-byte; conditional-tagged schema does not retroactively change legacy validation), and a language-vocabulary lint over public/. 30/30 PASS today.
Attestation model (independent vs issuer-asserted)DOCUMENTEDOptional attestations[] on the signed body — spec in POLICY_BINDING_SPEC.md and the taxonomy note. Verify UI already distinguishes "Reported by issuer" from "Independently attested".
Computation-proofs extension pointRESEARCHOptional computation_proofs[] on the receipt for external verifiable-computing / ZKP / TEE-attestation references. This verifier checks references only; proof-scheme soundness is out of scope. See VERIFIABLE_COMPUTING_EXTENSION_RESEARCH.md.
Receipt taxonomy (Evidence / Decision / Action / …)RESEARCHRECEIPT_TAXONOMY_RESEARCH_NOTE.md — no breaking rename planned; historical type: "decision_receipt" is preserved.
Long-term verification & crypto agilityRESEARCHTrusted-time options (RFC 3161, transparency logs, signed checkpoints, public anchors), historical key model, hybrid signatures — LONG_TERM_VERIFICATION_AND_CRYPTO_AGILITY.md.
Governance interoperability (vendor-neutral)DOCUMENTEDmetadata.governance_refs pattern — customer-controlled references to policy/control/framework IDs. Signatrust does not decide compliance. See GOVERNANCE_INTEROP_NOTE.md.
Horizontal write scaling across hostsRESEARCHThe advisory lock is same-host only. Multi-host write concurrency requires an external sequencer (e.g. Postgres advisory lock, Redis SETNX + fencing tokens, or etcd) — this is an open architectural item, not an implemented property of the current single-host deployment.
Automated / auditable deployment pipelineRESEARCHProduction is deployed today via manual scp + systemctl restart. Source-of-truth Git history is now in place, but a reviewable CI-driven pipeline (with reproducible builds and per-deploy attestations) is an open operational item.
HSM signingFUTURESoftware keys today; HSM is an enterprise-deployment option.
Post-quantum signatures (hybrid Ed25519 + PQ)RESEARCHAlgorithm agility exists via the sha256: and ed25519 prefixes; migration path is not implemented.
Runtime attestation of the issuing environmentRESEARCH
Central Evidence Discovery IndexRESEARCH / architecturalNot planned — discovery is a customer-side concern by design.
Completeness proof (no silent receipt omission)RESEARCHOpen question. Not claimed as an implemented property.
Formal legal / regulatory certification (GDPR, HIPAA, PCI, DNB, EU AI Act)RESEARCH / deployment-dependentRegulatory scope depends on the specific deployment and applicable legal context; not claimed as an inherent property of the receipt.

14. Open research questions

  1. Completeness verification. How does an external verifier detect selective omission of receipts by a cooperating issuer?
  2. Horizontal write scaling across hosts. The current write path is safe under concurrent processes on a single host via a filesystem advisory lock. Extending safe append across multiple hosts (each with its own writer) requires an external sequencer — a Postgres advisory lock, a Redis SETNX pattern with fencing tokens, or a consensus system such as etcd/Raft. The right choice depends on the deployment's failure model and is deliberately deferred rather than implemented pre-maturely.
  3. Long-term key resolution. How is a receipt signed under a key that has since been rotated verified five, ten, or twenty years later, without either party trusting a central registry unconditionally?
  4. Post-quantum migration. What is the transition strategy from Ed25519 to a hybrid or PQ-only signature envelope that preserves verifiability of receipts issued under legacy algorithms?
  5. Runtime attestation. How does a receipt bind to evidence that a specific model version, running on a specific execution environment, actually produced the output the hash covers?
  6. Sector-schema governance. Who authors and versions sector schemas so that coverage_classification: full carries external meaning across organisations?
  7. Canonicalization conformance. Formal test suite proving byte-for-byte agreement with RFC 8785 across all JSON edge cases (numeric edge cases, string escape edge cases, key ordering with Unicode code points).

These questions define our research agenda. They are deliberately not solved by adding claims to the marketing site.