Security
Technical and organisational measures under Art. 32 GDPR · Last updated: 5 October 2026
This page describes what actually protects your data. It doubles as Annex II to our data processing agreement, so a business customer's procurement questionnaire and a curious individual user get the same answers.
What we do not claim. Blurt is run by one person. We hold no SOC 2 report, no ISO 27001 certificate and no third-party penetration test. Saying otherwise would be easy and false. What follows is the concrete list of measures that are in place — judge it on that.
The strongest measure is architectural
Fully local dictation requires both speech and clean-up models to be installed and selected. In Blurt 0.3.27 and later, On-device mode never switches to cloud processing automatically. When both stages run locally, dictation content is not uploaded for processing. Account, billing and other service data are separate; the app requires a free account with a confirmed email address. The measures below cover the backend and the processing stages that use it.
Where your data lives
- Backend and PostgreSQL database run on Hetzner infrastructure in Germany. The backups of that database do not: they are held at Cloudflare, in a bucket that is not confined to the EEA, as the next section and our processor list set out.
- Audio is never written to disk on our side. The backend relays it to the speech provider in flight and holds nothing once the request completes.
- Your dictation history stays on your Mac and is never uploaded. Usage counters on the server hold numbers only — never the text you dictated.
In transit
- TLS on every connection: app to
api.blurt.me, backend to every provider, browser to this website. - The application server binds to localhost only. A reverse proxy terminates TLS in front of it; the application port is never exposed to the internet directly.
Credentials and sessions
- Passwords are stored only as scrypt hashes — never the password itself, and never anything reversible.
- Refresh tokens are stored only as hashes, alongside the device User-Agent, so a stolen database row cannot be replayed as a session and token misuse is detectable.
- Access tokens are short-lived and signed; comparisons of secrets use constant-time equality.
- The free-trial device marker is a salted hash of a per-Mac identifier — the one macOS hands the app for that machine, or, when macOS does not answer, a random one the app generates once and keeps on the Mac. The raw identifier is never stored and the hash cannot be reversed into it.
- Provider API keys live only on the server. They are never shipped inside the app, which is why the app has no key for you to leak.
The running system
- The application container runs with all Linux capabilities dropped,
no-new-privileges, and a read-only root filesystem with a small tmpfs for scratch. - PostgreSQL authenticates with SCRAM-SHA-256 and is not reachable from outside the host.
- Rate limiting per authenticated account (falling back to per-IP) throttles abuse and brute force; the admin panel has its own stricter per-IP limit on top.
- The admin panel is protected by authentication and is not linked from anywhere on the site.
- Payment webhooks are accepted only with a verified signature, and each event id is recorded so a replay changes nothing.
- Card numbers never reach our servers. Stripe's payment element collects them directly.
Backups and recovery
- Database dumps are taken daily and stored off-site — on storage separate from the machine that runs Blurt, so the copy itself survives the loss of that machine. Reaching it, today, does not: the credentials that read that storage are held only on that same server, so if the server is gone the dumps still exist but cannot be listed or downloaded until a second copy of those credentials is kept somewhere else. A backup you cannot reach protects you no better than one you do not have, and the two are stated separately here for that reason. "Off-site" here means Cloudflare R2, in a bucket that is not pinned to the EU. That is a complete copy of the database in the hands of another company, under no guarantee of staying inside the EEA, so it is named here and on the processor list rather than left as an adjective.
- A rolling window of the most recent backups is kept and older ones are deleted automatically, so a backup archive does not quietly become a second, unmanaged copy of everything.
- Restoring the database is a written procedure that has been rehearsed against a real backup — on 1 September 2026, from an actual daily dump, with a table-by-table check that the restored database matched production. A backup nobody has ever restored is an assumption, not a measure. Rebuilding the whole service is a longer path — among its steps a new machine, the restore into it, DNS, and replaying the payments that arrive while we are down — and that path has not been rehearsed from start to finish. Our own recovery runbook estimates it in hours rather than minutes and records, in those words, that it has never been performed end to end. That estimate is assembled from the parts that were measured; it is not a commitment, and we offer no recovery-time guarantee.
Correction, 1 September 2026. Until this date, this section said the dumps were stored encrypted. That was not true. The encryption had been designed and written, but it was never installed on the server, and this page described the intention as if it were the state. The claim is removed here, and recorded rather than quietly dropped, because you may have read the earlier version and relied on it. The three measures above are the ones actually in place. Encryption of those off-site dumps is the next piece of work here; until it appears in the list above, with the date it started, it is not running.
Further correction, 1 September 2026. Until this date the first item above ended "so losing that machine does not lose your data", and the third said the restore had been rehearsed end to end. Both reached further than the facts. The off-site copy does survive the machine — that half stands — but the credentials needed to read it are kept only on the machine itself, so losing the server today also means losing access to the backups, which from where you sit is the same thing until that second copy of the credentials exists. And what was rehearsed on 1 September 2026 was the restore of the database, from a real dump with a table-by-table comparison against production; the path back to a running service was not, and our internal runbook says so in as many words. Nothing about the backups changed on this date — only what this page claims about them. It is recorded here rather than quietly reworded because this page is Annex II to the data processing agreement, and you may have read or accepted the earlier version in reliance on it. Both gaps are tracked; when either is closed it will appear in the list above with the date it started, and until it does, it is not running.
Data minimisation
- No third-party analytics, telemetry or crash-reporting SDKs in the app or on this website — no Google Analytics, no Firebase, no Sentry, no advertising or attribution kit. That is a statement about other companies' code, so here is what Blurt itself collects. In the app, two things, and both are off unless you switch them on with a single switch. Usage analytics carries no text and no audio, goes to analytics software we run ourselves (OpenFrog) on this same German server — the daily off-site backup above is the one copy that leaves it, as it is for every other row of our data — is linked to your account only while you are signed in and only because you said yes to that, and is deleted after 25 months; switching it off erases what was already sent. (Blurt 0.3.31 and earlier sent it to our own database instead, never linked to an account, deleted after 90 days.) Crash reports carry a fault name, stack frames from Blurt's own binary, and the app and OS version — no text, no audio, no file paths and no identifier of any kind, not even the analytics one. Both are described field by field in the privacy policy, crash reports in Section 7f, which also says where they go. Outside the app, two more, both with analytics software we run ourselves on this same German server: this website counts its visits without cookies and without identifying you (Section 6f), and the payments of a subscription are recorded under the account identifier — no name, email or card — and erased with the account (Section 6g).
- Marketing and legal pages load no third-party resources. Fonts are served from our own domain. Checkout loads Stripe’s payment library and embedded payment fields directly from Stripe.
- Legal notices remain readable with JavaScript switched off. Online withdrawal and cancellation forms require JavaScript; each page also provides an email alternative.
- We do not use your voice or your text to train models, and we do not authorise our providers to do so.
Supplementary measures for transfers
For the speech and text providers outside the EEA listed on our processor page, the measures above are what supplements the contractual transfer mechanism: encryption in transit end to end, no audio at rest anywhere in our control, minimum necessary content per request (such a provider receives the audio or the text, never your account, your history or your other dictations), and no training use.
That sentence does not stretch to the platform providers, and stretching it would be the easy lie. The daily backup at Cloudflare is the opposite of minimum necessary: it is the entire database in one object, which is what a backup has to be. What limits the exposure there is the retention window and, once the encryption noted above is installed, the fact that the file cannot be read without a key that is not on the server. Until then the honest statement is that the measure protecting that copy is the contractual one plus Cloudflare's own security, and not a technical one of ours.
Organisational measures
- Blurt is operated by a single person; access to production systems is limited to that person, over key-based authentication.
- Secrets live in server-side environment files, never in the repository.
- Dependencies are pinned and updated deliberately; the release build is signed and notarised by Apple, and updates are delivered over a signed appcast, so an update cannot be substituted in transit.
- We have a written procedure for personal data breaches, including the 72-hour notification duty under Art. 33 GDPR to the Landesbeauftragte für den Datenschutz Sachsen-Anhalt, and notification of affected people under Art. 34 where required.
Reporting a vulnerability
If you find a security problem in Blurt, the backend or this website, please tell us at support-blurt@chbnk.one with "security" in the subject. We will confirm receipt within 72 hours and keep you updated until it is closed.
We will not take legal action against anyone who reports a problem in good faith, keeps it confidential until we have fixed it, and does not access, modify or delete other people's data while investigating. Please avoid denial-of-service testing and automated scanning of the production service — one small server serves everyone.
Related
See our Privacy Policy, the list of processors, the data processing agreement and the Terms of Use.