Attesto

Verifier System

Offline verifier y bundles

Un verifier bundle es un evidence pack portable. Contiene los proof objects necesarios para verificar un rango de stream sin acceso al backend de Attesto, además de un manifest que vincula los archivos incluidos.

Offline verifier

El offline verifier comprueba localmente. Los online anchor re-checks son opcionales y explícitos, para que un reviewer aún pueda verificar el núcleo del bundle cuando el acceso de red está restringido.

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

La verificación de windows, checkpoints, anchors, IVC y bundles completos también puede ejecutarse contra la API verifier online desde la misma 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

Un portable receipt es un export *.attesto.json self-contained alrededor de un signed receipt. Un receptor puede verificar el receipt con Python SDK, TypeScript SDK, Go SDK, CLI o browser verifier sin llamar al backend de Attesto. Una public key fijada es el camino de verificación confiable; una embedded key es solo un transport hint y no debe sustituir la trust policy del verifier.

Portable receipts son útiles para email attachments, support tickets, data-room uploads y regulator workflows cuando todavía no se necesita un bundle completo. Siguen fail-closed ante payload commitments cambiados, event hashes cambiados, signatures incorrectas o mismatched stream linkage.

Browser WASM verifier

El build WebAssembly verifier-only expone receipt, inclusion, checkpoint-root y completeness verification a una browser page. No tiene client creation flow, API key handling ni background network requirement. El shell JavaScript pasa JSON al WASM verifier y recibe un JSON report, por lo que browser verification sigue siendo una capa local delgada sobre las mismas Go verifier semantics usadas por la CLI.

Verify portal

El Verify portal del navegador en /verify.html sirve para una verificación rápida de receipts por parte de un destinatario externo, auditor o equipo de soporte. Suelta un receipt JSON o un portable receipt file en la página, pega la witness public key fijada y verifica localmente. La página carga el WASM verifier desde /assets/attesto-verify.wasm, pero no sube el receipt, payload, public key ni verifier result a Attesto.

Para workflows regulados, fija la witness public key out-of-band y compara el hash del asset WASM con el release manifest antes de confiar en un resultado del navegador. Usa POST /v1/public/verify para receipt verification en un server workflow, y POST /v2/verify para Proofstream object y bundle verification. Browser verification, CLI verification, SDK verification y API verification deben seguir la misma semántica de canonical JSON y signatures.

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

Los ZIPs de export de tenant también son lifecycle evidence. Cuando Attesto construye un package, escribe attesto.truth-package.manifest.json dentro del ZIP, calcula el hash del ZIP finalizado y registra un event Proofstream truth_package.generated. Cada acceso significativo desde dashboard o auditor registra un event truth_package.accessed con access id único, timestamp, package hash, manifest hash, actor type, access method y network metadata hasheada. Cuando un user, auditor, SDK o CLI envía a Attesto un cryptographic verifier report exitoso, el backend valida el report contra los package y manifest hashes guardados y registra un event truth_package.verified.

Esto prueba package integrity y lifecycle provenance. No prueba cumplimiento legal por sí solo, y no prueba que un destinatario haya leído o aceptado el contenido. Download/access prueba que el package fue servido; truth_package.verified prueba que un verifier realmente recalculó los hashes del ZIP y de los artifacts.

El hash final del ZIP se registra deliberadamente después de la finalización del ZIP y fuera del propio ZIP. Incrustar la receipt sobre el hash final del ZIP dentro del mismo ZIP crearía una self-reference circular: cambiar el ZIP para añadir la receipt cambiaría el hash que la receipt firma.

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

El comando lee el ZIP, recalcula el package SHA-256 completo, exige attesto.truth-package.manifest.json, verifica cada artifact hash listado en el manifest y rechaza archive paths prohibidos como absolute paths, parent traversal, macOS metadata, workstation paths y local filesystem references. Un events.csv, proofs.json o manifest.json modificado debe fallar la verificación antes de que el package pueda tratarse como evidencia confiable.

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

MutaciónResultado esperado
Payload cambiadoReject: payload hash ya no coincide con event commitment.
Sequence number cambiadoReject: stream ordering y head hash se rompen.
Event eliminadoReject: window inclusion o stream range está incompleto.
Event insertadoReject: sequence, previous hash o window commitment cambia.
Stale checkpointReject: checkpoint no coincide con la stream progression esperada.
Wrong witness signatureReject: statement signature o key epoch inválido.
Wrong anchorReject: anchor commitment no vincula la included epoch.
Checkpoint heads en conflictoReject y reportar fork evidence.

Public verification API

Use POST /v2/verify cuando un servicio online necesita las mismas verifier semantics que la CLI.

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