Encryption at rest (APPEND issue)

Issue Description

According to Overview | Stalwart, the server-wide “Encrypt on append” is supposed to be an override:

“The server-wide encryptOnAppend value is an override: when set to true, it applies to every account regardless of the per-account encryptOnAppend carried inside encryptionAtRest. When the server-wide flag is false, the per-account setting applies.”

However, in practice that is not so, at least for Stalwart 0.16.12. Specifically, I have an account which is set with both “Encryption at rest” and “Encrypt on append” ON. The system settings are default (Encryption at rest ON, Encrypt on append OFF).

In this configuration the emails sent via SMTP get encrypted, but emails imported via IMAP don’t (logs confirm messages were appended via IMAP).

If I turn system-wide “Encrypt on append” ON, then only then imported via IMAP messages actually get encrypted. Can this be fixed to ensure that account settings actually apply for that option instead of having it forced system-wide to all? Alternatively, could documentation be fixed to match the actual behaviour?

Expected Behavior

Imported messages should be encrypted when the account is configured with the encryption at rest with “Encrypt on append” ON.

Actual Behavior

The emails are imported unencrypted UNLESS system-wide “Encrypt on append” in the admin UI is set to ON.

Reproduction Steps

  1. Create an account, log into it, upload public PGP key and select AES-256 Encryption at rest. Toggle “Encrypt on append” to ON.
  2. Ensure system-wide settings are ON for “Encryption at rest” and OFF for “Encrypt on append”.
  3. Import any message into the account via IMAP and then retrieve it with the client - you should see unencrypted message.
  4. Reconfigure system-wide option to ON for “Encrypt on append”.
  5. Import new messages and retrieve those with the email client - they should be encrypted.

Relevant Log Output

Stalwart Version

v0.16.x

Installation Method

Docker

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

Thunderbird (with Open keychain)

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

Your reading of the code is correct, and this does look like a bug rather than a misunderstanding of the docs.

Looking at the ingestion logic, when a message arrives via IMAP or JMAP, encryption is only applied if:

let do_encrypt = match params.source {
    IngestSource::Jmap { .. } | IngestSource::Imap { .. } => {
        self.core.email.encrypt && self.core.email.encrypt_append
    }
    IngestSource::Smtp { .. } => self.core.email.encrypt,
    IngestSource::Restore => false,
};

Both self.core.email.encrypt and self.core.email.encrypt_append here come from the server-wide settings only. The per-account ACCOUNT_FLAG_ENCRYPT_APPEND flag is computed elsewhere (in principals.rs, from the account’s encryptionAtRest.encryptOnAppend) and stored on account.flags, but that flag is never actually consulted in this do_encrypt check for IMAP/JMAP ingestion. So a per-account encryptOnAppend: true has no effect unless the server-wide flag is also true, exactly matching what you observed.

This contradicts the documented behavior at Overview | Stalwart, which describes the server-wide flag as an override only when true, with the per-account setting applying when the server-wide flag is false. The code does not implement that override logic for the append path; it only implements the account-level override correctly for SMTP-based ingestion is trivial (SMTP encrypt is server-wide too, no append distinction).

This is a genuine bug in the encrypt-on-append logic, not a documentation error. A human maintainer will need to confirm and fix the ingest logic to check the account’s encrypt_on_append/ACCOUNT_FLAG_ENCRYPT_APPEND flag as an override, as documented.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.