MAILGATE  DOCS
Reference

Feature matrix

What MailGate ships today versus Gmail, Outlook, Proton Mail, and Web3 email competitors — with a migration-readiness scorecard for the gaps that still stand between us and a typical Gmail user switching over.

TL;DR: MailGate is the most complete production-grade demonstration of the Sui confidential-computing stack shipping today: accounts are on-chain MailGateAccount shared objects, every email body is encrypted with Seal IBE under the recipient's email hash, the key custodian is a Nautilus / AWS Nitro enclave whose PCR fingerprints are pinned on-chain and verified by Move, and the inbound spam barrier is an economic toll paid in Stripe USD or Circle native USDC. The headline gaps before a typical Gmail user can fully migrate are: scheduled send (UI exists, not wired), snooze, custom labels, email signatures, vacation responder, calendar/contacts suite, native mobile, and SMTP submission for third-party clients (IMAP is shipped; authenticated SMTP submission is not yet exposed). Outbound DKIM signing is also still a stub. Everything else on the email-core checklist is shipped.

Outbound delivery currently relays through Resend. Self-operating an internet-facing MTA requires months of warm-up traffic, IP reputation building, feedback-loop registrations with the major mailbox providers (Gmail, Outlook, Yahoo), and continuous postmaster monitoring before mail reliably lands in the inbox. Until that operational lift is justified, MailGate signs and dispatches all outbound mail through Resend's already-warmed infrastructure. Inbound mail, encryption, key custody, and the on-chain economic layer are unaffected — only the last-mile send to non-MailGate recipients depends on Resend.

Legend: ✅ shipped · ⚠️ partial / stubbed / UI-only · 🛣️ planned · ❌ not started · N/A not applicable.

This page is regenerated by reading the code, not the old docs/ tree. Anything marked ✅ has a concrete implementation surface (a Move entry function, an Elysia route, a Drizzle table, a Rust module, or a React component) you can grep for.

Could I move my Gmail life to MailGate today?

Short answer: about 65% of the way there. Daily-driver email already works — read, compose, reply, forward, search, threads, attachments, agents, payments — and IMAP4rev2 is now shipped for third-party mail clients. The remaining product work is classical Gmail polish (custom labels, snooze, signatures, schedule send, undo-send), native mobile, authenticated SMTP submission for clients, and the calendar / contacts suite. None of the gaps require new cryptography.

Receive & read mail (web)
95%
Compose & send
80%
Privacy & encryption
95%
Anti-spam (economic toll)
100%
AI agents & delegation
95%
Folders & organization
55%
External delivery & relay
60%
Mobile & desktop apps
5%
Calendar & contacts suite
5%
Overall migration readiness
65%

Migration readiness scorecard

The table below is the supporting detail for the bar chart above — same buckets, with the specific gaps spelled out.

Capability bucketStatusWhat still stands between us and a Gmail user moving over
Receive & read mail (web)✅ ReadyInbox, threads, search, attachments, encrypted bodies, SSE live updates — all shipped.
Compose & send (web)✅ ReadyRich-text Tiptap editor, recipient chips (max 25), CC/BCC, attachments, reply / reply-all / forward, drafts.
Folders & organization⚠️ MinimalInbox / Archive / Outbox / Drafts / Starred / Spam / Trash only. No custom labels, no nested folders, no drag-to-move.
Scheduled send⚠️ UI-onlyScheduleModal ships in the compose UI, but useCompose hard-rejects with "Live send does not support scheduled send yet". No scheduled_for column on outbound mail; no scheduler job.
Snooze❌ Not startedNo code path, no DB column, no UI.
Email signatures❌ Not startedNo signature field on user_v2; settings page has no signature editor.
Vacation auto-responder⚠️ Agent skill onlyAvailable via the AI auto-reply skill (LLM-generated reply per inbound). No classical "from / to / message" responder.
Native mobile app❌ Web onlyResponsive web works; no iOS / Android binary.
IMAP / SMTP for third-party clients⚠️ IMAP shipped; SMTP submission pendingIMAP4rev2 is implemented in crates/imap_protocol (ACL, quota, IDLE, CONDSTORE/QRESYNC, ENABLE/OBJECTID+, namespace, shared folders). Authenticated SMTP submission for clients is not yet exposed.
Custom domains⚠️ Scaffoldedlib/mailDomain.ts resolves the domain from env; no per-user custom-domain provisioning UI or DNS automation.
Calendar / contacts suite❌ Not startedContacts UI exists (/contacts) but only as a gating-list manager — no vCard, no CalDAV, no events.
Drag-and-drop folder moves❌ Not startedBulk moves work via the action bar; no DnD handlers.
Undo send❌ Not startedNo "Undo send" toast / delay window.
ML spam filter⚠️ Manual onlyThe spam folder exists and users can mark/unmark, but there is no classifier — economic toll + whitelist is the actual anti-spam mechanism.
Outbound DKIM signing⚠️ Stubbedservice/tee.ts signDkim() throws "TEE integration not implemented". Resend signs on its own domain for external mail today; the gap is for self-hosted relays.
OAuth login (Google / Apple / Microsoft)❌ Not startedBetter Auth is configured with email+password, username, passkey, 2FA — no social providers.
Login: Sui wallet✅ ReadyChallenge-and-verify flow, on-chain accountObjectId linkage, gas-sponsored.
Login: passkey + 2FA TOTP✅ ReadyBetter Auth passkey + twoFactor plugins.
AI agents with on-chain delegate⚠️ Discovery onlyMCP can report live on-chain delegates; agent JWTs, policy enforcement, and skills are not rebuilt in Rust yet.
Pay-to-deliver economic toll✅ ReadyStripe USD + Circle native USDC. Group bundles, payment links, sender-specific overrides.
Encrypted at rest + in transit✅ ReadyEvery body, subject, sender, recipient is Seal-encrypted; search is HMAC blind-tag.

So: the protocol-level differentiators are all in. The gap to "Gmail replacement" is a small, well-defined list of classical email-app features. None of them require new cryptography — they're product work.

Sui stack integration

MailGate is built specifically to showcase the Sui confidential-computing stack end-to-end. This is the area where MailGate has no real competition: classical providers run zero of these, Web3-native competitors run at most one.

Sui technologyMailGateGmailOutlookProton Mail
Sui Move smart contracts✅ Accounts, gating lists, delegates, tolls, Stripe commitments, account-upgrade commitments — all on-chain shared/owned objects. Modules: mailgate, enclave, seal_policy, caps.
Seal (Threshold IBE)✅ Every email body encrypted under SHA-256(recipient_email) as the IBE identity; fleet master seed Seal-wrapped on-chain (write-once) and decrypted only inside an attested TEE. Sealed env-secrets blob uses a separate mailgate:sealed-env:<env>:v1 identity namespace.⚠️ Proton uses classical OpenPGP — not threshold; single-party key custody.
Nautilus (Nitro TEE)✅ Rust enclave binary in an AWS Nitro Enclave; PCR0/1/2 fingerprints pinned on-chain via EnclaveConfig; NSM attestation verified by Move at register_enclave time. Fleet-wide HKDF-derived signing key + per-boot Enclave object.❌ — Swiss datacenter trust, no remote attestation.
Walrus (decentralized blob storage)🛣️ Roadmap — encrypted bodies and attachments currently live in Cloudflare R2 (apps/api/src/lib/storage.ts). Architecture cleanly swaps in.
Gas sponsorship (Enoki + admin fallback)✅ All user-facing transactions are sponsored via Enoki on testnet/mainnet, with an admin-keypair fallback for localnet. Users never hold SUI.
On-chain event indexer✅ Rust sui-indexer crate polls events (AccountCreated, TollUpdated, BlacklistAdded, DelegateAdded, StripeMailCommitted, EnclaveRegistered, FleetMasterSeedSet, etc.) → PostgreSQL mirror with cursor + dead-letter queue.
Native Circle USDC (on Sui)✅ Inbound tolls settle in Circle's native Sui USDC (SUI_TOLL_COIN_TYPE resolved per network); Stripe USD payments anchored on-chain via StripeMailCommitment.

Identity, ownership & auth

CapabilityMailGateGmailOutlookProton
Account ownershipUser-owned Sui shared object (MailGateAccount<T>) — transferable via transfer_account_owner, censorship-resistant.Google-owned row in a DBMicrosoft-owned rowProton-owned row
Wallet login (Sui)✅ Challenge / verify via /auth/challenge + /auth/verify; gas-sponsored.
Email + password✅ Better Auth emailAndPassword.
Username login✅ Better Auth username plugin.
Passkey (WebAuthn)@better-auth/passkey.
2FA (TOTP)✅ Better Auth twoFactor.
Multi-session✅ Better Auth multiSession.⚠️ Limited
Captcha on signup✅ Cloudflare Turnstile.
OAuth login (Google/Apple/MS)❌ Not configured.N/AN/A
Custodial → self-custody upgrade✅ Paid upgrade flow via AccountUpgradeCommitment (on-chain) + Stripe/USDC settlement.
Web2 → web3 upgradeweb2UpgradePlugin + paid checkout.
External email link & verifyexternal_emails table + verification code.N/AN/A✅ Aliases
Can the provider deplatform you?❌ — your account is a Sui shared object; the operator can withhold UI but cannot delete your account or your encrypted blobs from the chain.

Encryption & confidentiality

CapabilityMailGateGmailOutlookProton
E2E encryption of body✅ Seal IBE, identity = SHA-256(recipient_email). Plaintext only exists inside the attested TEE.❌ TLS only❌ TLS only✅ OpenPGP
At-rest encryption of body✅ Seal ciphertexts stored in R2 (encryptedBodyUri).✅ Google-held keys✅ Microsoft-held keys✅ Proton-held keys
Encrypted metadata fields✅ Subject, sender, recipient all AES-SIV encrypted (encryptedSubject, encryptedSender, encryptedRecipient).⚠️ Subject encrypted Proton↔Proton only
Searchable encryption✅ HMAC blind-tag index per field (subjectBlindTag, senderBlindTag, recipientBlindTag) — server can match exact tags without seeing plaintext.✅ Plaintext index✅ Plaintext index⚠️ Plaintext index in Proton's DB
Key custodianNo single party — Seal threshold key servers gated by Move policy + attested TEE.GoogleMicrosoftProton
Remote-attested key management✅ PCR0/1/2 pinned on-chain; register_enclave rejects any boot whose attestation doesn't match.
Versioned crypto key ringenclave_key_ring_versions table; ciphertexts carry a 1-byte version prefix; rotation re-derives keys from the unchanged master seed.
Subpoena resistance✅ Operator cannot decrypt user mail (threshold Seal + attested TEE separation).⚠️ Proton can be compelled to log IPs
Inbound DKIM / SPF / DMARC verification✅ Verified inside the TEE before encryption via mail_auth; results stored in inboundMails.authResults; DMARC reject policy enforced.
Outbound DKIM signing⚠️ signDkim() and verifyDkim() in service/tee.ts are stubbed. Resend signs with its own DKIM keys for the current external relay path, so deliverability is unaffected today; in-enclave signing is only required once MailGate operates its own outbound MTA.

Anti-spam & access control

CapabilityMailGateGmailOutlookProton
Economic toll (pay-to-deliver)✅ Unknown senders pay Circle USDC on-chain or fiat USD via Stripe. Toll amount is per-mailbox, configurable.
Whitelist (free-pass)✅ On-chain whitelist VecMap on MailGateAccount, up to 1000 entries.
Blacklist✅ On-chain blacklist VecMap, enforced in Move (precedence: blacklist > whitelist).
User-configurable toll amountupdate_toll Move entry; UI in Settings → Fees.
Per-sender fee overridessender_fee_overrides table — different toll for specific senders.
Group toll (multi-recipient bundle)✅ Single bundle payment for many recipients via payment-bundle.
Mailbox earns revenue from inbound✅ Toll accrues to on-chain MailGateAccount.balance. Withdrawal endpoint shipped (/balance/withdraw-to-wallet).
Top-up balance/balance/top-up/stripe.N/AN/AN/A
Transfer balance to agent/balance/transfer-to-agent.N/AN/AN/A
ML spam filter⚠️ Manual mark-spam only; no classifier.
Mark / unmark spam✅ UI shipped (no ML — moves between spaminbox folders).

AI agents & delegation

This is the area where MailGate has no peer outside of Gmail's closed Gemini integration.

CapabilityMailGateGmailOutlookProton
Agent as first-class on-chain principalDelegatePolicy on MailGateAccount.delegates with a 5-bit permission bitmap: READ (1), SEND (2), CONTACTS (4), GATING (8), TOLL (16).
Custodial agent (TEE-held key)prepare/finalize flow; Seal-encrypted key in agent_keys.
Self-custody agent (external wallet)pending_agents staging table; agent holds own Sui keypair.
Direct E2E agent decryptionseal_approve_delegate Move policy — no re-encryption shim.
Off-chain policy controlsagent_policies table: rate limits (maxReadsPerHour, maxSendsPerHour/Day), recipient allow/block lists, daily toll budget cap (maxTollSpendPerDay), requireApproval, directAccess.⚠️ Some via Workspace admin⚠️ Some via 365 admin
MCP (Model Context Protocol) server⚠️ Streamable HTTP in the enclave with OAuth client registration, PKCE consent, and per-request bearer validation.⚠️ Copilot (closed)
MCP tools shipped⚠️ Nine tools: whoami, list_agents, check_sender, get_mailbox_summary, list_emails, read_email, search_emails, send_reply, and compose_email.⚠️
MCP forward_email❌ Not advertised until a recipient-scoped forwarding implementation exists.⚠️
Per-mailbox LLM configllm_configs table — provider/model/API-key-blob/monthly-token-cap.
Built-in skillsauto-reply, triage (in apps/api/src/agents/skills).
Cron-scheduled skill triggersskill_installations.cronExpression + agent_trigger_queue with backoff & chain-depth tracking.⚠️ Apps Script⚠️ Power Automate
Inbound-mail skill triggersagents/inbound-trigger.ts.⚠️ Apps Script⚠️ Power Automate
Human-in-the-loop skill approvalsskill_approvals table + UI (Approvals tab).
Agent spending log (audit trail)agent_spending_log enforces daily budgets.
Auditable agent actionsaudit_logs table — read_email, send_email, update_contacts, update_gating, pay_toll, add_delegate, remove_delegate.⚠️ Some⚠️ Some
Agent JWT replay protectionagent_jwt_replay table.N/AN/AN/A
Sponsored delegate add/remove/delegate/sponsor-add, /delegate/sponsor-remove, /delegate/sponsor-execute.N/AN/AN/A

Email core features

This is the user-facing checklist. Use it to gauge "could I do my daily email here?"

Reading & inbox

FeatureMailGateGmailOutlookProton
Inbox list with previewsMailListPanel, paginated.
Three-pane (folder / list / reading) layout✅ Split / fullscreen toggle.
Threading (conversation view)✅ Deterministic 16-char hex threadId derived from RFC-5322 headers (Message-ID/In-Reply-To/References) inside the TEE.
Unread counts✅ Per-folder via /mail/unread/count.
Star / unstarisStarred on inbound + outbound.
Mark read / unread (incl. bulk)mark-all-read, individual toggles.
Search✅ Blind-index over encrypted subject, sender, recipient. Cannot do full-text body search yet.✅ Full text✅ Full text⚠️ Encrypted full text (Proton's client-side index)
Live updates (push)✅ Server-Sent Events via /mail/subscribe.
Reading pane with rich HTML✅ Sanitized via sanitizeMailHtml.
Attachment list & download✅ Encrypted attachments via /attachment/:id/download + client-side decrypt.

Composing & sending

FeatureMailGateGmailOutlookProton
Rich-text editor✅ Tiptap with bold / italic / underline / strikethrough / lists / blockquote / link / text color / alignment / undo-redo.
Recipient chips (To / Cc / Bcc)✅ Up to 25 total recipients.
Reply / Reply-all✅ UI buttons + keyboard r / a.
Forward✅ UI button + keyboard f.
Attachments✅ Client-side AES-encrypted, presigned PUT to R2 (/attachment/presign + /confirm).
Drafts (autosaved)drafts table; auto-deleted on send.
Schedule send⚠️ UI exists (ScheduleModal) but compose hook throws "Live send does not support scheduled send yet". No backend job runner.
Undo send
Email signature❌ No signature config on the user model or settings page.
Templates / canned responses❌ Closest equivalent is the auto-reply AI skill.⚠️
Inline images (CID)⚠️ Not specifically wired in compose.

Organization

FeatureMailGateGmailOutlookProton
System folders✅ Inbox, Archive, Outbox, Drafts, Starred, Spam, Trash.
Custom labels / tagsmail_folder is a fixed Postgres enum (inbox/archive/trash).
Nested folders
Archive/mail/archive, /mail/inbox/archive.
Trash with restore/mail/trash, /mail/trash/restore, /mail/trash/all.
Auto-purge trash (countdown UI)TrashCountdown component.
Snooze⚠️
Drag-and-drop move❌ Move is via action bar.
Bulk select & action barMailboardHeaderBulkBar.
Keyboard shortcutsj/k navigate, o/Enter open, u toggle unread, e archive, # trash, s star, ! spam, r reply, a reply-all, f forward, / search, x checkbox, Esc close, Shift+I/O/D/S jump to folder, plus Cmd/Ctrl+Z undo.

External integration & delivery

FeatureMailGateGmailOutlookProton
Send to external (non-MailGate) addresses✅ Routed through the Resend API. Self-operated MTA is deferred until IP reputation, FBL enrollment, and postmaster tooling are in place.
Self-operated outbound MTA (own IPs, own reputation)🛣️ Roadmap — Resend is the current relay. Direct-to-MX send is gated on warm-up traffic and postmaster ops, not on protocol work.
Receive from external SMTP✅ Internet-facing SMTP listener inside the enclave (port 2525 dev, 25/465 prod).
Proxy / forwarding modeMODE_PROXY on MailGateAccount — TEE decrypts and relays plaintext via STARTTLS to a configured downstream address.✅ Filters✅ Aliases
IMAP / POP3 / SMTP for clients (Outlook, Apple Mail, Thunderbird)⚠️ IMAP4rev2 shipped (ACL, quota, IDLE, CONDSTORE/QRESYNC, ENABLE/OBJECTID+, namespace, shared folders, UNAUTHENTICATE, LOGINDISABLED). POP3 and authenticated SMTP submission not yet exposed.⚠️ Bridge (paid)
Custom domains⚠️ MAILGATE_DOMAIN env-driven; no per-user domain provisioning UI.✅ Workspace✅ 365✅ Paid
Calendar suite
Contacts suite⚠️ /contacts page exists but only manages gating entries (whitelist/blacklist), not classical address book.
Native mobile app❌ Responsive web only.

Per-account settings & storage

FeatureMailGateGmailOutlookProton
Storage quota✅ Default 1 GiB per mailbox (storage_quota_bytes), tracked via storage_used_bytes.✅ 15 GB free✅ 15 GB free✅ 1 GB free
Storage indicator UIStorageIndicator.
Light / dark themeThemeProvider toggle.
Notification digest (periodic summary)notification_queue.deliveryType=digest; user-configurable digestFrequency / digestTime / digestTimezone on the user model. Wired sender uses Resend.
Billing tier / subscriptions⚠️ billingTier and premiumUnlockedAt columns exist; no subscription flow.✅ Workspace✅ 365✅ Plus / Unlimited

Payments & monetization

CapabilityMailGateGmailOutlookProton
Pay-per-email economic layer✅ Fiat USD via Stripe + native Circle USDC on Sui.
Stripe checkout for senders/payment/:id/stripe/checkout + webhook.N/AN/AN/A
Stripe webhook → on-chain commitment✅ TEE-signed StripeMailCommitment Move call.N/AN/AN/A
USDC bundle payments/payment/bundle/:sendGroupId/{prepare,confirm-wallet,stripe-checkout,status}.N/AN/AN/A
Payment links (no login)/payment/link/:token/{prepare,confirm,confirm-wallet,request-code}.N/AN/AN/A
Verify / confirm pending payments/payment/:id/verify, /payment/:id/confirm.N/AN/AN/A
Payment history/payment/history, /payment/pending.N/AN/AN/A
Expired-payment cleanup/payment/cleanup.N/AN/AN/A
On-chain balance & withdrawalwithdraw_balance Move entry; custodial-wallet withdrawal endpoint shipped.
User captures value from attention✅ Toll revenue accrues to mailbox balance.
Subscription tier⚠️ DB columns exist (billingTier, premiumUnlockedAt) but no checkout flow.✅ Workspace✅ 365

Decentralization & trust model

PropertyMailGateGmailOutlookProton
Trusted parties required to read your mailZero — threshold Seal + attested TEE separation of duties.GoogleMicrosoftProton
Account survives provider going offline✅ Wallet + Seal lets a new operator decrypt with the same on-chain root.⚠️ Export only
Code integrity verified✅ On-chain PCR pinning + NSM attestation verified inside Move.
Censorship resistance✅ Account is a Sui shared object — operator cannot delete the row from the chain.⚠️
Open protocol / verifiable contracts✅ Move source on-chain; published package id is the canonical reference.⚠️ Frontend FOSS
Operator audit trailaudit_logs table + on-chain events for every sensitive mutation.⚠️⚠️
Indexer can be re-run independentlysui-indexer is a stand-alone Rust binary against any Sui RPC.N/AN/AN/A

Web3-native competitors

CapabilityMailGateDmail NetworkEtherMailSkiff (shutdown 2024)
On-chain account object✅ Sui shared MailGateAccount<T>⚠️ BNB/Polygon NFT alias only⚠️ ENS-bound alias❌ Off-chain
Threshold IBE encryption✅ Seal⚠️ MLS-style E2E (acquired + sunset)
Remote-attested TEE✅ Nautilus / Nitro, PCR-pinned on-chain
Pay-to-deliver economic toll✅ Stripe USD + Circle USDC✅ Read-to-earn (advertiser-paid)
Per-recipient configurable price✅ + per-sender overrides
On-chain delegate / agent✅ 5-bit permission bitmap
MCP server✅ With ~15 tools
Native fiat ramp (Stripe-anchored)
Gas sponsorship for end users✅ Enoki + admin fallback⚠️⚠️N/A
Open-source Move contracts⚠️ Partial⚠️ Frontend FOSS
Classical email-app features (drafts, threads, search, attachments, …)✅ Most shipped⚠️⚠️✅ Best-in-class for Web3 at the time

Dmail and EtherMail are aliasing layers (a wallet address ↔ a username), not full mail providers — they rely on classical SMTP under the hood and have no confidential-computing stack. Skiff had the best classical E2E story but was acquired by Notion and shut down in early 2024. MailGate is the only entrant pairing on-chain identity, threshold-IBE encryption, attested key custody, configurable economic anti-spam, and a delegate / agent protocol into one product.

Where we are vs "Gmail user can switch"

To close the gap to a typical Gmail user adopting MailGate as their primary inbox, in rough priority:

  1. Wire scheduled send end-to-end. UI is done; needs a scheduled_for column on outbound_mails, a scheduler worker, and the compose-hook gate removed.
  2. Custom labels. Replace mail_folder enum with a labels table + many-to-many; refactor the sidebar.
  3. Snooze. New snoozed_until column + a sweeper that returns the row to inbox when the time hits.
  4. Email signatures. New column on user_v2 + a settings editor + signature injection in send-orchestrator.
  5. Vacation responder (classical). A non-AI, deterministic auto-reply path that doesn't require an LLM key. The AI skill stays as the upgraded option.
  6. Outbound DKIM signing + self-operated MTA. Implement signDkim() inside the enclave and stand up a warmed sending infrastructure (own IPs, FBL enrollments, postmaster tooling) so MailGate can retire the Resend relay. Until then, Resend handles the last mile and signs with its own DKIM keys, which is fine for deliverability but means the outbound path is not yet end-to-end self-hosted.
  7. Native mobile app. Capacitor / React Native wrapper around the existing PWA is the cheapest start.
  8. Authenticated SMTP submission for clients. Complements the shipped IMAP fetch service; requires exposing a user-facing SMTP submission endpoint inside the enclave.
  9. Calendar + contacts suite. Largest scope; potentially out of v1 charter.

Everything in this list is product engineering, not new cryptography. The hard parts — on-chain accounts, threshold IBE, attested key custody, economic anti-spam — are already shipped.

How is this guide?

Last updated on

On this page