Privacy Architecture
At a glance
MailMail has no server that stores or relays email. Your iPhone connects directly to your mail provider (Gmail, Outlook, Naver…), summaries and translations are produced by Apple's on-device models on the iPhone, and only summary cards cross to the watch. The one server we run is a wake-up beacon that tells the app "there may be new mail" — and all it knows is a push token.
1. What never leaves the device
| Data | Where it lives | Protection |
|---|---|---|
| Email bodies | Local database on iPhone/iPad (SwiftData) | Encrypted until first unlock (iOS file protection). Never sent to the watch, a server, or logs |
| AI summaries (headline, key points, labels) | Local DB → watch card | Generated on-device by Apple Foundation Models. No external AI API calls |
| Translations | Memory only | Apple Translation (on-device) → discarded right after summarizing. Never stored |
| App passwords · OAuth tokens | iPhone Keychain | Device-only (iCloud Keychain sync blocked). Never sent to the watch or a server |
| Sender · subject | Local DB → watch card | The watch card carries summary-card fields only (sender, subject, headline, received time, category, reply suggestions). It has no body field |
| Profile avatar photo | App-private folder on iPhone | 256px thumbnail only, original discarded. No backup, no sync |
| Personalization learning data | iPhone local | Senders stored as hashed tokens only (no plaintext email). Pro sync ships weights and hashes, end-to-end encrypted |
| Look back retrospective (Pro) | iPhone local | The input is not the body but the summaries already made (headline, category). The retrospective boundary type has no body field, and the summary itself is written by the on-device model |
2. What leaves the device — the complete list
This is the entire set of outbound data. If it is not in this table, it is not sent.
| To | What | Why |
|---|---|---|
| Your mail provider (Gmail, Naver, Daum, work IMAP) | IMAP login, mail fetch, read/archive flags, and quick replies you choose to send (SMTP) | Direct TLS connection to your own mailbox. We are not in the path |
| Microsoft (Outlook) | OAuth sign-in, Graph API mail reads and reply sends | Same — direct. Tokens stay in Keychain |
| MailMail wake-up beacon (Cloudflare Worker) | { token, env } — the APNs push token and environment, exactly two fields | Sends a content-free push about every 10 minutes so the app can sync in the background. Any extra key is rejected with 400 |
| Same beacon (Outlook users) | subscription ID, push token, environment, verification hash | Where Microsoft posts "new mail" notifications. No mail content included |
| Apple (App Store) | Purchases and receipts | StoreKit. Verified on-device |
| Apple (iCloud, Pro, optional) | Encrypted personalization profile blob | Keeps your learning when you switch devices. Contents = weights, sender hashes, category affinity. Key lives in iCloud Keychain — we cannot decrypt it |
| Your own Reminders app | Extracted to-do title + mail subject | Pro feature, only when you tap. Never the body |
| Apple (iCloud Keychain) | Personalization salt and encryption key (32 random bytes each) | So your learning survives a device change. Apple end-to-end encrypted, so we cannot read it |
| Apple (Siri / Shortcuts) | Headline, sender, counts, the search term you speak | Results reach the system only when you ask for a briefing. For voice search, the words you speak pass through Siri into the app — the search itself runs on device. No body |
| Cloudflare (website) | Launch sign-up email, language, time | Only if you signed up on the web. Unrelated to the app; deleted after the launch notice |
Verify it yourself: put the app behind Proxyman or Charles. The only requests to mailmail.app would be /v1/register and /v1/unregister (in the current build the beacon is off, so even those do not go out) (plus /v1/graph/* for Outlook), and their bodies contain nothing but a token string.
3. What we don't do
- The app has no sign-up and no account. Using it never requires giving us your email address. The one exception is the launch-notification sign-up on this website, which we delete after the launch notice or immediately on request.
- No ad SDK, no analytics SDK, no crash-reporting SDK. Crash and performance diagnostics come from Apple MetricKit and are tallied on-device as counts only.
- No cloud AI. On devices without Apple Intelligence we do not fall back to a cloud model — we honestly show that summaries are unavailable.
- No body logging. Even debug builds contain no code that writes an email body to a log.
- No bodies to the watch. The watch card type has no body field at all.
4. How the code enforces it
Enforced by types and link structure, not by policy — so it is hard to break by accident later.
- Boundary types — the watch card, the beacon registration payload and the Reminders request are separate structs with no field a body could fit in. Unit tests fail if a body ever passes through.
- Cloud inference code is not linked — an experimental cloud-inference interface lives in a separate package that the shipping app does not link. It is not a runtime switch; it does not compile in.
- The server rejects surplus data — push registration (
/v1/register) validates an exact two-field schema and returns 400 on any extra key. The other endpoints discard keys they do not know rather than storing them. - Device-only Keychain — credentials use
AfterFirstUnlockThisDeviceOnly, so they never sync via iCloud Keychain. - A fresh AI session per email — summary sessions are created and discarded per message, so one email's content never bleeds into another's prompt.
5. Honest limits
- Your mail provider (Google, Microsoft, Naver) of course has your mail. MailMail simply adds nothing in between.
- AI summaries require an iPhone or iPad that supports Apple Intelligence. That is the cost of not having a cloud fallback.
- If you keep device backups on (iCloud or a computer), the app's local database is included in that backup. Apple's backup encryption applies and we cannot access it, but it is an exception to "never leaves the device," so we say so.
- The wake-up beacon and iCloud personalization sync in the table above are turned off in the current release build (server and container provisioning pending). We will update this page before turning them on.
- The on-device model and translation engine are Apple's. We verified they run on-device; their internals follow Apple's public documentation.
- Outlook goes through Microsoft's sign-in screen, which follows Microsoft's policies.
Changelog
- 2026-09-11 — First publication (as of build 24).
- 2026-09-12 — Updated for build 38. Added the Look back (Pro) retrospective to "what never leaves the device" (its input is existing summaries, not the body). Noted spoken search terms in the Siri row.
- 2026-09-12 — Updated for build 34. Added quick-reply sending (SMTP/Graph), iCloud Keychain personalization keys, Siri briefing, and the website launch sign-up to the "what leaves the device" table. Noted that the wake-up beacon and iCloud sync are off in the current build. Added the device-backup limitation.