How it stays private

The data path, in full — nothing hidden.

Content-blind does not mean invisible. This page is the honest, checkable account of exactly what happens to your spreadsheet, byte for byte. Every claim here is one you can verify in your own browser's Network panel.

1 · Parsing + cloaking are 100% on-device

When you drop a file or paste rows, the CSV/TSV/xlsx is parsed in the tab — no upload. Each cell is run through the published CloakAPI browser engine (a WebAssembly tokeniser, an on-device name dictionary, a ~25 000-name gazetteer, and the same on-device multilingual NER model the rest of the suite uses — Layer B, DistilBERT, ~135 MB, fetched same-origin). Cells it detects — emails, phone numbers, dates of birth, cards, IBANs, passports, national/health/company IDs, IP addresses, postcodes, places, organisations, and person names, including uncommon and non-Latin-script names the model finds — are replaced with realistic, locale-matched surrogates. If the name model is still loading or cannot load, nothing is cloaked and nothing is sent (fail-closed). Cells it still does not detect are left as they are: a residual the receipt measures. Secrets-class values (cards, national IDs) become opaque, locked markers that can never be revealed. During this step the app makes zero network connections except the same-origin model fetch. Watch the live egress monitor: the third-party counter stays at 0.

2 · Only the schema and surrogates are relayed

When you ask a question, we build a request containing your column names and a sample of the first 8 rows in their cloaked form. Be precise about what that means: every cell the engine detected is a surrogate in that sample, and a cell it detected nothing in is included exactly as it is — a department, a salary figure, or a residual the on-device name model also missed. The receipt measures those bytes and shows the number. That request is relayed to the CloakAPI gateway through the published SDK's fail-closed wrapper, which re-tokenises the whole body, obtains a pretokenisation proof, and only then forwards it. The model reads the schema and writes analysis code — it never sees the full table, and it never runs over your data.

3 · The analysis runs on your device

The model's Python is executed in a sandboxed Web Worker on your machine, using a pinned, same-origin Pyodide runtime. The worker is served with a connect-src 'self' Content-Security-Policy and installs a no-network guard as its first statement, so the code that touches your real rows cannot reach the network at all — belt and braces. pandas, numpy and matplotlib run over your real numbers; the answer and any charts are written to an in-memory folder and rendered locally.

4 · A receipt, not a promise

After each analysis, the receipt shows how many cells were cloaked, by category, how many bytes of detected values survived into what was sent (a real measurement over the relayed bytes, not a printed constant), and how many bytes of un-detected cell content went into the sample rows as written. The total relayed byte count is shown too. The re-identification map that restores your originals never leaves the browser.

What we can and can't claim

  • We can say: the full table never leaves the tab — only the column names and a cloaked 8-row sample are relayed; every value the engine detected is a surrogate in those bytes, and the receipt measures that rather than asserting it; the analysis code runs locally with no network; the re-identification map never egresses.
  • We won't say: that no real cell value reaches the gateway. A cell in the sample rows in which the engine detected nothing is relayed exactly as written — the receipt counts those bytes for you.
  • And we won't say that detection is complete. Structured PII (emails, phones, dates of birth, cards, IBANs, passports, national/health/company IDs, IPs, postcodes) is deterministic and high-coverage. Person names, organisations and places are checked by the on-device NER model (Layer B) on top of the dictionary and gazetteer — uncommon and non-Latin-script names are in scope. The model is not perfect: some organisations still slip through both layers, and street addresses are still matched in US number-first order only, so a European “Storgata 14” is not detected as an address. If the name model does not run, the sheet is not sent. Reveal originals and scan the grid before you rely on a column being fully cloaked.

The platform's full legal terms — Terms of Service, Privacy Policy, Data Processing Addendum and data-subject requests — live at cloakapi.io/legal ↗.