Attesto

Verifier System

Offline verifier and bundles

A verifier bundle is a portable evidence pack. It contains the proof objects needed to verify a stream range without Attesto backend access, plus a manifest that binds the included files.

Offline verifier

The offline verifier checks locally. Online anchor re-checks are optional and explicit, so a reviewer can still verify the core bundle when network access is restricted.

attesto receipts verify \
  --file ./receipt.json \
  --public-key-hex "$ATTESTO_RECEIPT_SIGNER_PUBLIC_KEY_HEX"

attesto bundles offline-verify --file ./attesto-bundle.json
attesto verify file --file ./receipt.attesto.json \
  --public-key-hex "$ATTESTO_RECEIPT_SIGNER_PUBLIC_KEY_HEX"
attesto verify truth-package --file ./truth-package.zip

Window, checkpoint, anchor, IVC, and full bundle verification can also be run through the online verifier API from the same CLI:

attesto windows verify --file ./window.json
attesto checkpoints verify --file ./checkpoint.json
attesto anchors verify --file ./anchor.json
attesto ivc epochs verify --file ./ivc-epoch.json
attesto bundles verify --file ./attesto-bundle.json

Portable receipts

A portable receipt is a self-contained *.attesto.json export around one signed receipt. It lets a recipient verify the receipt with the Python SDK, TypeScript SDK, Go SDK, CLI, or browser verifier without calling the Attesto backend. A pinned public key is the trustworthy verification path; an embedded key is only a transport hint and must not replace a verifier's trust policy.

Portable receipts are useful for email attachments, support tickets, data-room uploads, and regulator workflows where a full bundle is not needed yet. They still fail closed on changed payload commitments, changed event hashes, wrong signatures, or mismatched stream linkage.

Browser WASM verifier

The verifier-only WebAssembly build exposes receipt, inclusion, checkpoint-root, and completeness verification to a browser page. It has no client creation flow, no API key handling, and no background network requirement. The JavaScript shell passes JSON into the WASM verifier and receives a JSON report back, so browser verification stays a thin local wrapper around the same Go verifier semantics used by the CLI.

Verify portal

The browser Verify portal at /verify.html is for quick receipt verification by an external recipient, auditor, or support team. Drop a receipt JSON or portable receipt file into the page, paste the pinned witness public key, and verify locally. The page loads the WASM verifier from /assets/attesto-verify.wasm but does not upload the receipt, payload, public key, or verifier result to Attesto.

For regulated workflows, pin the witness public key out-of-band and compare the WASM asset hash with the release manifest before relying on a browser result. Use POST /v1/public/verify for receipt verification in a server workflow, and POST /v2/verify for Proofstream object and bundle verification. Browser verification, CLI verification, SDK verification, and API verification must agree on the same canonical JSON and signature semantics.

Bundle structure

{
  "manifest": {
    "bundle_id": "bundle_...",
    "protocol": "ATTESTO-PROOFSTREAM-001",
    "created_at": "2026-06-07T12:00:00Z",
    "stream_id": "str_...",
    "from_seq_no": 1,
    "to_seq_no": 250,
    "artifact_hashes": {
      "receipts.json": "sha256-hex",
      "windows.json": "sha256-hex",
      "checkpoints.json": "sha256-hex",
      "witnesses.json": "sha256-hex",
      "anchors.json": "sha256-hex"
    }
  }
}

Truth packages

Tenant export ZIPs are also lifecycle evidence. When Attesto builds a package, it writes attesto.truth-package.manifest.json into the ZIP, hashes the finalized ZIP, and records a truth_package.generated Proofstream event. Every meaningful dashboard or auditor access records a truth_package.accessed event with a unique access id, timestamp, package hash, manifest hash, actor type, access method, and hashed network metadata. When a user, auditor, SDK, or CLI submits a successful cryptographic verifier report back to Attesto, the backend validates the report against the stored package and manifest hashes and records a truth_package.verified event.

This proves package integrity and lifecycle provenance. It does not prove legal compliance by itself, and it does not prove that a recipient read or accepted the contents. Download/access proves that the package was served; truth_package.verified proves that a verifier actually recomputed the ZIP and artifact hashes.

The final ZIP hash is deliberately recorded after ZIP finalization and outside the ZIP itself. Embedding the receipt over the final ZIP hash inside the same ZIP would create circular self-reference: changing the ZIP to add the receipt would change the hash the receipt signs.

attesto verify truth-package --file ./truth-package.zip

The command reads the ZIP, recomputes the full package SHA-256, requires attesto.truth-package.manifest.json, verifies every manifest-listed artifact hash, and rejects forbidden archive paths such as absolute paths, parent traversal, macOS metadata, workstation paths, and local filesystem references. A changed events.csv, proofs.json, or manifest.json must fail verification before the package can be treated as trustworthy evidence.

curl -X POST https://dashboard.attesto.eu/v1/exports/exp_.../truth-package/verify \
  -H "Authorization: Bearer $ATTESTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "verifierKind": "attesto-cli",
    "verifierVersion": "0.4.0",
    "accessId": "tpa_...",
    "verificationReport": {
      "ok": true,
      "packageSha256": "hex...",
      "manifestSha256": "hex...",
      "verifiedArtifacts": 4,
      "problems": []
    }
  }'

Verifier matrix

MutationExpected result
Changed payloadReject: payload hash no longer matches event commitment.
Changed sequence numberReject: stream ordering and head hash break.
Removed eventReject: window inclusion or stream range is incomplete.
Inserted eventReject: sequence, previous hash, or window commitment changes.
Stale checkpointReject: checkpoint does not match expected stream progression.
Wrong witness signatureReject: statement signature or key epoch is invalid.
Wrong anchorReject: anchor commitment does not bind the included epoch.
Conflicting checkpoint headsReject and report fork evidence.

Public verification API

Use POST /v2/verify when an online service wants the same verifier semantics as the CLI.

curl -X POST https://verify.attesto.eu/v2/verify \
  -H "Content-Type: application/json" \
  --data-binary @attesto-bundle.json