Security & privacy architecture

SayWrite security and privacy architecture

SayWrite turns your voice into text on your Mac's Neural Engine without uploading your audio. Temporary recordings are deleted after transcription. Optional AI Polish uses Apple's on-device model or a server on your own Mac. Account and license services, model downloads, updates and feedback use the network; they are separate from speech processing.

7 days free · no card, no account · then $30/year or $5/month · no word limit

On your phone? SayWrite runs on a Mac. Send yourself the link and download it there.

Illustrative demo rendered from SayWrite's interface. Timing is scripted, not a benchmark.

Data flow

What happens when you hold Fn

How your voice moves through SayWriteYour voice goes from the microphone into your Mac, where speech recognition, the temporary recording and AI Polish all run, and the text goes straight into your app. Nothing goes to cloud servers.Your voiceYOUR MACSpeech → textParakeet on the Apple Neural EngineTemporary recordingDeleted as soon as it's transcribedAI Polish (optional)Apple's model, or your server at 127.0.0.1Your apptext at the cursorNo cloud stepHugging Facemodel, on requestUpdate feeddaily, optionalsaywrite.applicense, feedbackNone of these requests contains your audio or dictated text.How your voice moves through SayWriteYour voice goes from the microphone into your Mac, where speech recognition, the temporary recording and AI Polish all run, and the text goes straight into your app. Nothing goes to cloud servers.Your voiceno cloudYOUR MACSpeech → textParakeet on the Neural EngineTemporary recordingDeleted once it's transcribedAI Polish (optional)On-device, or 127.0.0.1Your apptext at the cursorHugging Facespeech model setup or recoverySayWrite update feeddaily update check (optional)saywrite.applicense (subscribers), feedback you sendNone of these requests containsyour audio or dictated text.
Mic → your Mac (speech recognition on the Neural Engine, temporary recording deleted, optional AI Polish on-device or at 127.0.0.1) → text in your app. Separate network requests support speech-model setup or recovery, optional update checks, account and license services, and Send Feedback when you click Send.

What runs where

Every component, and whether it touches the network

SayWrite components
ComponentWhere it runsNetwork
Microphone captureYour Mac, into a temporary file in the app's temp folderNone
Speech recognitionNVIDIA Parakeet TDT 0.6B v2 via FluidAudio and Core ML, on the Apple Neural EngineNone
Cleanup (fillers, commands, snippets, dictionary)Your MacNone
AI Polish with Apple IntelligenceApple's on-device foundation model (macOS 26+)None
AI Polish with Ollama or LM StudioYour own server on your Mac127.0.0.1 only (loopback, never leaves the machine)
Text insertionmacOS Accessibility, or paste with your clipboard restoredNone
History, Stats, file transcriptsYour user Library, in a folder only your account can readNone, and no iCloud sync
Speech model downloadInitial setup; recovery may download missing or damaged model files againHugging Face
Update checkOnce a day while automatic checks are onSayWrite update feed
Turning SayWrite on for a MacSubscribers only, when you sign in with your email or enter a license key (up to 2 Macs per subscription)saywrite.app (license key or sign-in link, random install ID, Mac model and name; your email if you sign in)
License renewalSubscription licenses only: about once a week, daily within 5 days of expirysaywrite.app (license key only)
Send FeedbackOnly when you click Send in the feedback window; you can preview exactly what's sentsaywrite.app (your message, your email if you add it, optional diagnostics; never dictations or audio)
License checkYour Mac: the key's signature is verified offline and stored in your KeychainNone

Data boundaries

Your dictation stays local

  • Your audio. It exists only as a temporary file while it's transcribed, then it's deleted, including when you cancel or something fails. Leftovers are swept when SayWrite starts.
  • Your text. SayWrite never uploads dictations, AI rewrites, History or file transcripts. Text you dictate into another app is then handled by that app, under its own settings.
  • Your screen. SayWrite never takes screenshots or reads the screen to add “context”. Per-app tone uses only the name of the app you're typing in.
  • Usage data. There are no analytics, crash reporters or telemetry SDKs. The app's own logs record state names, durations and byte counts, never audio or transcript text. Diagnostics go out only if you send feedback with “Include diagnostics” ticked, and you can read them first.
  • Account and license information is different. There's no password, and the free trial needs no account. Subscribers turn SayWrite on by signing in with the email they used at checkout (we email a link) or with a license key. To keep a subscription to 2 Macs, the app sends a random install ID, the Mac's model and its name when you turn it on; the install ID isn't derived from your hardware. License keys are then checked on your Mac.

Network

What uses the network

Speech processing stays on your Mac. Separate network uses include model setup or recovery, updates, account and license services, and feedback. Optional AI also connects to a server on your own Mac.

  1. Speech model setup and recovery. Clicking Download Model fetches the Core ML version of Parakeet (about 465 MB) from Hugging Face. Hugging Face sees an ordinary download request, including your IP address. With the model ready on disk, dictation works offline. The speech runtime may try downloading files again if the cache is incomplete or a model load fails.
  2. Update check, once a day, if you allow it. SayWrite fetches a small appcast file from the SayWrite update feed. It sends no system profile. Updates are EdDSA-signed. Turn it off in Settings › General and check by hand instead.
  3. Turning SayWrite on, for subscribers only. When you sign in with your email or enter a license key, SayWrite sends https://saywrite.app the license key or sign-in link (and your email address if you sign in), a random install ID created by SayWrite, the Mac's model and the Mac's name. That's how a subscription is kept to 2 Macs at a time; you can see and remove your Macs in your account.
  4. License renewal, for subscribers only. About once a week, and daily in the last 5 days before a subscription license expires, SayWrite asks saywrite.app to confirm the subscription and this Mac are still active, and gets a renewed key. The request contains only the license key, which includes the Mac's random install ID: no audio, text or email. It uses no cookies, refuses redirects, only talks to https://saywrite.app, and stops trying 30 days after a license lapses. Gift keys never connect. Manage Subscription asks saywrite.app for a Stripe billing link, then opens it in your browser; subscribing happens on Stripe's checkout page in your browser.
  5. Send Feedback, only when you click Send. SayWrite posts the message you typed to https://saywrite.app/api/feedback, with your email address if you add one and, while “Include diagnostics” is ticked, the app and macOS versions, Mac model, language, license status (never the key), AI and shortcut settings and the names of recent errors. “See exactly what's sent” shows the request body before you send. It does not automatically attach dictations, History or audio, nothing is sent in the background, and it uses the same hardened connection as the license check. The full list is in the privacy policy.
  6. Your own AI server, only if you turn it on. With Ollama or LM Studio selected, the text to rewrite (never audio) goes to 127.0.0.1 on your Mac. That's a loopback connection that never leaves the machine. Apple Intelligence makes no network request at all.

These service requests are separate from audio transcription. Feedback sends the message you choose to submit. For local AI, SayWrite restricts its own connection to loopback; check your server's settings too, because a local endpoint alone does not guarantee that the server never relays text elsewhere.

AI Polish

Why AI is locked to 127.0.0.1

A local model is only private if the app can't be talked into sending text somewhere else. SayWrite's AI client enforces that in code:

  • It accepts only 127.0.0.1, ::1 or localhost, and rewrites localhost to 127.0.0.1 so DNS can't redirect it.
  • LAN addresses, other hostnames, 0.0.0.0, decimal IP spellings and look-alikes such as localhost.example.com are refused, even if you type them in Settings.
  • The URL is re-checked right before every request, HTTP redirects are refused, and system proxies, cookies and caching are off.
  • AI is off until you turn it on. While it's off, SayWrite makes no AI requests of any kind.

More on choosing a model: Bring your own model and AI Polish with Apple Intelligence.

Storage

What's stored, and where

  • History (text, time, target app, length) is on by default so you can search and paste past dictations. Choose 7, 30, 90 or 365 days or forever, or turn it off. Password managers (1Password, Bitwarden, Apple Passwords, Keychain Access) are excluded by default, and spoken AI instructions aren't saved.
  • Stats store numbers: words, durations and filler-word counts without the text. Typing speed is opt-in and records keystroke timing only, never which keys you press.
  • File transcripts keep the text and timestamps, never the audio.
  • Everything lives in ~/Library/Application Support/LocalDictation/, a folder only your user account can read, plus the app's preferences. Nothing syncs to iCloud.
  • Delete it all from inside the app, or remove the folders. The privacy policy lists each one.

macOS permissions

Permissions, and why each is needed

  • Microphone: to hear you. Recording only happens while you hold or have tapped the trigger, and the pill shows a red live dot the whole time.
  • Accessibility: to type the text at your cursor and to notice the Fn key while another app is in front. Without it, SayWrite copies the text to the clipboard instead.

Those are the only two privacy permissions SayWrite asks for. It doesn't request Screen Recording, Full Disk Access, Contacts, Calendars or Location, and the Control-Option-D shortcut is a standard hot key that needs no extra permission.

Supply chain

Code signing and updates

  • Updates use Sparkle. Every update archive is signed with an EdDSA key, and the app checks that signature against the public key built into it before installing anything.
  • Builds use Apple's hardened runtime, and each release is published with its notes on the changelog.
  • Notarized. SayWrite is signed with an Apple Developer ID and notarized by Apple. Notarization is Apple's automated malware scan, not an independent security audit.

Test conditions

Where the speed and size numbers come from

Archived speech test: 0.179 seconds median from stop to result over 30 runs of one 25.93-second recording, with the model already loaded, on an M5 Pro. The minimum was 0.146 seconds and the maximum was 0.359 seconds. Measured September 26, 2026 on a MacBook Pro M5 Pro with 48 GB RAM and macOS 26.6.2, in Local Dictation 0.1.0 (pre-release build a094c7c), using Parakeet TDT 0.6B v2 through FluidAudio 0.17.4.

The app's QA path replaced the microphone with one prerecorded WAV file and ran the speech pipeline 30 times. The timer started at the stop toggle and ended when the app reached its result state. Delivery was forced to copy-only mode, with the clipboard restored after each run. The QA test used prerecorded audio and copy-only delivery. It excluded live microphone capture, typing into another app and AI Polish. It has not been rerun for the current release; this is a historical result, not a speed guarantee or a competitor comparison.

First use takes longer. The speech model was already downloaded and loaded for those 30 runs. The first model load for that build took 23.73 seconds, including Core ML preparation. A separate first run with keep-warm off and an existing compiled cache took 0.400 seconds from stop to result. These are different timings; download, preparation, live recording and typing into another app are not included in the headline warm-model result. Your chip, recording, settings and other running apps affect the wait.

About 465 MB is the speech model, not the whole app. The September 26 measurement counted 464,413,250 bytes across 22 Parakeet model files: 464.4 MB in decimal units (442.9 MiB). That is the basis for the approximate model-download size. Actual transfer size can vary, and the app, Core ML caches and optional AI models need additional space. It is not a RAM measurement.

AI Polish is a separate step. In a September 27 developer test on an M5 Pro with 48 GB RAM and macOS 26.6, six synthetic text samples were each rewritten with and without app context (12 requests per engine). Apple's on-device model took 1.30 seconds warm median and 2.66 seconds on the first request; Ollama qwen3.5:9b took 2.59 seconds warm median and 5.58 seconds with the model unloaded. These measured text rewrites, not microphone-to-insertion time. LM Studio was not benchmarked. The archived test predates the current release; model versions, settings and text length affect results. A separate 39-request Apple evaluation across 13 synthetic inputs and several rewrite actions measured a 0.47-second warm median after an excluded warm-up, with a 3.33-second maximum. That is the source of the approximate half-second figure; it is not a guarantee for every quick fix.

Source: the developer's archived app measurements and model-bundle notes dated September 26, 2026, and Polish rewrite evaluation dated September 27. These are developer tests, not an independent benchmark. No current-release or cross-app speed result is claimed here.

Verify it yourself

Check offline dictation and network activity

  1. Finish setup, download and prepare the speech model, and make sure dictation is ready. Record your app version, macOS version and Mac chip. Use a non-sensitive test sentence in a local text editor.
  2. Turn AI Polish off, disconnect Wi-Fi, Ethernet and any phone hotspot, and dictate. Check whether the text appears. A successful run demonstrates offline operation for that setup; it does not prove the app never sends data when online.
  3. Reconnect and watch SayWrite with a network monitor during startup, plain dictation and idle time. Compare the destinations with the network list above. Test optional AI Polish separately, recording which engine and model you selected. Ollama and LM Studio use loopback on your Mac; the local server's own configuration and network behavior also matter.
  4. A Terminal snapshot can help identify open connections:
    lsof -i -n -P -c LocalDictation
    The process is called LocalDictation internally. A single snapshot can miss brief connections and cannot establish what an encrypted request contains. An empty result is not a complete privacy audit.

The September 26 archived test successfully loaded and transcribed prerecorded audio with network access denied and the model already on disk. It demonstrates that speech inference can run offline. It did not audit every online code path or the current released binary. The app's source is private, and SayWrite has not had an independent security audit.

Open components

Model sources and licenses

  • Speech model: NVIDIA Parakeet TDT 0.6B v2 by NVIDIA, licensed CC BY 4.0. SayWrite downloads the Core ML conversion published by FluidInference on Hugging Face. Attribution: “Parakeet TDT 0.6B v2” © NVIDIA, used under CC BY 4.0; converted to Core ML by FluidInference.
  • Speech runtime: FluidAudio, licensed under the Apache License 2.0.
  • Updates: Sparkle (MIT-style license). Shortcuts: KeyboardShortcuts (MIT).
  • AI models you run in Ollama or LM Studio are yours, under their own licenses. Apple's on-device model is part of macOS.

Honesty

What we don't claim

  • SayWrite holds no HIPAA, SOC 2, ISO 27001 or other certifications, and it isn't a compliance product.
  • It hasn't had an independent security audit.
  • The source code is private, so you're trusting this description and your own network checks.
  • On-device doesn't protect against malware on your Mac or someone with access to your user account.

Responsible disclosure

Report a security issue

Found a vulnerability? Email hello@saywrite.app with steps to reproduce. Please give us a reasonable chance to fix it before you disclose it publicly. We'll reply, credit you if you want, and note the fix in the changelog.

Frequently asked questions

Does SayWrite upload my audio for transcription?

No. Speech recognition runs on your Mac's Neural Engine and the temporary recording is deleted after transcription. Optional AI Polish processes text with Apple's on-device model or sends it to your own server at 127.0.0.1. SayWrite's local-server restriction covers its connection to that server; the server's own configuration and network behavior also matter. Account and license requests and feedback you choose to send are separate from transcription.

Can I point SayWrite's AI at a server on my network or in the cloud?

No. SayWrite only connects to 127.0.0.1, ::1 or localhost for AI, and rewrites localhost to 127.0.0.1 so name resolution can't redirect it. LAN addresses, other hostnames and tricks like localhost.example.com are refused even if you type them, and redirects and proxies are ignored.

Is SayWrite HIPAA compliant or SOC 2 certified?

No. SayWrite holds no certifications and is not a compliance product. Its design keeps audio and text on your Mac, which may help with your obligations, but check your own requirements with your compliance team.

How can I check that SayWrite works offline?

Finish setup and download the speech model, then disconnect Wi-Fi, Ethernet and any phone hotspot and try a non-sensitive sentence. Successful offline dictation shows it can work without internet; it does not establish what happens online. For that, observe SayWrite with a network monitor during setup, dictation, AI Polish and idle time. Model downloads, updates, account and license services, and feedback are separate from audio transcription. A brief lsof snapshot can miss short-lived connections.

Is SayWrite open source?

No. The source code is private. That's why this page describes the architecture in detail and explains how to verify the network behavior yourself.

Say it messy. We'll write it neat.

Try it free for 7 days in the app: no card, no account. Then $30 a year or $5 a month, charged when you buy. No word limit.

On your phone? SayWrite runs on a Mac. Send yourself the link and download it there.

7-day free trial · no card, no account · macOS 15+ · Apple silicon