How should group chats work in decentralized systems?

Realman782 pts0 comments

How should group chats work in decentralized systems?<br>&larr; back<br>Intro

I’ve recently released the initial version of Kiyeovo - a decentralized P2P messenger desktop app.

I cannot emphasize how much time went into thinking about group chats. Each model that I came up with had a major flaw, and this was really where the “no server” aspect started to hurt. I realized that there is no “best” way to do this, and that I must choose some tradeoffs in order to keep the app fully decentralized.

Why a server makes groups easy

With a central server, you have a trusted authority that answers these questions:

Who is in this group right now?

What key encrypts the messages, and who should have it?

What order did messages happen in?

I was offline; what did I miss?

Even E2E encrypted apps that can’t read your messages still use servers for these questions.

Signal’s server stores the group roster (and forwards messages)

Matrix homeserver stores group state and orders events

They hand the group state to newly added users, and simply stop the removed users from receiving updates and messages. The content is encrypted, but the coordination - who’s in, what’s the latest state, what came first, what you missed - is answered centrally.

Delete the server and what happens? There’s no “place” that for sure knows the roster, no sequencer machine for ordering, and no 24/7 mailbox for the people who were offline.

2. How other decentralized systems handle it — and why I went another way

There’s a whole range of approaches, below are some that I considered.

(a) Keep a coordinating server (Signal, WhatsApp, Matrix)

The content is E2E encrypted, but a server (or homeserver) still holds everything described a moment ago. Group key schemes here are usually:

Sender keys: Signal - symmetric key per sender, rotates keys when a member leaves

Megolm: Matrix - per-sender ratcheting session, rotated on members leaving/joining

Why not: This one was a hard pass because it included centralization, which was one of my non-negotiables. This defeats the purpose of a serverless app - the network needs to keep working with no “privileged” points.

(b) MLS / TreeKEM (RFC 9420)

MLS is the state-of-the-art for group encryption. Every member’s key is arranged in a tree, so when you remove or add someone, it only touches a part of the tree. In other words, it’s very scalable - stays fast even in groups of thousands.

Why not: MLS requires a “Delivery Service” that hands out its key-change messages. Doing it<br>with no server, over a DHT, where peers can be offline… is a lot. But also, the tree only really pays off in big groups whereas Kiyeovo groups cap at 10

(c) Leaderless membership

Let any member add or remove other members, and eventually converge with some merge logic. Authority is fully decentralized — no<br>admin at all.

Why not: The moment two people change the membership at the same time, peers can end up with<br>different pictures of who’s actually in the group. You can merge those back together<br>eventually, but the merge rules get tricky. For example, there’s no way to answer an ordering question without a trusted clock. “Was X kicked before or<br>after the message they just sent?” has no answer if members don’t agree on a “global event order”. I have thought about having a proof-of-work layer, but that seemed too heavy.

(d) Fix the membership at creation (e.g. Briar-style private groups)

Some P2P apps dodge the whole problem by not supporting dynamic membership: the member set is fixed when the group is created, and you never add or remove anyone.

Why not: This was actually my initial idea. However, not having invite or kick was too big of a downside for me. While I’m writing this, I am actually thinking about how often do the groups I’m in change membership, and the answer is - not that often. This would’ve simplified things quite a bit, but now it’s done and dynamic groups work, so that’s pretty good.

3. How I actually did it

Rules: no server anywhere, make convergence trivial.

3.1 Membership: One creator

Every group has one creator, identified by an Ed25519 key. All other members have the creator’s key so they can use it to confirm that the update actually came from them. Only the creator can invite and kick . Members who want out send a signed leave request and the creator applies the removal.

Pros: There’s no “two admins kicked different people during a partition” situation to merge - there is exactly one legit writer of membership state. Convergence is simple when there’s only one author -> this is actually the opposite of approach (c).

Cons: the creator is a single point of failure. If they lose their device (identity) or are just not online - existing members can keep talking on the current key, but nobody can be added or removed (users can still leave and not receive message, but the other group members will not have a verified notification that X left the group).

3.2 Keys: Rotated Sender keys per epoch

An epoch is...

group server groups members membership decentralized

Related Articles