Encryption Gateway and Post-Quantum Email Encryption
When we released Stalwart v1.0 last week, it carried only part of the work we had been doing. Several large features were being built in parallel, and for a while the plan was to ship them all together. In the end we chose a different path: v1.0 would be about performance and a stable database schema, and nothing else would be allowed to distract from that. The other features would follow over the next few weeks, one release at a time, each given the attention it deserves.
The first of them is encryption. Stalwart v1.0.2 introduces an encryption gateway that encrypts outgoing mail with each recipient’s own public key, a completely new OpenPGP and S/MIME engine with modern algorithms, including post-quantum encryption, and a set of tools to find, verify and keep track of the keys of the people your users write to. And, as with everything in Stalwart’s core, all of it is open source under the AGPL.
Locks and keys
Section titled “Locks and keys”Email is well protected while it travels: TLS encrypts each connection between servers, so nobody on the network can read a message in transit. The protection ends when the message arrives. Every server along the way stores the message in a form that anyone with access to it can read, from the administrators to an attacker who copies a backup.
Message encryption closes that gap by protecting the message itself rather than the connection. It relies on public-key cryptography, which is easiest to picture as a padlock and its key. Your public key is like an open padlock: you can hand out copies to anyone, and anyone can use one to lock a box. Your private key is the only key that opens those padlocks, and it never leaves your hands. A message locked with your public key can be read by you and nobody else, which is why publishing the public key is safe.
Two standards apply this idea to email. OpenPGP lets people create their own key pairs with tools such as GnuPG or Thunderbird and publish the public half wherever they like. S/MIME uses certificates issued by a certificate authority, in the same X.509 format as the certificates that secure websites but issued for email addresses, and it is built into Outlook, Apple Mail and most corporate environments. Stalwart supports both.
One principle runs through everything below: Stalwart only ever holds public keys. It encrypts, but it never decrypts and never stores a private key. A message it has encrypted cannot be read by Stalwart itself, by its administrators, or by anyone who later gets hold of its disks.
Encryption at rest, rebuilt
Section titled “Encryption at rest, rebuilt”Encryption at rest has been part of Stalwart since 2023. Each user who wants it registers a public key, and from then on the server encrypts every message it delivers to that user before writing it to storage. Only the user’s mail client, holding the private key, can open what is stored. For v1.0.2 we rebuilt it on top of the new engine described below, and it gained a good deal along the way.
There is no longer a cipher to choose. The server reads the key itself and picks the strongest format that the key’s owner can actually read, following the preferences that the OpenPGP key announces or the type of the S/MIME certificate. A registered key entry can hold several keys or certificates, so a user who reads mail on devices with different keys, or who is rotating to a new key, can decrypt with any of them (when only some of them support post-quantum encryption, every message uses the format all of them can read). When a key is registered, the server describes it in plain terms (for example OpenPGP v6: ML-KEM-1024+X448), shows its fingerprints, and raises warnings before trouble arrives: a key that expires within two weeks, an RSA key shorter than 3072 bits, a key that names none of the account’s addresses, or one that few mail clients could decrypt.
Stored messages can also carry header protection (RFC 9788), a recent standard that places a copy of the sender, recipients and subject inside the encrypted part, where they cannot be altered without the client noticing; on stored mail the outer copies, subject included, stay readable. Two compatibility switches cover the quirks of real-world clients: one enables authenticated encryption for S/MIME users whose clients support it, and the other picks between the encoding Outlook expects and the one the standard prescribes for elliptic-curve certificates.
Encryption gateway
Section titled “Encryption gateway”Most people never set up OpenPGP or S/MIME, and most of those who do forget to use it. Organisations that must not send readable mail to certain partners have long relied on a dedicated appliance to fix this: an encryption gateway. Stalwart now has one built in.
The encryption gateway works on mail leaving the server, once an administrator turns it on. When a message is addressed to someone whose public key Stalwart knows, the gateway encrypts it with that key on the way out. The sender does nothing different and needs no software at all, and the recipient opens the message in their own client, with their own private key, exactly as if the sender had encrypted it by hand. Unlike TLS, the protection does not end at the next server: the message stays encrypted at the recipient’s provider, in their mailbox and in every backup made along the way.
A policy decides what happens to each recipient. In opportunistic mode, every recipient with a known key receives encrypted mail and the rest receive it as usual. In required mode, a recipient without a usable key receives nothing in plain text: the sender gets a bounce instead. The policy is an expression, so it can require encryption for one partner domain, stay opportunistic everywhere else and leave internal mail alone, all in a few lines.
Each encrypted recipient receives a copy of their own, encrypted for their key alone, A single shared copy would list the key of every recipient it was encrypted for; separate copies reveal nothing about who else received the message, which keeps blind-copy recipients blind. Every copy is signed again with DKIM and DKIM2, so it passes authentication checks at the other end just as the original would. And by default the gateway uses header protection to its full extent: the subject line, which often says as much as the message itself, is replaced with [...] on the outside and travels only inside the encryption.
Finding the right key
Section titled “Finding the right key”A gateway is only as good as the keys it knows, and a wrong key is worse than none, because it hands the message to whoever holds the matching private key. Stalwart therefore treats recipient keys with care. They are external keys, managed by the system administrator and shared by every sender on the server, and they arrive in three ways.
The administrator can enter a key directly, when it came through a trusted channel. The administrator can also ask the server to follow a key that the recipient’s organisation publishes, and Stalwart supports every common way of publishing one: the Web Key Directory, where a domain serves its users’ OpenPGP keys over HTTPS; keys.openpgp.org, which publishes a key only after verifying the owner’s address by email; classic HKP key servers; and DNS itself, through OPENPGPKEY (RFC 7929) and SMIMEA (RFC 8162) records protected by DNSSEC. Followed keys are refreshed on a schedule, so a rotated or revoked key is picked up automatically, or held for approval when the change cannot be verified.
Finally, Stalwart can learn keys from the mail it receives. When a correspondent sends a message signed with S/MIME, or one carrying an Autocrypt header with their OpenPGP key, the server stores the key, but only if the message passed DMARC, was not classified as spam and the key belongs to the sender’s address. From then on, replies from your organisation to that person can be encrypted. An Autocrypt key whose message signature could not be checked, or a self-signed certificate, is stored at the lowest trust level, which the gateway does not use by default.
Every key carries a trust level that reflects where it came from. At the top are keys an administrator entered or vouched for; then keys proven by a certificate authority or DNSSEC; then keys fetched from a directory such as WKD or keys.openpgp.org, and keys learned from mail; and at the bottom, keys nobody can vouch for. The gateway can demand a minimum level per recipient. When a key changes in a way the server cannot verify on its own, the new key waits for an administrator’s approval while the old one stays in use. S/MIME certificates are validated against the root certificates that Mozilla trusts for email, or against your own private certificate authorities, and harvested certificates are checked against revocation lists every day.
What Stalwart never does is look up a key for an address it has no record of. Searching a key server at the moment a message is sent would tell a third party who your users write to, and would delay every message to someone without a key. Keys exist only for the addresses you, or your correspondents’ own signed mail, have told the server about.
Every algorithm that matters
Section titled “Every algorithm that matters”Underneath all of this sits a new cryptographic engine, written from scratch in Rust for Stalwart. It replaces the third-party libraries we used before, removes more than 80 dependencies from the server, and was built for one job: encrypting mail quickly and correctly for whatever key it is handed. Its output is tested against independent implementations, including GnuPG (both gpg and gpgsm), OpenSSL, Mozilla’s NSS, RNP (the engine inside Thunderbird), Sequoia, rPGP, OpenPGP.js, Proton’s GopenPGP, PGPainless and Bouncy Castle, so that the format it picks for each key is one that the key’s owner can read.
On the OpenPGP side, Stalwart implements RFC 9580, the 2024 revision of the standard, alongside the formats every existing client understands. It accepts both version 4 keys, which is what nearly all software creates today, and the new version 6 keys. For the public-key part it supports RSA, the long-standing workhorse, from 2048 to 8192 bits; elliptic-curve Diffie-Hellman on the NIST P-256, P-384 and P-521 curves; and X25519 and X448, the fast modern curves designed by Daniel J. Bernstein and Mike Hamburg respectively, including the legacy Curve25519 format that GnuPG creates. Messages are encrypted with AES, either in the classic format every client reads or, when the recipient’s key says its software supports it, in the newer format of RFC 9580, whose authenticated encryption (AES in OCB or GCM mode) detects any tampering with the message.
On the S/MIME side, Stalwart writes the Cryptographic Message Syntax used by every S/MIME client. It encrypts for RSA certificates, with either the classic padding every client reads or its modern, provably secure successor RSA-OAEP, for elliptic-curve certificates on the NIST P-256, P-384 and P-521 curves, and for X25519 and X448 certificates. The content itself is protected with AES-256-CBC, which every client reads, or with AES-256-GCM, the authenticated encryption that the current S/MIME standard recommends. Stalwart knows which mail clients can read what, from Outlook’s particular expectations for elliptic-curve keys to Apple Mail’s limitations, and defaults to the choice that works with the most clients.
Post-quantum encryption
Section titled “Post-quantum encryption”Every public-key algorithm above relies on mathematical problems that today’s computers cannot solve in any useful amount of time: factoring large numbers for RSA, and discrete logarithms on elliptic curves for the rest. A sufficiently large quantum computer could solve both. No such machine exists yet, and nobody knows when one will. But encrypted email has a long shelf life, and an adversary who records encrypted traffic today can afford to wait. This strategy is known as “harvest now, decrypt later”, and it is the reason post-quantum cryptography matters for messages being sent right now, not only for those that will be sent once quantum computers arrive.
Post-quantum algorithms are built on different mathematics, which resists attacks by both classical and quantum computers. The first standardised for encryption is ML-KEM (Module-Lattice-based Key Encapsulation Mechanism), published by NIST in 2024 as FIPS 203 after a public competition that ran for most of a decade, in which it was known as Kyber. Stalwart supports it in both email standards:
In OpenPGP, Stalwart implements RFC 9980, which pairs ML-KEM with a classical curve: ML-KEM-768 with X25519, and ML-KEM-1024 with X448. The pairing is deliberate. An attacker must break both algorithms to read the message, so the encryption is at least as strong as the classical curve alone, even if a flaw were ever found in the newer lattice mathematics. Messages for post-quantum keys are always encrypted with AES-256.
In S/MIME, Stalwart implements RFC 9936, encrypting for certificates with ML-KEM-512, ML-KEM-768 and ML-KEM-1024 keys using the key encapsulation format of RFC 9629, with AES-256-GCM for the content.
Using it requires no configuration. When a user registers a key with a post-quantum component, encryption at rest uses it; when a recipient publishes one, the gateway does the same. Stalwart is also careful about one subtle trap: a key that contains both a classical and a post-quantum encryption key is encrypted to the post-quantum one only, because encrypting to both would let anyone who breaks the classical half read the message.
A word of honesty: mail clients are still catching up. Thunderbird and GnuPG in its default configuration cannot yet decrypt post-quantum OpenPGP messages, while clients built on Sequoia, rPGP, OpenPGP.js or GopenPGP can. On the S/MIME side, no mainstream mail client decrypts ML-KEM yet, and no public certificate authority issues ML-KEM certificates, so post-quantum keys are for now best suited to users whose software is ready for them. The server side is ready today, and when the clients arrive, nothing on your server will need to change.
Who holds the key
Section titled “Who holds the key”Almost every mail service says it encrypts your mail, and almost every one of them does. The difference lies in a single question: who holds the key that opens the stored messages?
For the large hosted services, the answer is the provider. Microsoft 365 encrypts mailboxes at rest, but by default “Microsoft manages all cryptographic keys”, and even when a customer supplies its own root keys, it authorises the service to keep using them for search, anti-spam and eDiscovery. Google, Apple’s iCloud Mail works the same way by default: storage encryption protects against a stolen disk, but the provider holds the keys. Google does offer client-side encryption that its servers cannot decrypt, but only on selected Enterprise and Education editions, with the keys held by an external key service the organisation chooses rather than by each user. Apple says plainly that iCloud Mail is not end-to-end encrypted, because it has to interoperate with the rest of the email world.
Self-hosted servers have mostly followed a similar pattern, apart from a few add-on tools that encrypt incoming mail with the recipient’s public key. Dovecot’s mail-crypt plugin encrypts stored mail either with a global key kept in the server’s configuration or with per-user keys stored on the server, unprotected or protected by a value derived from the user’s password, and its own documentation describes per-folder keys as “not considered production quality”. In every variant the private keys are kept on the server, which decrypts mail itself to serve it over IMAP, and the format is its own rather than OpenPGP or S/MIME.
Privacy-focused providers such as Proton Mail and Tuta go much further. Their users’ private keys are kept on the provider’s servers, but encrypted with a key derived from the user’s password, and they are unlocked only inside the provider’s app or web client at login. Between two users of the same service, mail is end-to-end encrypted, which is a stronger guarantee than any server-side scheme can offer. The protection of stored mail, however, rests on the password and on the client code the provider delivers, and Tuta’s protocol cannot be read by standard OpenPGP or S/MIME software at all.
Stalwart builds that model into the server itself. The private key does not exist on the server in any form, not even encrypted. Someone holding a complete copy of the server, its database, its backups and the administrator’s password still cannot read a single encrypted message, because the only key that opens them lives in the user’s own mail client. And because the messages are standard OpenPGP and S/MIME, they can be read by any client that supports those standards, and they stay readable if the mailbox is ever moved elsewhere. A few providers, such as Posteo and mailbox.org, offer a similar option of encrypting incoming mail with the user’s own public key; Stalwart brings the same model to any server you run yourself, and adds the gateway, key discovery, header protection and post-quantum algorithms on top. Post-quantum support is still uncommon. Proton, which co-authored RFC 9980, added opt-in post-quantum OpenPGP keys this year; Tuta’s TutaCrypt uses a protocol of its own; and Dovecot supports ML-KEM keys in its own storage format. Stalwart implements the published IETF standards for both OpenPGP and S/MIME. Unlike services that publish only their client apps, the whole of Stalwart, server included, is open source.
Honesty requires a few qualifications, and we would rather state them than have you discover them. Encryption at rest protects mail from the moment it is stored, not before: the server sees each incoming message in readable form when it arrives, which is what lets the spam filter and Sieve scripts do their work, and an attacker in control of the running server at that moment could read it too. Unless the sender encrypted the message, the protection is not end-to-end. Header fields, the subject included, stay readable, so that clients can list and sort mail, and the server can search only those headers, not the encrypted bodies. Encrypted messages can be read only in a client that supports OpenPGP or S/MIME, not in a webmail without it. Some messages stay in plain text: mail stored before encryption was enabled, drafts and sent copies that clients upload unless the user also turns on encryption of uploaded messages (JMAP drafts, and the sent copies of messages submitted over JMAP, always), and new mail while the registered key is expired or unusable. And a user who loses their private key loses access to the mail encrypted for it, because nobody, Stalwart included, can recover it. And a user who loses their private key loses access to the mail encrypted for it, because nobody, Stalwart included, can recover it.
Upgrading
Section titled “Upgrading”Stalwart v1.0.2 is available now. Upgrading is a matter of replacing the binary or pulling the new container image, as described in the upgrade instructions. The changelog lists every change in this release.
One last thing
Section titled “One last thing”While the server team was busy with ciphers, the WebUI got a makeover, and it now has a good deal more pizzazz. Version 2.0.4 brings a new colour palette and a reorganised sidebar, and every settings form has been reworked: fields sit in two columns on wide screens and stack neatly on a phone, nested settings are simpler to follow, variants are picked from segmented controls, long forms get an index of their sections, and the save button floats along as you scroll. The dashboards were rebuilt too, as a mosaic of statistics, charts, headline figures and rankings, so the state of the server reads at a glance, in the light theme or the dark one.
To try it, run the Update Applications action from the WebUI, or with stalwart-cli create Action/UpdateApps, and the server downloads WebUI 2.0.4 straight away.
Stay tuned
Section titled “Stay tuned”Encryption is only the first of the features that were held back from the v1.0 cut. Several more are finished or nearly so, and they will arrive over the coming weeks, one release at a time. Like everything in this post, all of them will be open source under the AGPL. Stay tuned.