Skip to content

Content-blindness attestation

This is a strong, provable property — and it is important to state it honestly. It is content-blindness, not encryption and not zero-knowledge. The rest of this page says exactly what is provable, how the receipt is built, and how you can verify all of it yourself with no account and no trust in our servers.

The content-blindness guarantee

Three mechanisms together make the guarantee real:

  1. Tokenisation happens on your device. Every value the on-device detector matches is replaced with a surrogate by an open tokeniser that runs client-side (browser WASM, the desktop app, the local proxy, or the SDK), before anything is transmitted. Detection is pattern- and dictionary-bound, so this is a recall-bounded claim, not an absolute one: structured identifiers (email, phone, national ID numbers, cards, IBAN, IP addresses, dates) are the strong measured lane, while free-form names outside the on-device dictionary can be missed. See Detection coverage for the known limits and How privacy works for the client-side flow.
  2. The gateway performs zero content inspection. After the server-side PII removal campaign, there is no gateway code path that detects, tokenises, or de-tokenises message content — the detection engine is deleted from the gateway at the code level, not merely disabled behind a runtime flag. The gateway relays the tokenised bytes to the upstream model verbatim.
  3. The re-identification map never leaves your device. The token→value map that turns surrogates back into real values is held only on the client. The gateway never receives it, so it cannot re-identify the surrogates even if it wanted to.

What is provable — and what is not

Provable properties (content-blindness):

  • No detected PII in the surrogates — every value the on-device detector matched is replaced with a surrogate before egress. This is bounded by detection recall (see Detection coverage); it is not a claim that no identifier can ever slip past the detector.
  • No server-side content inspection — the detection/tokenisation engine is deleted from the gateway, not flag-gated.
  • On-device tokenisation — enforced by a content-blind request gate plus a per-tenant MAC.
  • Map-never-leaves-device — the token→value map is held only on the client.
  • Genuine open engine — the client’s engine hash is attested against the published /engine/hashes allowlist.

Do not read the guarantee as any of these (they would be false):

  • “encrypted so we can’t read it” / “zero-knowledge.” The gateway forwards tokenised text that the upstream model must read. The surrogates are readable; they carry a surrogate in place of every value the on-device detector matched. This is content-blindness, not ciphertext hidden from the relay.
  • “we can’t see the tokenised text.” We can see the tokenised text — we relay it. What we never see or process is the values the on-device tokeniser replaced — those never leave your device.
  • “detection is perfect, so nothing identifying can ever reach us.” Anything the on-device detector does not match is relayed verbatim. The strength of the privacy claim is the strength of detection — see Detection coverage, and pre-tokenise known sensitive fields at the application layer for high-assurance use.

How the relay receipt is built

Every relay produces a signed OpenReceipt envelope. The signature is computed over the canonical bytes of the envelope after the receipt is chain-linked, so the signature always covers exactly what is persisted (see the OpenReceipt protocol for the envelope and chain semantics). The top-level envelope carries:

FieldMeaning
v, algEnvelope version and signature algorithm (ES256 / ecdsa-p256-sha256).
jtiUnique receipt id.
kidWhich signing key to fetch from the public JWKS to check sig.
iss, sub, iatIssuer, subject (tenant), issued-at.
chain{ chain_id, seq, prev_hash } — tamper-evident, gap-free per-tenant chain.
claimsThe attestation payload (below).
sigThe ECDSA (P-256) signature over the canonical envelope bytes.

The content-blindness claims, field by field

When a request is relayed as client-pretokenised (the content-blind path), the gateway adds these claims — these are the exact fields it emits, and each one proves a specific thing:

FieldValue / typeWhat it proves
pretokenisedtruePII was tokenised client-side; the gateway never saw raw PII on this call.
tokenisation_mode"client_pretokenised"Names the content-blind relay mode explicitly (vs. any server-side mode).
genuine_enginetrue | falseServer-attested: true only when the client-declared engine hash is non-empty and present on the gateway’s own official-hash allowlist. A dishonest client that claims genuine but sends a forged/absent hash gets false here — the gateway does not trust the client’s self-report.
engine_versionstring (present when known)The engine ruleset version the gateway actually observed, so a verifier can reproduce the check.
engine_binary_hashstring (present when known)The engine binary hash the gateway actually observed — checked against the public allowlist.
pretokenised_leak_detectedtrue (only if it fired)A monitor-only signal: raw PII the client should have tokenised was spotted. Absent on a clean relay.

On the fully client-side surfaces (browser chat, extension, desktop) the device that tokenised also signs a richer v3 client attestation before egress — carrying no_raw_pii_egress, tokenised_body_hash, detector_categories (categories only, never matched values), engine_ruleset_version, engine_binary_hash, genuine_engine, and a token_binding_hmac that proves which values were tokenised without revealing any PII. The gateway then adds an additive countersignature witnessing provider, model, and upstream byte counts. See OpenReceipt protocol for both envelopes.

Verify it yourself — the independent recipe

None of the steps below need an account or trust in our servers. Every input is public and content-addressed, so you reproduce the trust anchors from source.

1. Fetch the public JWKS — the signing keys:

Terminal window
curl -s https://api.cloakapi.io/api/.well-known/cloakapi-receipt-pubkeys.jwks | jq

Pick the key whose kid matches the receipt’s kid (see Public JWKS).

2. Check the ECDSA signature. Verify sig (ECDSA P-256 / ES256) over the receipt’s canonical bytes using that public key. If it fails, the receipt was tampered with.

3. Check the engine hash against the public allowlist:

Terminal window
curl -s https://api.cloakapi.io/api/v1/engine/hashes | jq
# { "published": true, "algorithm": "sha256",
# "engine_binary_hashes": […,"fa837ad1…","028b5f7b…","651a5cb2…"],
# "ruleset_version": "1.4.1", ... }

The receipt’s engine_binary_hash must appear in engine_binary_hashes. If it does, the client ran a genuine, published open build; an unknown hash is honestly reported (genuine_engine=false), never silently trusted.

4. Run a verifier client-side — no account, no server:

import { checkGenuineEngine } from '@cloakapi/conformance';
const engineHashes = await (await fetch('https://api.cloakapi.io/api/v1/engine/hashes')).json();
checkGenuineEngine([receipt], engineHashes);
// genuine hash + genuine_engine:true -> "pass"
// unknown / forged hash -> "fail"

5. Reproduce the engine build → same hash. Because every allowlist entry is the sha-256 of a published, open artifact, the allowlist is not a trust anchor you take on faith — you rebuild it and confirm it matches what your client loaded:

Terminal window
# Browser WASM engine (should equal the fa837ad1… entry):
sha256sum pkg/cloakapi_tokeniser_wasm_bg.wasm
# Ruleset digest (should equal the 651a5cb2… entry):
sha256sum shared/pii-patterns/patterns.json

See Reproducibility for the full build-from-source and provenance story.