Following up on my previous mail, I've spent some time thinking more about how encrypted mailing lists could be integrated with the current Mailman architecture. Based on my current understanding of Mailman Core, Postorius and HyperKitty, I tried to sketch a possible message processing pipeline architecture diagram here: https://www.tldraw.com/f/v4LLMD7t72DyEcbE-J7Qf?d=v-2032.-109.3919.2270.page
The main idea is to allow encrypted delivery in mailing lists, while making sure plaintext messages are never stored on disk, but still keeping the archives working. Key management, - every subscriber provides a PGP public key to Postorius - Postorius stores subscriber public keys and Mailman core can fetch them through the existing API. The mailing list itself also has a keypair (list_pub, list_priv) used for receiving encrypted messages - HyperKitty has an archive keypair (archive_pub, archive_priv) used for archive access by subscribers Sender, When a sender posts to the mailing list, the sender does two things: encrypt the message using list_pub, and optionally sign the message using their private key (sender_priv). Mailman Core then receives the encrypted SMTP message. Mailman Core processes the message roughly as follows: - decrypt the message using the list private key (list_priv) - optionally verify the sender signature using the sender’s public key - generate a random symmetric key K (e.g. AES or ChaCha20) - encrypt the message body using K - encrypt K for each subscriber using their public key - encrypt K once more using the archive public key (archive_pub) This follows the standard envelope encryption approach: the message itself is encrypted once using a symmetric key (K), and that symmetric key is then shared with recipients using asymmetric encryption. Subscriber delivery, For each subscriber, Mailman sends a message containing: - the encrypted message ciphertext - encrypted_K_user Each subscriber receives the ciphertext and a copy of the encrypted symmetric key K. The subscriber first decrypts encrypted_K_user using their private key to recover K, and then uses K to decrypt the message ciphertext. Archive storage, For archives, Mailman Core sends HyperKitty two things: - the encrypted message ciphertext - encrypted_K_archive HyperKitty stores only encrypted data. When a subscriber requests an archived message, HyperKitty decrypts encrypted_K_archive using archive_priv, retrieves K, and then decrypts the message so it can be rendered in HTML. Design tradeoffs, This design intentionally uses an archive key to support access to historical archives. This allows new subscribers to view past messages without needing expensive re-encryption of archived content. The tradeoff is that HyperKitty must hold archive_priv, which means the archive server technically can decrypt stored messages. So the system assumes that the archive service is trusted to some extent. However, plaintext messages are never stored on disk, archived data remains encrypted at rest, and messages stay encrypted in transit and outside controlled processing stages. Feedback is welcome if I misunderstood any part of the Mailman pipeline or component responsibilities. _______________________________________________ Mailman-Developers mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/mailman-developers.python.org/ Mailman FAQ: https://wiki.list.org/x/AgA3 Security Policy: https://wiki.list.org/x/QIA9
