Trust
Security, specifically
The software runs on your machine, so most of the trust question is about what it does there. Here is what it does.
Where your data is
On your server. Mail is Maildir on your disk; tenants, domains, mailboxes and policy are in a Postgres container beside it. There is no MailDock service in the path of a message, no telemetry of mail content, and nothing to opt out of.
The one thing that leaves is a licence heartbeat to licence.maildock.app: the licence’s id and, from 0.4.0, its key (the key is what proves the licence is yours; 0.3.0 sends the id alone), a fingerprint of the server it runs on, how many mailboxes and domains it holds (to check the licence's allowance), and the product version. Not your domain names, not your users, not your mail.
Authentication
- Mailbox users get TOTP on webmail sign-in and an app password for each mail client, which turning TOTP on makes mandatory, with ten single-use recovery codes stored only as a keyed hash. App passwords are matched inside the Dovecot password query rather than returned as extra rows — a detail that matters because a second row is an outage, not a fallback.
- Administrators get three roles and their own TOTP. An unreadable TOTP secret fails closed and needs a reset — by another administrator, or by a sole owner on the host — and it never degrades to a password-only login.
- Programs get scoped, revocable API tokens.
- Browser sessions end when they are ended: signing out, or signing a session out from your account page, refuses its access token at the next request, and a password change or an emailed admin-console password reset ends every other session of the account.
Brute force, and both doors
Failed authentication is counted and banned, and the API and the mail daemons read thesame ban list from the same table. A bot that gives up on the web form does not get a fresh budget by moving to IMAP.
When a mailbox is compromised anyway
A mailbox that starts sending spam is contained automatically — and containment blockssending only. Receiving keeps working. That is a deliberate choice: the account’s owner is the victim, the mail arriving is still your customer’s mail, and cutting off receipt turns an incident into data loss. Our own outbound throttle is excluded from the evidence, so a rate limit never reads as a compromise.
Secrets at rest
Provider keys and migration credentials are encrypted with a server key, and from 0.11.0 so are DKIM private keys and the outbound relay password. Migration credentials are wiped when the migration ends — cutover, cancel or delete — rather than when a sync finishes, because the final delta runs after the MX change.
Transport
TLS is Caddy’s ACME by default, or your own certificate if you have one; either way it reaches the daemons within thirty seconds of changing. MTA-STS and TLS-RPT are published for your domains and the reports are parsed rather than filed.
In the browser, and in the containers
From 0.10.0, both web applications send a content security policy under which scripts and requests come only from the application’s own origin — remote images in an email are the one exception, and the mail client holds them back until you allow them — and the usual headers beside it (no framing, no sniffing, no referrer). The routes that touch the session cookie refuse a request from another origin. The web container runs as an unprivileged user on a read-only filesystem, and the API, worker and certificate containers drop every capability; from 0.13.0 the API and the worker also run as an unprivileged user, and the worker reads the mail logs through a group rather than a capability. Every image we build installs that day’s security updates and is scanned before a release pushes it; from 0.12.1, a fixable high or critical vulnerability stops the release. From 0.12.1, the Postfix, Dovecot and Rspamd containers also drop every capability except the ones measured for them, and no container can gain privileges. CI fails on a high or critical advisory in any npm package the product ships. Not yet: a finding in an upstream image is reported at release, and does not stop it.
From 0.13.0 the edge proxy runs our own scanned and signed web image, the upstream Postgres and Redis images are pinned by digest and scanned at every release, and the console sends Strict-Transport-Securityfor one day on its own names, not longer, because a longer one would lock a browser out of a console whose certificate later lapses.
Releases
From 0.3.0, released in September 2026, every release ships a manifest of image digests signed with an ECDSA P-256 key, and bothmailctl install and mailctl upgrade verify it before pulling anything — with node:crypto, so there is no signing toolchain to install on your host. A release with no manifest is refused, not warned about. Install checks the signaturebefore it writes your .env, because that write generates the server’s secrets. Releases before 0.3.0, including 0.2.1, predate signing and carry no manifest.
What we do not claim
- No certification. There is no SOC 2, no ISO 27001 and no penetration-test report, because none has been done. When one is, it will be linked here with a date.
- No third-party audit of the code. The source is private and has not been reviewed by anyone outside the project.
- No uptime guarantee. The server is yours; its uptime is your hosting provider’s and yours. The only thing we run is the licence server, and mail keeps flowing when it is down.
What the AI features send
The other half of the trust question, and the one with the most surprising answer: nothing, unless you configure a provider.