[{"data":1,"prerenderedAt":1295},["ShallowReactive",2],{"search":3,"content-developer\u002Ftransport-security":478,"surround-\u002Fdeveloper\u002Ftransport-security":1290},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,304,308,312,316,320,324,328,332,336,340,344,348,352,356,359,363,367,371,375,379,383,387,391,395,399,403,407,411,415,419,423,427,431,435,439,443,447,451,455,459,462,466,470,474],{"path":5,"title":6,"description":7},"\u002Fguide","Guide","Product guides for Owlat — a modular, self-hosted email platform. Learn how to send campaigns, run a personal mailbox, manage a team inbox, and more.",{"path":9,"title":10,"description":11},"\u002Fguide\u002Fgetting-started","Welcome to Owlat","Set up your Owlat workspace and send your first email — from deploying the stack to verifying a domain, building your audience, and launching a campaign.",{"path":13,"title":14,"description":15},"\u002Fguide\u002Fcontact-properties","Contact Properties","Custom fields that extend built-in contact data with your own values for segmentation.",{"path":17,"title":18,"description":19},"\u002Fguide\u002Ftopics","Topics","Topics are explicit audience groups you manage by hand — ideal for opt-in subscribers, imported cohorts, and organized contact buckets you target with campaigns.",{"path":21,"title":22,"description":23},"\u002Fguide\u002Fsegments","Segments","Build dynamic, rule-based contact groups from properties, email activity, and topic membership, re-evaluated from current data each time they're used.",{"path":25,"title":26,"description":27},"\u002Fguide\u002Fforms","Forms","Form Endpoints collect new contacts from your website or landing pages by exposing a public endpoint that accepts submissions and feeds them into a topic.",{"path":29,"title":30,"description":31},"\u002Fguide\u002Fcampaigns","Campaigns & Reporting","Build and send marketing campaigns to a topic or segment with the three-step wizard, optional A\u002FB testing, and full delivery reporting.",{"path":33,"title":34,"description":35},"\u002Fguide\u002Fab-testing","A\u002FB Testing","Compare two variants of a campaign on a test group, then automatically or manually send the winning version to the rest of your audience.",{"path":37,"title":38,"description":39},"\u002Fguide\u002Fautomations","Automations","Send emails automatically based on triggers, delays, and conditions — build welcome series, trial flows, and follow-ups once and let Owlat run them.",{"path":41,"title":42,"description":43},"\u002Fguide\u002Ftransactional","Transactional Emails","One-to-one emails your application triggers in response to a user action — password resets, order confirmations, welcome emails, and similar notifications.",{"path":45,"title":46,"description":47},"\u002Fguide\u002Fcreate-campaign","Create a Campaign","Walk through Owlat's three-step campaign wizard: Setup, Content, and Review & Send.",{"path":49,"title":50,"description":51},"\u002Fguide\u002Fsend-campaign","Send & Monitor a Campaign","How to send your campaign and track its performance with real-time metrics.",{"path":53,"title":54,"description":55},"\u002Fguide\u002Fquick-start","Quick Start","The fastest path from a blank Owlat workspace to a live email campaign, from your first template through sending and reviewing results.",{"path":57,"title":58,"description":59},"\u002Fguide\u002Ftransactional-setup","Transactional Email Setup","Set up and send transactional emails like password resets and order confirmations via the Owlat API and SDKs.",{"path":61,"title":62,"description":63},"\u002Fguide\u002Fdeliverability","Deliverability","Verify sending domains, manage your blocklist, monitor sending reputation, and stay compliant so your emails reach the inbox.",{"path":65,"title":66,"description":67},"\u002Fguide\u002Fapi-keys-webhooks","API Keys & Webhooks","Create API keys for programmatic access and set up outbound webhooks to receive real-time notifications for email and contact events.",{"path":69,"title":70,"description":71},"\u002Fguide\u002Ffeature-flags","Feature flags","Owlat is modular — every feature listed in this guide can be turned on or off. This page is the user-facing overview of how to do it.",{"path":73,"title":74,"description":75},"\u002Fguide\u002Fteam-permissions","Team & Permissions","Use role-based access to control what each member of your organization can do, with Owner, Admin, and Editor roles.",{"path":77,"title":78,"description":79},"\u002Fguide\u002Faudit-logs","Audit Logs","A chronological record of significant actions in your Owlat organization, so you can see who did what and when.",{"path":81,"title":82,"description":83},"\u002Fguide\u002Fshare-links","Share Links","Create temporary preview links to share email designs with stakeholders who don't have dashboard access.",{"path":85,"title":86,"description":87},"\u002Fguide\u002Fpostbox","Postbox — Personal Email","Per-user mailboxes with a webmail interface and native IMAP\u002FSMTP support. Run your own Gmail-equivalent personal mailbox on your Owlat instance.",{"path":89,"title":90,"description":91},"\u002Fguide\u002Fmigrate-from-google","Migrate from Google","Import your full Gmail history into Owlat over IMAP, and let your AI assistant learn from every imported conversation.",{"path":93,"title":94,"description":95},"\u002Fguide\u002Fteam-inbox","Team Inbox","Triage inbound email as a team: read AI-classified threads, approve, edit or reject agent drafts, work the review queue, and manage quarantine.",{"path":97,"title":98,"description":99},"\u002Fguide\u002Femail-editor","Email Editor","A block-based visual editor for building responsive emails that render consistently across desktop, mobile, Outlook, Gmail, and Apple Mail.",{"path":101,"title":102,"description":103},"\u002Fguide\u002Fai-agent","AI Agent & Autonomy","Configure the AI agent that classifies and drafts replies to inbound mail: auto-reply settings, the health dashboard, circuit breakers, autonomy rules, and the knowledge backfill.",{"path":105,"title":106,"description":107},"\u002Fguide\u002Fknowledge-graph","Knowledge Graph","Browse, search, and manage Owlat's typed organizational knowledge — the 7 entry types, source attribution, confidence decay, relations, and how entries are extracted from mail.",{"path":109,"title":110,"description":111},"\u002Fguide\u002Ffiles","Files","Upload, browse, search, tag, and version documents in the file library.",{"path":113,"title":114,"description":115},"\u002Fguide\u002Fchat","Team Chat","Use Owlat's built-in team chat: public and private channels, direct messages, mentions, attachments, and channels linked to an inbox conversation.",{"path":117,"title":118,"description":119},"\u002Fguide\u002Fcode-tasks","Code Tasks","Queue coding-agent tasks, watch them move from queued through review, and run the code-worker sidecar that opens the pull requests.",{"path":121,"title":122,"description":123},"\u002Fguide\u002Faudience-data","Audience Data: Identities, Relationships & Timeline","Unify a contact across email, phone, and messaging channels, merge duplicates, map relationships, and read the cross-channel interaction timeline.",{"path":125,"title":126,"description":127},"\u002Fguide\u002Fimporting-contacts","Importing & Exporting Contacts","Bring contacts into Owlat from a CSV or from Mailchimp and Stripe, export them back out, and run bulk operations on your audience.",{"path":129,"title":130,"description":131},"\u002Fguide\u002Faccount","Your Account & Data","Export your data as JSON or CSV, request account deletion with a 30-day grace period, and use the onboarding checklist and the public preference center.",{"path":133,"title":134,"description":135},"\u002Fguide\u002Fchannels","Communication Channels","Configure SMS, WhatsApp, and generic-webhook channels, monitor channel health, and understand which channels are fully live today.",{"path":137,"title":138,"description":139},"\u002Fguide\u002Fdesktop-app","Desktop App","Install the Owlat desktop app, connect one or more workspaces, switch between them, and use native notifications, the dock\u002Ftaskbar unread badge, shortcuts, and deep links.",{"path":141,"title":142,"description":143},"\u002Fguide\u002Femail-templates","Email Templates","Reusable email designs that define the structure, content, and personalization of every campaign and transactional message you send in Owlat.",{"path":145,"title":146,"description":147},"\u002Fguide\u002Fai-assistant","AI Assistant","Owlat's multi-turn, streaming, tool-calling AI assistant — a private chat surface that can search your workspace and draft copy, plus @assistant replies inside team chat.",{"path":149,"title":150,"description":151},"\u002Fguide\u002Fsecurity-scanning","Sending Security & Scanning","Owlat's security scanning: a content check for spam and phishing, an attachment scan for malware, and a Google Safe Browsing URL check. Suspicious content goes to a review queue.",{"path":153,"title":154,"description":155},"\u002Fguide\u002Fsystem-updates","System & Updates","The owner-only System & Updates screen: your current Owlat version, container health, LLM spend, and the in-app one-click updater with history.",{"path":157,"title":158,"description":159},"\u002Fguide\u002Foperating-modes","Operating Modes","The different ways to run Owlat at a company — read external mailboxes over IMAP, send transactional or marketing email through a delivery provider, host your own mail server, or run a team inbox with AI — and the rules that keep each combination coherent.",{"path":161,"title":162,"description":163},"\u002Fguide\u002Freply-queue","Reply Queue","A task list of emails waiting on your reply — Postbox detects unanswered asks, ranks them by urgency and age, and clears them the moment you respond.",{"path":165,"title":166,"description":167},"\u002Fguide\u002Fsmart-inbox","Smart Inbox","Split your Postbox inbox into People, Newsletters, Notifications, and Receipts — a deterministic classifier first, AI refinement for the ambiguous middle, off by default, and a per-sender override that's remembered.",{"path":169,"title":170,"description":171},"\u002Fguide\u002Fpostbox-settings","Postbox settings reference","Every Postbox behavior toggle in one place — auto-advance, reply defaults, density, writing suggestions, auto-summaries, notifications, the on-device cache, and the send sound — with what each does and its default.",{"path":173,"title":174,"description":175},"\u002Fguide\u002Fcalendar-availability","Calendar Availability for Scheduling Replies","Point Owlat at a read-only calendar feed so AI scheduling replies propose your real open times instead of only echoing the sender's.",{"path":177,"title":178,"description":179},"\u002Fguide\u002Fconnect-your-ai","Connect your AI","Pick the AI backend every Owlat AI feature uses — a hosted provider via an API key (OpenAI, Anthropic, Google, Azure OpenAI, OpenRouter) or a model you host yourself (Ollama, vLLM, llama.cpp) — plus the local-by-default embeddings that make retrieval work under any choice.",{"path":181,"title":182,"description":183},"\u002Fguide\u002Fsealed-mail","Sealed Mail — End-to-End Encryption","How Owlat encrypts personal mail end-to-end between Owlat workspaces, when a message auto-seals versus sends in the clear, and how to read the Sealed and sender-verified badges.",{"path":185,"title":186,"description":187},"\u002Fguide\u002Fsaved-blocks","Saved Blocks","Create reusable, linked content blocks you can drop into any email — edit one and every email that uses it updates automatically.",{"path":189,"title":190,"description":191},"\u002Fguide\u002Fsealed-mail-recovery-kit","Sealed Mail Recovery Kit","What a Sealed Mail recovery kit is, when it's offered, how to download and store it, how to restore access after a rebuild, and the blunt warning about losing it.",{"path":193,"title":194,"description":195},"\u002Fguide\u002Fmedia-library","Media Library","Manage, organize, search, and reuse images and files across your emails from one centralized hub.",{"path":197,"title":198,"description":199},"\u002Fguide\u002Femail-theme","Email Theme","Set your organization's default colors, font, and email width so every new template starts from a consistent baseline.",{"path":201,"title":202,"description":203},"\u002Fguide\u002Ftranslations","Translations","Send one email in multiple languages: add per-language translations to a single template and Owlat picks the right version for each recipient.",{"path":205,"title":206,"description":207},"\u002Fguide\u002Fcontacts","Contacts","How to add, view, organize, and manage contacts in Owlat, including sources, the contact detail tabs, and subscription compliance.",{"path":209,"title":210,"description":211},"\u002Fapi","API Overview","Owlat exposes authenticated API endpoints under your Convex site URL.",{"path":213,"title":214,"description":215},"\u002Fapi\u002Fwebhooks","Webhooks","Owlat supports both outbound customer webhooks and inbound provider webhooks.",{"path":217,"title":218,"description":219},"\u002Fapi\u002Fpublic-endpoints","Public Endpoints","These routes are public-facing and usually accessed from email links or embedded forms.",{"path":221,"title":222,"description":223},"\u002Fapi\u002Fwebhook-payloads","Webhook Payloads","The authoritative wire contract for outbound webhooks: envelope, signature headers, per-event data shapes, and payload versioning.",{"path":225,"title":226,"description":227},"\u002Fapi\u002Finbound-channels","Inbound Channel Webhooks","Provider webhook reference for inbound SMS, WhatsApp, and generic-channel messages, plus the MTA mailbox and credential callbacks.",{"path":229,"title":230,"description":231},"\u002Fapi\u002Fauthentication","Authentication","Secure API access with organization-scoped API keys.",{"path":233,"title":234,"description":235},"\u002Fapi\u002Fsdk","TypeScript SDK","Typed client for the Owlat API, usable from Node.js, Bun, Deno, or any server-side JavaScript runtime.",{"path":237,"title":238,"description":239},"\u002Fapi\u002Fsdk-java","Java SDK","The official `owlat-sdk` package provides a typed client for interacting with the Owlat API from any JVM application. Requires Java 11+.",{"path":241,"title":242,"description":243},"\u002Fapi\u002Fcontacts","Contacts API","Manage contacts for your organization.",{"path":245,"title":246,"description":247},"\u002Fapi\u002Ftopics","Topics API","Manage topic membership through authenticated endpoints.",{"path":249,"title":250,"description":251},"\u002Fapi\u002Fevents","Events API","Send contact events to drive segmentation and automation triggers.",{"path":253,"title":254,"description":255},"\u002Fapi\u002Ftransactional","Transactional API","Send published transactional templates to a recipient.",{"path":257,"title":258,"description":259},"\u002Fapi\u002Fforms","Forms API","Capture subscribers through public form endpoints.",{"path":261,"title":262,"description":263},"\u002Fdeveloper","Developer Guide","Technical architecture, feature-flag model, and provider abstractions used by Owlat.",{"path":265,"title":266,"description":267},"\u002Fdeveloper\u002Fmta-system","MTA System","Owlat's custom Mail Transfer Agent for direct SMTP delivery with intelligent rate limiting, bounce processing, and IP warming.",{"path":269,"title":270,"description":271},"\u002Fdeveloper\u002Ffeature-flags","Feature flags — developer reference","How the Owlat feature flag system works: single source of truth, dependency resolution, docker profile mapping, and how to add a new flag.",{"path":273,"title":274,"description":275},"\u002Fdeveloper\u002Fhow-email-works","How Email Works","A technical deep-dive into how email actually works — from SMTP and DNS to authentication, deliverability, and the differences between marketing and private email.",{"path":277,"title":278,"description":279},"\u002Fdeveloper\u002Femail-security","Email Security","Content scanning, attachment validation, URL reputation checking, and malware detection for outbound emails.",{"path":281,"title":282,"description":283},"\u002Fdeveloper\u002Fpostbox-architecture","Postbox Architecture","How the Postbox personal-mail feature is wired — schema, IMAP server, app-password auth, outbound relay, inbound delivery, and external mailboxes.",{"path":285,"title":286,"description":287},"\u002Fdeveloper\u002Fproviders","Providers","Pluggable provider abstractions for LLM, email sending, notifications, vector stores, and analytics, selected per-deployment so self-hosters can swap implementations without code changes.",{"path":289,"title":290,"description":291},"\u002Fdeveloper\u002Fcampaign-internals","Campaign Internals","How the campaign backend works: two status machines, send pre-flight, the send orchestrator, emailSends records, and the priority workpools.",{"path":293,"title":294,"description":295},"\u002Fdeveloper\u002Faudience-internals","Audience Internals","Backend reference for contact resolution, the double opt-in lifecycle, topic subscription, the conditions registry, and segment evaluation.",{"path":297,"title":298,"description":299},"\u002Fdeveloper\u002Fautomation-internals","Automation Internals","How the automation run engine works: the step walker, the lifecycle state machine, trigger fanout, the three step types, and the resilience cron.",{"path":301,"title":302,"description":303},"\u002Fdeveloper\u002Fdeliverability-infrastructure","Deliverability Infrastructure","The Convex-side deliverability backend: provider routing, health-aware failover, sending reputation with auto-enforcement, IP warming cache, the blocklist, and the content-scan gate.",{"path":305,"title":306,"description":307},"\u002Fdeveloper\u002Farchitecture","Architecture Overview","Owlat follows a modern serverless architecture with real-time capabilities.",{"path":309,"title":310,"description":311},"\u002Fdeveloper\u002Fplatform-operations","Platform Operations","Operator reference for abuse status and the sending gate, the platform-admin roster, content review, org deletion, in-app self-update, dev endpoints, crons, and migrations.",{"path":313,"title":314,"description":315},"\u002Fdeveloper\u002Fsealed-mail-at-rest","Sealed Mail: Bodies at Rest","How Owlat seals every stored message body with an instance data key, and the deliberate search-index exceptions that stay plaintext.",{"path":317,"title":318,"description":319},"\u002Fdeveloper\u002Ftransport-security","Transport Security","Operator guide to Sealed Mail's transport hardening: requiring TLS for inbound delivery, publishing MTA-STS, outbound TLS and DANE posture, TLS-RPT, and secrets at rest.",{"path":321,"title":322,"description":323},"\u002Fdeveloper\u002Fscopes","Scopes","What each app and package in the Owlat monorepo is responsible for.",{"path":325,"title":326,"description":327},"\u002Fdeveloper\u002Fself-hosting","Self-Hosting","Deploy Owlat on your own infrastructure with Docker Compose. Complete guide from first boot to production.",{"path":329,"title":330,"description":331},"\u002Fdeveloper\u002Fself-hosting-config","Self-Hosting Configuration","Complete reference for Docker environment variables, Convex backend variables, service topology, and volume persistence.",{"path":333,"title":334,"description":335},"\u002Fdeveloper\u002Fself-hosting-dns-email","DNS & Email Setup","Configure DNS records, DKIM signing, SPF, DMARC, and bounce handling for reliable email delivery.",{"path":337,"title":338,"description":339},"\u002Fdeveloper\u002Fself-hosting-production","Production Deployment","Secure your self-hosted Owlat instance with TLS, firewall rules, backups, and monitoring.",{"path":341,"title":342,"description":343},"\u002Fdeveloper\u002Fself-hosting-maintenance","Maintenance & Updates","Keep your self-hosted Owlat instance up to date, manage backups, scale performance, and troubleshoot common issues.",{"path":345,"title":346,"description":347},"\u002Fdeveloper\u002Fself-hosting-desktop","Desktop Installer","Install Owlat on a bare Linux VPS straight from the desktop app over SSH — no terminal — with a live, animated provisioning timeline.",{"path":349,"title":350,"description":351},"\u002Fdeveloper\u002Fsetup-cli","Setup CLI & Installer","Operator reference for the Owlat self-host tooling: the install.sh one-liner, the owlat-setup CLI, the convex-deploy flow, and admin bootstrap.",{"path":353,"title":354,"description":355},"\u002Fdeveloper\u002Fconvex","Convex Backend","Owlat uses Convex as its serverless backend, providing real-time subscriptions, ACID transactions, and TypeScript-first development.",{"path":357,"title":230,"description":358},"\u002Fdeveloper\u002Fauthentication","Owlat uses BetterAuth with the Convex adapter for authentication and organization (team) management.",{"path":360,"title":361,"description":362},"\u002Fdeveloper\u002Femail-system","Email System","Owlat's email system consists of a visual editor, template management, and multi-provider sending infrastructure.",{"path":364,"title":365,"description":366},"\u002Fdeveloper\u002Femail-renderer","Email Renderer","The @owlat\u002Femail-renderer package converts editor JSON blocks into production-ready HTML emails with cross-client compatibility, CSS inlining, dark mode, and Outlook VML fallbacks.",{"path":368,"title":369,"description":370},"\u002Fdeveloper\u002Fenvironment-variables","Environment Variables","Reference for every environment variable Owlat reads across the Convex backend, web app, MTA, IMAP server, and mail-sync worker.",{"path":372,"title":373,"description":374},"\u002Fdeveloper\u002Fcomponents","Component Library","Reference for the reusable, auto-imported Vue UI components shipped in the packages\u002Fui layer.",{"path":376,"title":377,"description":378},"\u002Fdeveloper\u002Fdecisions","Architectural Decision Records","The architectural decision records for the Owlat project, each capturing the context, the decision, and the trade-offs involved.",{"path":380,"title":381,"description":382},"\u002Fdeveloper\u002Fdecisions\u002F009-model-routing","ADR-009: Task-Based Model Routing","Why Owlat supports per-task LLM model selection instead of using a single model for all pipeline steps.",{"path":384,"title":385,"description":386},"\u002Fdeveloper\u002Fdecisions\u002F010-listing-engine","ADR-010: Listing Engine","Why Owlat replaced four incompatible list-query contracts with one generic listing engine driven by per-entity descriptors.",{"path":388,"title":389,"description":390},"\u002Fdeveloper\u002Fdecisions\u002F001-custom-email-renderer","ADR-001: Custom Email Renderer Over MJML","Why Owlat built a custom table-based HTML email renderer instead of using MJML, gaining full control over VML, dark mode, and per-client rendering.",{"path":392,"title":393,"description":394},"\u002Fdeveloper\u002Fdecisions\u002F002-convex-backend","ADR-002: Convex as Backend","Why Owlat chose Convex over PostgreSQL and Firebase for real-time reactivity, co-located TypeScript logic, and zero-config scaling.",{"path":396,"title":397,"description":398},"\u002Fdeveloper\u002Fdecisions\u002F003-notion-like-builder","ADR-003: Notion-like Email Builder","Why Owlat replaced the traditional 3-panel email editor with a Notion-like single-column canvas for inline WYSIWYG editing.",{"path":400,"title":401,"description":402},"\u002Fdeveloper\u002Fdecisions\u002F004-monorepo-bun-workspaces","ADR-004: Monorepo with Bun Workspaces","Why Owlat uses a monorepo with Bun workspaces and Turborepo for fast installs, atomic cross-package changes, and cached CI.",{"path":404,"title":405,"description":406},"\u002Fdeveloper\u002Fdecisions\u002F005-custom-mta","ADR-005: Custom MTA","Why Owlat built a custom Mail Transfer Agent instead of relying solely on third-party email providers.",{"path":408,"title":409,"description":410},"\u002Fdeveloper\u002Fdecisions\u002F006-self-hosted-convex","ADR-006: Self-Hosted Convex","Why Owlat uses the open-source Convex backend for self-hosting instead of migrating to a different database.",{"path":412,"title":413,"description":414},"\u002Fdeveloper\u002Fdecisions\u002F007-pluggable-llm","ADR-007: Pluggable LLM Provider","Why Owlat uses the Vercel AI SDK with a provider abstraction layer instead of hardcoding a single LLM vendor.",{"path":416,"title":417,"description":418},"\u002Fdeveloper\u002Fdecisions\u002F008-process-architecture","ADR-008: Agent Process Architecture","Why Owlat processes inbound messages with a self-scheduling step walker plus a lifecycle coordinator instead of one sequential function.",{"path":420,"title":421,"description":422},"\u002Fexamples","Examples","Copy-pasteable integration patterns for common Owlat use cases.",{"path":424,"title":425,"description":426},"\u002Fexamples\u002Fwelcome-email","Welcome Email","Send a personalized welcome email when a new user signs up.",{"path":428,"title":429,"description":430},"\u002Fexamples\u002Fbilling-email","Billing Email","Send a billing receipt with an invoice PDF attached after a successful payment.",{"path":432,"title":433,"description":434},"\u002Fexamples\u002Fevent-automation","Event Automation","Trigger automations with custom events for trial lifecycle, feature adoption, and more.",{"path":436,"title":437,"description":438},"\u002Fexamples\u002Fcontact-sync","Contact Sync","Sync contacts from your database to Owlat using upsert patterns and bulk operations.",{"path":440,"title":441,"description":442},"\u002Fexamples\u002Fwebhook-handler","Webhook Handler","Handle Owlat delivery webhooks with signature verification and event routing.",{"path":444,"title":445,"description":446},"\u002Fexamples\u002Fmultilingual-email","Multilingual Email","Send emails in the recipient's preferred language using template translations.",{"path":448,"title":449,"description":450},"\u002Fvision","Vision","Where Owlat is heading — from email platform to unified communication intelligence powered by AI agents.",{"path":452,"title":453,"description":454},"\u002Fvision\u002Fself-hosting","Self-Hosting Architecture","How Owlat runs as a fully self-hosted stack using Docker Compose — open-source Convex backend, custom MTA, and a pluggable LLM provider.",{"path":456,"title":457,"description":458},"\u002Fvision\u002Fagent-pipeline","Agent Pipeline","Technical architecture for the inbound email agent pipeline — step modules, the walker, security scanning, threading, and human review.",{"path":460,"title":106,"description":461},"\u002Fvision\u002Fknowledge-graph","Technical architecture for Owlat's typed knowledge storage — how organizational knowledge is stored, searched, decayed, and maintained.",{"path":463,"title":464,"description":465},"\u002Fvision\u002Fmulti-channel","Multi-Channel & CRM","Technical architecture for channel adapters, unified messaging, contact identity unification, and the CRM hub.",{"path":467,"title":468,"description":469},"\u002Fvision\u002Ffile-system","Semantic File System","Technical architecture for Owlat's semantic file storage — version tracking with provenance today, plus the planned embedding-based retrieval and auto-tagging layer.",{"path":471,"title":472,"description":473},"\u002Fvision\u002Fdesktop-app","Desktop App & Advanced Agents","Architecture of the Owlat desktop shell, visualization agent, adaptive dashboard, agent health, graduated autonomy, and coding agents.",{"path":475,"title":476,"description":477},"\u002Fvision\u002Froadmap","Roadmap","What's planned next for Owlat — the documented-but-unbuilt pieces still being wired, and the enhancements on our radar.",{"id":479,"title":318,"body":480,"description":319,"extension":1284,"meta":1285,"navigation":1286,"path":317,"seo":1287,"stem":1288,"__hash__":1289},"content\u002F3.developer\u002F22.transport-security.md",{"type":481,"value":482,"toc":1267},"minimark",[483,501,504,509,524,535,538,545,549,564,633,643,669,687,699,707,720,776,785,792,799,805,872,897,907,953,977,988,1029,1035,1046,1060,1064,1073,1102,1105,1113,1125,1129,1132,1139,1149,1155,1158,1179,1194,1201,1204,1240,1244],[484,485,486,487,491,492,496,497,500],"p",{},"Sealed Mail's ",[488,489,490],"a",{"href":181},"end-to-end encryption"," protects message ",[493,494,495],"strong",{},"contents"," between Owlat workspaces. This page covers the complementary layer: hardening the ",[493,498,499],{},"SMTP transport"," so that mail to and from ordinary (non-Owlat) mail servers is encrypted in flight and can't be silently downgraded, plus the secrets that keep everything sealed at rest.",[484,502,503],{},"Inbound delivery is secure by default: Owlat rejects SMTP transactions that have not upgraded with STARTTLS. The outbound and publication controls remain deliberate operator choices.",[505,506,508],"h2",{"id":507},"requiring-tls-for-inbound-delivery","Requiring TLS for inbound delivery",[484,510,511,514,515,519,520,523],{},[493,512,513],{},"Settings → Sealed Mail → Require TLS for incoming mail"," controls the SMTP acceptance floor. It is on by default. While enabled, the MTA checks the live connection before accepting ",[516,517,518],"code",{},"MAIL FROM","; a plaintext sender receives ",[516,521,522],{},"550 5.7.10 Encryption needed"," and Owlat accepts or stores none of the message bytes.",[484,525,526,527,530,531,534],{},"Configure ",[516,528,529],{},"BOUNCE_TLS_CERT"," and ",[516,532,533],{},"BOUNCE_TLS_KEY"," so the inbound SMTP server can advertise STARTTLS. Without a certificate and key, the default-on floor rejects every inbound delivery because senders have no encrypted path; only disable the floor as a temporary recovery measure.",[484,536,537],{},"Owners and admins can disable the floor for a legacy sender that cannot negotiate STARTTLS. Disabling it permits plaintext delivery to every address on the instance, so it should be a temporary compatibility measure. The choice is synchronized to the MTA's Redis-backed SMTP gate; missing or unreadable policy state fails closed and continues to require TLS.",[484,539,540,541,544],{},"This acceptance floor requires encryption, not certificate authentication. Publishing MTA-STS in ",[516,542,543],{},"enforce"," mode complements it by telling compatible senders in advance to require a certificate-verified TLS connection to the expected MX.",[505,546,548],{"id":547},"publishing-mta-sts-inbound","Publishing MTA-STS (inbound)",[484,550,551,552,555,556,559,560,563],{},"MTA-STS (RFC 8461) lets senders that deliver mail ",[493,553,554],{},"to"," your deployment require encrypted, certificate-verified delivery — protecting against STARTTLS-stripping attacks. You publish it from ",[493,557,558],{},"Delivery → provider config"," (\"Inbound TLS policy (MTA-STS)\"), which is owner\u002Fadmin-gated. The posture is stored on the workspace settings as ",[516,561,562],{},"mtaStsMode"," and has three steps, in ascending strictness:",[565,566,567,583],"table",{},[568,569,570],"thead",{},[571,572,573,577,580],"tr",{},[574,575,576],"th",{},"Mode",[574,578,579],{},"UI label",[574,581,582],{},"Effect",[584,585,586,600,617],"tbody",{},[571,587,588,594,597],{},[589,590,591],"td",{},[516,592,593],{},"none",[589,595,596],{},"Off",[589,598,599],{},"No policy is published. Senders deliver mail to you exactly as they do today. The default.",[571,601,602,607,610],{},[589,603,604],{},[516,605,606],{},"testing",[589,608,609],{},"Testing",[589,611,612,613,616],{},"A policy is published, but senders only ",[493,614,615],{},"report"," TLS problems — they never fail delivery. The safe first step while you watch for issues.",[571,618,619,623,626],{},[589,620,621],{},[516,622,543],{},[589,624,625],{},"Enforce",[589,627,628,629,632],{},"Senders ",[493,630,631],{},"must"," deliver over verified TLS to a listed MX, or the message is rejected. Turn this on only once testing looks clean.",[484,634,635,636,639,640,642],{},"Publishing a policy has two DNS\u002FHTTPS halves, both surfaced on the ",[493,637,638],{},"Domains"," page once you leave ",[516,641,593],{},":",[644,645,646,658],"ol",{},[647,648,649,650,653,654,657],"li",{},"A TXT record at ",[516,651,652],{},"_mta-sts.\u003Cdomain>"," announcing the policy and a short ",[516,655,656],{},"id"," that changes whenever the policy changes (so senders re-fetch).",[647,659,660,661,664,665,668],{},"The policy file itself, served over HTTPS at ",[516,662,663],{},"https:\u002F\u002Fmta-sts.\u003Cdomain>\u002F.well-known\u002Fmta-sts.txt",". Owlat serves this automatically for a configured mail host; you just publish the ",[516,666,667],{},"mta-sts"," DNS record that points to it.",[484,670,671,672,675,676,678,679,683,684,686],{},"The published policy uses a one-week ",[516,673,674],{},"max_age"," (the widely-used default). Start at ",[516,677,606],{},", watch the ",[488,680,682],{"href":681},"#reading-the-tls-rpt-dashboard","TLS-RPT dashboard"," until reports look clean, then advance to ",[516,685,543],{},".",[688,689,691],"callout",{"type":690},"warning",[484,692,693,695,696,698],{},[516,694,543],{}," with no inbound mail host configured can't actually take effect — there's no MX to serve a verified-TLS policy for. Set up receiving first, or stay on ",[516,697,606],{},". The UI warns you honestly in this case.",[505,700,702,703,706],{"id":701},"outbound-tls-posture-outbound_tls_mode","Outbound TLS posture (",[516,704,705],{},"OUTBOUND_TLS_MODE",")",[484,708,709,711,712,715,716,719],{},[516,710,705],{}," governs the built-in MTA's ",[493,713,714],{},"direct-to-MX"," delivery — how strict Owlat is about TLS when it sends mail out. It's one of three values (default ",[516,717,718],{},"opportunistic","):",[565,721,722,733],{},[568,723,724],{},[571,725,726,730],{},[574,727,728],{},[516,729,705],{},[574,731,732],{},"Behaviour",[584,734,735,749,762],{},[571,736,737,746],{},[589,738,739,741,742],{},[516,740,718],{}," ",[743,744,745],"em",{},"(default)",[589,747,748],{},"Encrypt when the receiver offers STARTTLS, but never fail delivery on a missing or unverifiable certificate (RFC 7435). Byte-identical to the historic behaviour.",[571,750,751,756],{},[589,752,753],{},[516,754,755],{},"require",[589,757,758,759,761],{},"The handshake ",[493,760,631],{}," upgrade to TLS; the certificate is not verified (encrypt-always, tolerate self-signed MX certs).",[571,763,764,769],{},[589,765,766],{},[516,767,768],{},"require-verified",[589,770,771,772,775],{},"The handshake must upgrade to TLS ",[493,773,774],{},"and"," the certificate must verify against the WebPKI trust store. Can bounce mail to receivers with broken or self-signed TLS.",[484,777,778,779,782,783,686],{},"The MTA reads this from its own config; the value is also surfaced read-only to the delivery transport editor so re-applying an edit preserves your chosen floor. A typo (for example ",[516,780,781],{},"require_verified"," with an underscore) fails the MTA boot fast rather than silently degrading to ",[516,784,718],{},[484,786,787,788,791],{},"Independently of this global floor, Owlat already ",[493,789,790],{},"enforces"," other domains' published MTA-STS policies when it sends to them, so a receiver that demands verified TLS gets it regardless of your outbound mode.",[505,793,795,796,706],{"id":794},"dane-posture-dane_mode","DANE posture (",[516,797,798],{},"DANE_MODE",[484,800,801,802,804],{},"DANE (RFC 7672) authenticates a receiver's TLS certificate against a DNSSEC-signed TLSA record, closing the trust gap that plain WebPKI leaves. It's governed by ",[516,803,798],{}," on the MTA, one of three values:",[565,806,807,817],{},[568,808,809],{},[571,810,811,815],{},[574,812,813],{},[516,814,798],{},[574,816,732],{},[584,818,819,829,857],{},[571,820,821,826],{},[589,822,823],{},[516,824,825],{},"off",[589,827,828],{},"No TLSA lookups, no DANE effect — byte-identical to the historic (DANE-disabled) path.",[571,830,831,835],{},[589,832,833],{},[516,834,615],{},[589,836,837,838,840,841,844,845,848,849,852,853,856],{},"Look up each recipient MX's TLSA RRset and check the certificate against it, then ",[493,839,615],{}," the result in TLS-RPT (a ",[516,842,843],{},"success",", or a ",[516,846,847],{},"validation-failure"," under the ",[516,850,851],{},"tlsa"," policy) — but ",[493,854,855],{},"never"," require TLS or bounce on a DANE outcome. Delivery proceeds on the normal opportunistic\u002FMTA-STS decision. Observability only, zero delivery impact.",[571,858,859,863],{},[589,860,861],{},[516,862,543],{},[589,864,865,866,869,870,686],{},"A usable TLSA RRset ",[493,867,868],{},"mandates"," verified TLS authenticated against it (this supersedes MTA-STS); a non-matching certificate defers the message (never falls back to cleartext) and records a ",[516,871,847],{},[484,873,874,875,877,878,881,882,884,885,887,888,890,891,893,894,896],{},"The default is ",[516,876,825],{},", matching locked decision ",[493,879,880],{},"D6",". Opt into ",[516,883,615],{}," to gather DANE visibility in the ",[488,886,682],{"href":681}," without changing delivery outcomes. Promote a domain to ",[516,889,543],{}," only once report-only shows its TLSA records validating cleanly — exactly the ",[516,892,606],{}," → ",[516,895,543],{}," progression you use for MTA-STS.",[484,898,899,900,903,904,642],{},"DANE needs a ",[493,901,902],{},"validating DoH (DNS-over-HTTPS, RFC 8484) resolver",", configured with ",[516,905,906],{},"DANE_RESOLVER_URL",[565,908,909,919],{},[568,910,911],{},[571,912,913,916],{},[574,914,915],{},"Env var",[574,917,918],{},"Purpose",[584,920,921,938],{},[571,922,923,927],{},[589,924,925],{},[516,926,798],{},[589,928,929,931,932,934,935,937],{},[516,930,825],{}," (default), ",[516,933,615],{},", or ",[516,936,543],{},". An unrecognised value fails the MTA boot fast rather than silently degrading to a different posture.",[571,939,940,944],{},[589,941,942],{},[516,943,906],{},[589,945,946,947,949,950,952],{},"A validating DoH resolver endpoint. Needed for ",[516,948,615],{},"\u002F",[516,951,543],{}," to actually run.",[688,954,957],{"type":955,"title":956},"info","No resolver → DANE is inert",[484,958,959,530,961,963,964,966,967,970,971,530,974,976],{},[516,960,615],{},[516,962,543],{}," both require ",[516,965,906],{},". ",[493,968,969],{},"When it is unset, DANE is inert in every mode"," (no TLSA lookups). Set both ",[516,972,973],{},"DANE_MODE=report",[516,975,906],{}," to turn report-only observability on.",[484,978,979,980,983,984,987],{},"DANE's entire security rests on the resolver's DNSSEC ",[493,981,982],{},"AD (Authenticated Data) bit",", so the channel to the resolver must be one an on-path attacker can't forge over. When a resolver URL ",[493,985,986],{},"is"," set, the MTA validates it at boot (in every mode, so a mistake is caught before you enable DANE, not on enable-day):",[989,990,991,997],"ul",{},[647,992,993,994,996],{},"A malformed ",[516,995,906],{}," → boot fails.",[647,998,999,1000,741,1003,1006,1007,1010,1011,1014,1015,1018,1019,1018,1022,1018,1025,1028],{},"A non-",[516,1001,1002],{},"https:",[493,1004,1005],{},"remote"," resolver → boot fails. ",[516,1008,1009],{},"http:"," is permitted ",[493,1012,1013],{},"only"," for a loopback resolver (",[516,1016,1017],{},"localhost",", ",[516,1020,1021],{},"127.0.0.1",[516,1023,1024],{},"::1",[516,1026,1027],{},"*.localhost","), where there is no on-path network to attack.",[484,1030,1031,1032,1034],{},"When DANE is enabled, the same validating resolver performs destination discovery as well as the TLSA lookup. The MTA retains the DNSSEC state of the MX and address answers, refuses to apply DANE through an unauthenticated address chain, and treats resolver failures as temporary delivery failures in ",[516,1033,543],{}," mode instead of silently retrying without DANE.",[484,1036,1037,1038,1041,1042,1045],{},"Both interoperable SMTP usages are supported. ",[493,1039,1040],{},"DANE-EE(3)"," authenticates the leaf key\u002Fcertificate directly, so WebPKI trust, certificate names, and certificate dates are intentionally ignored. ",[493,1043,1044],{},"DANE-TA(2)"," validates the presented chain to the TLSA-associated CA and still enforces certificate validity, CA\u002Fsignature chaining, and the RFC 7672 MX reference-name rules. During certificate rotation, any valid association in a mixed EE\u002FTA RRset may authenticate the peer. Reusable SMTP connections are partitioned by a fingerprint of the complete TLSA RRset and its reference names, so a connection authenticated under an older policy is never reused under a changed policy.",[688,1047,1049],{"type":955,"title":1048},"Run a local validating resolver",[484,1050,1051,1052,1055,1056,1059],{},"The recommended setup (per D6) is a ",[493,1053,1054],{},"local validating resolver"," — for example ",[516,1057,1058],{},"https:\u002F\u002F127.0.0.1:8443\u002Fdns-query"," — rather than a public DoH endpoint. A local resolver you control does its own DNSSEC validation, so the AD bit it returns is trustworthy end to end. Trusting a remote resolver's AD bit means trusting both that resolver and the network path to it.",[505,1061,1063],{"id":1062},"reading-the-tls-rpt-dashboard","Reading the TLS-RPT dashboard",[484,1065,1066,1067,1069,1070,1072],{},"TLS Reporting (TLS-RPT, RFC 8460) is how you close the loop: other mail servers send you daily aggregate reports about how TLS negotiation went when they delivered ",[493,1068,554],{}," you. Owlat ingests them and rolls them up on the ",[493,1071,558],{}," page (\"Inbound TLS reports — How partners reach us over TLS\").",[484,1074,1075,1076,1079,1080,1083,1084,1087,1088,1091,1092,1095,1096,1098,1099,1101],{},"To receive reports you must publish a ",[516,1077,1078],{},"_smtp._tls"," TXT record naming a reporting address you actually monitor. Set ",[516,1081,1082],{},"MTA_TLSRPT_RUA"," (for example ",[516,1085,1086],{},"mailto:tls-reports@example.com"," or an ",[516,1089,1090],{},"https:\u002F\u002F"," collector) and Owlat emits the record — ",[516,1093,1094],{},"v=TLSRPTv1; rua=\u003Caddress>",". If ",[516,1097,1082],{}," is unset, no ",[516,1100,1078],{}," record is generated (Owlat doesn't provision a per-domain reports mailbox, so the reports would otherwise go unread).",[484,1103,1104],{},"The dashboard shows, over a rolling 30-day window:",[989,1106,1107,1110],{},[647,1108,1109],{},"An overall TLS success rate, plus a breakdown by reporting organization.",[647,1111,1112],{},"A plain-language tally of any failures — for example \"STARTTLS stripped upstream\" or \"certificate didn't match the server name\".",[484,1114,1115,1116,1119,1120,1122,1123,686],{},"Ingestion is idempotent by reporting organization and ",[516,1117,1118],{},"report-id",", so a re-delivered report never double-counts. Watch this dashboard while a domain is on MTA-STS ",[516,1121,606],{}," before you promote it to ",[516,1124,543],{},[505,1126,1128],{"id":1127},"secrets-at-rest","Secrets at rest",[484,1130,1131],{},"Two secrets protect Sealed Mail's data at rest. Both are set once and must be kept safe — losing them has real consequences.",[1133,1134,1136],"h3",{"id":1135},"mta_secret",[516,1137,1138],{},"MTA_SECRET",[484,1140,1141,1142,530,1145,1148],{},"Seals the MTA's own credentials at rest: ",[493,1143,1144],{},"DKIM signing keys",[493,1146,1147],{},"relay credentials",". The MTA fails to boot if it's absent or too weak, rather than sealing under a guessable key. Scope it to the MTA process.",[1133,1150,1152],{"id":1151},"instance_secret",[516,1153,1154],{},"INSTANCE_SECRET",[484,1156,1157],{},"The root secret for everything Owlat seals at rest on the Convex side:",[989,1159,1160,1169],{},[647,1161,1162,1163,1166,1167,686],{},"The ",[493,1164,1165],{},"Sealed Mail key vault"," — every sealing private key is encrypted under a domain-separated box derived from ",[516,1168,1154],{},[647,1170,1171,1174,1175,1178],{},[493,1172,1173],{},"Message bodies at rest"," — stored bodies and blobs are sealed under separate domain-separated keys derived from the same secret (see ",[488,1176,1177],{"href":313},"Sealed Mail at Rest",").",[688,1180,1182],{"type":690,"title":1181},"Losing INSTANCE_SECRET",[484,1183,1184,1186,1187,1189,1190,1193],{},[516,1185,1154],{}," opens the key vault. If you lose it ",[493,1188,774],{}," every ",[488,1191,1192],{"href":189},"recovery kit"," is lost, sealed mail already received can no longer be opened — there is no admin escrow (D7). Back it up as carefully as any root credential.",[1195,1196,1198,1199],"h4",{"id":1197},"rotating-instance_secret","Rotating ",[516,1200,1154],{},[484,1202,1203],{},"To rotate the instance secret without losing access:",[644,1205,1206,1224,1235],{},[647,1207,1208,1209,1212,1213,1215,1216,1219,1220,1223],{},"Set the ",[493,1210,1211],{},"new"," value as ",[516,1214,1154],{}," and keep the ",[493,1217,1218],{},"previous"," value in ",[516,1221,1222],{},"INSTANCE_SECRET_PREVIOUS",". While both are set, the vault opens each sealed key under the current secret and falls back to the previous one, so reads keep working mid-migration.",[647,1225,1226,1227,1230,1231,1234],{},"Run ",[493,1228,1229],{},"Re-seal sealed mail"," from ",[493,1232,1233],{},"Settings → Sealed Mail"," (\"After changing the instance secret\"). This re-encrypts every stored key under the new secret. Sealed mail keeps opening throughout.",[647,1236,1237,1238,686],{},"Once re-sealing finishes, remove ",[516,1239,1222],{},[505,1241,1243],{"id":1242},"related","Related",[989,1245,1246,1252,1257,1262],{},[647,1247,1248,1251],{},[488,1249,1250],{"href":181},"Sealed Mail"," — the end-to-end encryption these transports carry.",[647,1253,1254,1256],{},[488,1255,190],{"href":189}," — the user-held keys that survive a rebuild.",[647,1258,1259,1261],{},[488,1260,1177],{"href":313}," — how stored bodies are sealed.",[647,1263,1264,1266],{},[488,1265,266],{"href":265}," — the built-in mail transfer agent.",{"title":1268,"searchDepth":1269,"depth":1269,"links":1270},"",2,[1271,1272,1273,1275,1277,1278,1283],{"id":507,"depth":1269,"text":508},{"id":547,"depth":1269,"text":548},{"id":701,"depth":1269,"text":1274},"Outbound TLS posture (OUTBOUND_TLS_MODE)",{"id":794,"depth":1269,"text":1276},"DANE posture (DANE_MODE)",{"id":1062,"depth":1269,"text":1063},{"id":1127,"depth":1269,"text":1128,"children":1279},[1280,1282],{"id":1135,"depth":1281,"text":1138},3,{"id":1151,"depth":1281,"text":1154},{"id":1242,"depth":1269,"text":1243},"md",{},true,{"title":318,"description":319},"3.developer\u002F22.transport-security","iIWYaqYKXIlWcOsP79kMb8XnCcugYFkwUfdAYszfdpE",[1291,1293],{"title":314,"path":313,"stem":1292,"children":-1},"3.developer\u002F21.sealed-mail-at-rest",{"title":322,"path":321,"stem":1294,"children":-1},"3.developer\u002F3.scopes",1784224019126]