Topic · Private AI therapy scribe

A private AI therapy scribe that physically cannot phone home

The strongest privacy claim a scribe can make is not "we don't upload your sessions" but "the app is incapable of uploading them." TherapyDraft is built around that second claim.

TL;DR

"Private" is a marketing word for most AI scribes. It usually means "we promise not to train on your data" or "we signed a BAA." For TherapyDraft, privacy is a structural property of the app: a macOS network sandbox entitlement allow-lists exactly two hostnames — Stripe (for license checks) and the app-version endpoint — and nothing else. There is no code path, configuration switch, or hidden telemetry that can upload audio, transcript, or draft text. The enforcement layer is the operating system, not the vendor.

What clinicians mean when they say "private"

When a therapist asks whether an AI scribe is private, they rarely mean the GDPR definition. They mean three practical things: audio is not re-used to train a model, transcripts are not readable by a vendor's engineers, and nothing about the session is visible to a subpoena served on a third party. A cloud scribe can satisfy the first two contractually but not the third. The session artifacts exist in the vendor's storage; that storage is discoverable.

TherapyDraft's answer is one level deeper: the artifacts never exist outside the clinician's own Mac, so none of those questions have an answer that involves us. We are not a subprocessor the clinician has to list on their Notice of Privacy Practices. We don't appear in any data-flow diagram for the session.

How a macOS network sandbox entitlement works

On a signed, notarized macOS application, Apple enforces a set of capabilities declared at build time through entitlements. The relevant entitlement here is com.apple.security.network.client — which in a sandboxed app is used together with an allow-list of outbound hostnames. If a code path inside the app tries to open a socket to a hostname not on the list, the connection fails at the kernel level before the TCP handshake even starts. It doesn't matter whether the call comes from our code, a third-party library, or a compromised dependency: the OS refuses.

TherapyDraft's entitlement allow-list contains two hostnames: api.stripe.com (for license activation; no PHI crosses this) and update.therapydraft.com (an anonymous version ping that sends only the app build number). That's it. Any attempt to contact a transcription service, an LLM provider, a logging backend, or even our own analytics would be denied by macOS itself.

You can verify it yourself

This is the key property of the architecture: a clinician can audit it in about ninety seconds without trusting anything we say.

  1. Open Activity Monitor's Network tab.
  2. Drag a session audio file into TherapyDraft and run a full draft pass.
  3. Filter by the TherapyDraft process. You will see roughly zero bytes sent for the duration of transcription and drafting, then a tiny payload (a few hundred bytes) if a Stripe license check happens to fire.
  4. For a deeper audit, install LuLu (a free firewall from Objective-See) and watch the outbound-connection log. Every DNS lookup and TCP open by the app will appear there. There is no unnamed chatter.

If the app ever starts reaching out to anywhere it shouldn't, the firewall will tell you before you finish your coffee. That inspection doesn't exist for cloud scribes — the interesting traffic happens inside the vendor's own data center, where you can't watch it.

What about the local LLM and whisper.cpp — can those phone home?

Reasonable question. The transcription engine (whisper.cpp) is open source and has no network code path in its inference loop; same for the MLX runtime and Qwen 2.5 14B weights. Both are audited by the broader local-inference community on GitHub, not by us alone. Even if a future version did add telemetry, the entitlement allow-list would still block the call — it is the last layer of defense, not the first, and it doesn't rely on the honesty of any upstream dependency.

Why this matters for high-sensitivity practices

For a generalist private-practice clinician, a cloud scribe with a BAA is usually fine. For a clinician who sees trauma survivors, other licensed therapists, attorneys testifying in family cases, or executives whose work is under NDA, "usually fine" is the wrong risk profile. A breach is unrecoverable in a way that a wrong note is not. An architectural guarantee is worth the $39/month premium over the cheaper cloud options, because there is no scenario the architecture doesn't cover.

See also: the full privacy page (which documents the entitlement list verbatim) and the HIPAA-AI-SOAP-note explainer for the regulatory framing.

Related questions

Does "private" mean you don't train on the data? Or something stronger?

Stronger. No vendor ever sees the data, so the question of training on it doesn't arise. The training corpus for the bundled model is whatever Qwen or Llama open-sourced; none of your sessions are part of it, and they never could be, because they never leave your Mac.

Could a court order force you to decrypt session data?

We have nothing to decrypt. All session files live in your user directory, encrypted at rest with keys in your macOS keychain. A subpoena in our name produces nothing; a subpoena served on you applies to your records regardless of what tool drafted them.

What if I turn on iCloud Drive for Application Support?

Don't. TherapyDraft writes to ~/Library/Application Support/TherapyDraft, and if you've enabled iCloud for that location, Apple may sync it to iCloud Drive — which is a cloud vendor, BAA-distinct from us. The app settings page flags this and the installer writes an exclusion by default.

Further reading