Security and threat model

What we can protect against, what we can't, and how to verify every claim on this page in under thirty seconds using your browser.

Most privacy pages are sales copy. This is a threat model. It tells you exactly what we protect against, exactly what we can't, and how to verify every claim below in under thirty seconds using your browser.

What we protect

  • Your files and text never leave your device. Processing runs in your browser.
  • No server receives your documents. The optional phone signing relay sees only an encrypted blob it has no key for.
  • No client-side analytics, tracking pixels, or cookies.
  • A Content Security Policy restricts which scripts, frames, and forms this site can use.

What we can't protect

  • Your browser itself (Chrome telemetry, Privacy Sandbox, Topics API).
  • Browser extensions with permission to read our pages.
  • Your operating system (screen recorders, clipboard managers, malware).
  • That you visited our domain (your ISP sees the hostname, not the content).

What we guarantee

Unwrite is a static site. Your documents are never uploaded: files and text are read into browser memory, processed using JavaScript and WebAssembly, and the result is made available to you. The tools have no upload endpoint for your content. Three narrow edge endpoints exist, a fetch proxy and an image proxy for the social share preview tool and the optional sign-on-your-phone relay. Only the relay is unreadable by design; the proxies fetch public pages and images on your behalf. All three are detailed in the exceptions below.

A Content-Security-Policy header is served on every page. Scripts are restricted to our origin and jsDelivr (plus inline scripts, which the build requires), and frames, objects, and forms are locked to our origin. Two directives are deliberately wide — connections and images may reach any HTTP(S) origin — because remote LLM mode connects to a server you specify (including plain-HTTP LAN servers like Ollama) and the share preview renders images from any URL you enter. The browser enforces all of this independently of our code.

See the privacy policy for the formal version, and why Unwrite isn't open source for the reasoning behind verifying via DevTools rather than a public repository.

What we can't protect against

Honesty matters more than a clean marketing page. Three categories of threat sit outside anything a website can defend against. If any of them apply to you, the ladder further down tells you what to do about it.

Your browser itself

Chrome participates in tracking through the Topics API, Privacy Sandbox, browser telemetry, Safe Browsing URL checks, and Chrome sync if you have enabled it. Edge sends more. A webpage cannot opt you out of what your browser chooses to do. If this matters, Firefox and Brave are stricter by default.

Browser extensions

Any extension with permission to run on our pages can read what you type, what you paste, what our tools output, and your clipboard. This is a limit of the web platform, not a gap in our site. Extensions run with more privilege than our code and no page can stop them. Audit your extensions in your browser settings, or use incognito or private browsing where most extensions are disabled by default.

Your device

Screen recorders, clipboard history tools, accessibility software, keyloggers, malware. Anything running on your machine sits between your eyes and our page. Outside our reach.

What we don't run

Modern websites commonly include a lot of third-party code. Unwrite doesn't. This list is stronger than the usual “we respect your privacy” line because it is a list of absences, not intentions.

  • No client-side analytics of any kind (no Google Analytics, Plausible, Umami, Fathom).
  • No tracking or advertising pixels (no Meta, TikTok, LinkedIn, Pinterest, Snap).
  • No session-replay tools (no Hotjar, FullStory, Microsoft Clarity).
  • No error-reporting SDKs (no Sentry, Bugsnag, Rollbar).
  • No chat widgets (no Intercom, Crisp, Drift, HubSpot).
  • No social embeds or sharing widgets.
  • No third-party fonts. Fonts are self-hosted from our origin.
  • No A/B testing or feature flagging against external services.
  • No cookies of any kind, not even first-party.
  • No browser fingerprinting, canvas fingerprinting, or device identification.

What we do collect

Cloudflare sits in front of the site and produces aggregate traffic figures from its own edge request logs. Page views, popular pages, countries. No JavaScript is injected into your browser to generate these numbers. No cookies. No individual user profiles. We see traffic, we do not see you.

The full list is in the privacy policy. We also wrote a post on removing everything Cloudflare was injecting by default to get to this point.

The exceptions

A handful of tools need the network to work. These are the only cases where your device talks to anything beyond the static page, and none of them involve sending us your readable content.

ToolWho your device talks toWhat they see
Sign tool (phone handoff only)Our relay at the Cloudflare edgeAn end-to-end encrypted signature and a hashed session code, which expire after ten minutes. The encryption key travels in the QR URL fragment, which browsers never send to servers, so the relay cannot decrypt what it briefly holds. The PDF itself never leaves your computer.
Social share preview (fetch)Our fetch proxy at the Cloudflare edgeThe public URL you asked it to check, fetched because browsers block the page from reading another site directly. The URL is cached at the edge for five minutes and appears in standard edge request logs.
Social share preview (PNG export)Our image proxy at the Cloudflare edgeThe public image URLs needed to render the export. Cached at the edge for seven days; the URLs appear in standard edge request logs.
Social share preview (rendering)The site you are previewingYour IP address, when your browser loads that site's images and favicon directly to render the preview.
PDF and Image toolsjsDelivr CDNYour IP address when your browser downloads the open-source WebAssembly libraries on first use. The Unzip tool is an exception: its engine is self-hosted from our origin, so it contacts nothing.
LLM tools (local mode)Hugging Face and jsDelivrYour IP address when your browser downloads the open-source language model you chose and its runtime library.
LLM tools (remote mode)A server you configureYour prompts and responses. You enter the URL; we never see or proxy the traffic.

The first three are our own endpoints. Only the signing relay is designed so that even we cannot read what passes through it; the proxies fetch public content on your behalf. The rest reach a public CDN or a server you chose. For remote LLM mode, this is the whole point: you want your data to reach that server.

How to maximise your privacy

A ladder, from casual to strict. Most readers stop at the first rung.

Default

You're fine. HTTPS plus in-browser processing covers the realistic threats for almost everyone.

Cautious

Use incognito or private browsing. Most extensions are disabled by default in these modes, which removes the biggest category of residual risk.

Strict

Install Unwrite as a Progressive Web App, then work with your network disabled. Your browser will show “offline” and the tools will keep running. If nothing can leave, nothing can leak.

Paranoid

Combine the strict setup with a privacy-focused browser (Brave, LibreWolf, hardened Firefox), a dedicated profile for sensitive work, and a clean extension audit. At this point you are defending against threats that have nothing to do with us.

Verify it yourself

Every claim above is visible in your browser. You don't need to trust us and you don't need source code. You need DevTools.

  • Open DevTools (F12, or right-click and choose Inspect). Switch to the Network tab and clear the log.
  • Use any tool on this site. Process a PDF, clean some HTML, compare text, humanise a draft.
  • Watch the Network tab. For many tools (text, HTML, QR, compare, unzip) the request count after the page has loaded stays at zero. For the PDF, image, GPT, and LLM tools, you will see requests to jsDelivr or Hugging Face downloading libraries or models, never uploads of your content. If you sign on your phone, you will see small polls to /api/signature-session and one encrypted blob arriving, which you can inspect.
  • Check the response headers on any page. The content-security-policy header shows exactly what is locked down (scripts, frames, forms) and what is deliberately open (connections and images, for the reasons above).
  • Install the site as a PWA, then toggle “Offline” in the DevTools Network tab. The tools keep working. Nothing goes out because nothing can.

Still have questions?

The privacy policy is the formal version of everything above. The posts on removing every tracker Cloudflare injected by default and why Unwrite isn't open source explain the reasoning in more depth.