Projects / Rocket.Chat

Rocket.Chat + minidauth a chat server whose messages the database can't read

A chat server's most sensitive data is the message itself. In this fork of Rocket.Chat, the open source Slack alternative, a message's text is sealed before it reaches MongoDB, and opens back to plaintext only for a member a quorum granted the reading role, both when loading history and as messages arrive live.

Run end to end

What gets sealed

Rocket.Chat is the open source Slack alternative. These fields are stored as ciphertext, and nothing on the server can decrypt them.

Messages
The body of every message. The room id, the sender and the timestamp stay in the clear, because a chat server sorts and routes on them.

How it's wired

  1. Sealed at the model layer

    One hook on Rocket.Chat's MongoDB base repository seals the message body on insert and update, so every write goes through the same place, and ciphertext is what reaches MongoDB.

  2. Opened per reader, in history and live

    Loading a room opens the body as the requesting member through the common message normaliser. A message that arrives live opens per recipient, by reusing Rocket.Chat's own per-subscription transform in the streamer.

  3. Gated by a quorum role

    A message opens only if minidauth's quorum grant says that member holds the reading role. A member without it sees ciphertext in the very same room, and revoking it makes reads go dark.

The key that seals these fields exists only as shares across the Tide network, and 14 of 20 nodes have to cooperate to use it. It is never on the Rocket.Chat server.

Details that matter

  • The sidecar holds no reading identity of its own. Opening is delegated per member and gated on a quorum-granted role.
  • With no reader in context, a message stays sealed, so there's never an open decryption service to abuse.
  • Rocket.Chat pre-parses each message into a rendered copy; that copy is dropped on write, so plaintext can't leak through it.

Status and running it

A proof of concept, off unless MINIDAUTH_SEAL_URL is set, so an unconfigured checkout behaves exactly like upstream Rocket.Chat. The fork's README covers setup against a running minidauth.

Want to do the same for another app, or stuck running this one? Join the Discord and I'll help you out.

Other projects: Formbricks · Twenty · Cal.diy · Documenso · Medusa · Chatwoot · Firefly III · Integrations