7 min read

Roomy Chat - Alpha

Screenshot of the Roomy UI

Roomy is (becoming) an open source group chat application. It's similar in scope to Discord, but built on open standards like ATproto for social discovery and Automerge for peer-to-peer connectivity.

About 2 weeks ago we received a generous grant from Skyseed to develop a chat prototype on top of the AT Protocol! The grant funded the next month of work for me and @zeu.dev, with direction from @erlend.sh.

Today we're releasing the Highly experimental public demo so that people can test it out!

The demo app is live at roomy.chat!

This is alpha software, meaning it is extremely unstable. Don't put anything in it that you want to keep safe. In this post I'm going to go over what's working, what we want to get working before the end of the month, and a little bit about how it works and why that makes a difference.

What is Working?

0:00
/0:41

The main functionality working right now is direct messages that backup to your PDS.

You can login with your BlueSky account, create a new direct message, and, if the other user also creates a direct message with you, you can both chat with each-other!

We have some work-in-progress UI for creating threads, and some ideas that we want to experiment with to try and improve, not only the way you chat, but the way that you can distill the valuable ideas and thoughts from your chats into more permanent mediums such as articles or wiki pages.

Caveats - Beware of Dragons!

There are some pretty major caveats to be aware of. Feel free to reach out to us if you have any issues!

  • As we make updates, we may make breaking changes that will require you to delete all your chat data before the app starts working again. There is a button in the left sidebar for doing this. This is a temporary situation!
  • We store all of your data on your AtProto PDS, which means that it's all in a place where anybody in the world can download it. The PDS doesn't let us store private data.

Encryption

To help with the lack of private data, we do encrypt direct messages, which makes it hypothetically difficult or impossible for a stranger to read your messages, even though the encrypted data can still be downloaded by anybody. This has some caveats, too:

  • This is all super experimental and un-audited. We could have a critical flaw that makes the encryption almost useless.
  • There is some non-encrypted metadata that shows who you are talking to, just not what you are saying.

Even if it's not perfect, we figured we might as well have some mechanism to prevent people from viewing your direct messages outright, even if we're not sure that it's bullet-proof yet. If you manage to break our security, let us know!

ℹ️
Note: True privacy, where not anybody can download your encrypted data, is something that we will probably provide a paid service for in the future.

See the section on sync servers below.

How it Works

Roomy works differently than most AtProto apps, and it operates partially peer-to-peer.

Most AtProto apps work something like the diagram below. The PDSs all send their data as it is created to the relay, and the relay aggregates the data from all PDSs and sends it to any subscribing AppViews.

Each app tends to have their own AppView, and it will record the data that it is actually interested in in it's own database. Then when clients want to view the data, they will ask the AppView which will query it's database to respond.

Atproto architecture: PDSes send data to the Relay, which sends it to the AppView which sends it to the clients and records it in the database.

Notice that the AppView is very similar to a typical, centralized web application server. The difference is that it is able to ingest the data that comes from many different personal data stores across the network, and when a user wants to add their data to the app, they do so by writing to their own PDS directly.

Something we are very interested in, though, is the possibility to lessen or remove the dependency on the relay and AppView. For example, for chat between small groups, there's no need to have a relay that subscribes to every PDS on the whole network. We only need to find out about the data from a few other friends, which each have their own PDS.

Not needing an AppView also means we have less financial and organizational dependency on something needs to scale up dramatically the more people use it.

Roomy's architecture is shown below, and we'll explain every piece of it.

Roomy architecture shows clients connecting directly to their own PDS with connections between clients facilitated by the routing server and key server.

Key Server

First off, we have the Key Server, which is super simple. It allows you to ask for a public key for any user on AtProto, even if they haven't ever used Roomy before. It does this by just generating a new key for the user if one doesn't exist. This means that the keyserver also has the private keys for all users on the network, by default.

This might stand out as a "security flaw", but the reason is simple: the user experience must default to what the user expects. New users's should never lose access to their data / permissions if they can still log into their AtProto account. Having to keep track of a private key that they cannot recover if they lose is a hard no.

If an extra security conscious user wants to manage their own private key so that our key server doesn't have access to it, that's fine. They can announce their public key on their PDS instead of letting our keyserver create one for them.

This way we can support a good user experience, while still allowing users to choose take on more responsibility to gain more security.

💡
We also have some future ideas for creating a more secure, but still recoverable key-pair system using FROST signatures.

See 2FA For Keypairs for more explanation on the idea.

Routing Server

Being that Roomy is a web app, and we have no AppView, we need a way to connect the web clients to each-other. That's the job of the routing server.

The routing server is a very simple WebSocket server that the clients will connect to in order to find out who is online and what chat rooms they share. The router also forwards encrypted sync messages between peers.

In the future the router will also act as a WebRTC signalling server, so that peers can send their messages directly to each-other, without having to use up bandwidth on the routing server.

The routing server is the most centralized and most expensive service in Roomy right now, but I'm hoping it should still be very cost-effective to run, even with a lot of users.

In the future we want to allow you to have alternatives to using the one central routing server, and that could take the form of allowing PDSs to specify alternate routing / WebRTC signalling servers that must be used if you want to chat with that user. The Roomy app would manage this automatically so that you don't have to care what routing server another user is using to chat with them.

If we make a Roomy desktop app, we could possibly make it 100% peer-to-peer by using Iroh for networking and hole-punching and even possibly the BitTorrent DHT for peer discovery.

We want to design things so that they can be as centralized or decentralized as necessary or useful, so that we can reap the benefits of each depending on the situation. One size does not fit all.

Automerge & ( Future ) Sync Servers

In the future we will most-likely have a new, optional service we're currently calling a Sync Server.

We use Automerge to power our p2p-style chat synchronization so that we're able to sync data to local browser storage, and the PDS, while doing realtime updates through the routing server. But this is not the most efficient setup because PDSs aren't designed for doing synchronization like this, and the routing server doesn't have any chat data on it at all, making things less efficient when you need to keep track of chats all on different PDSs with clients not all online at the same time.

There is a work-in-progress Beelay protocol that we plan on experimenting with as soon as it's public. It's designed to efficiently sync end-to-end encrypted data with many peers, and supports private data, unlike the PDSs. While this is much better for synchronization, it would mean that our servers now have to take on the load of everybody's data who uses it, instead of being able to offload to PDSs.

That extra load is why we would make sync servers a paid service, or an optional self-hosted component. We are trying to keep things as sustainable and realistic as possible, allowing things to work as much as absolutely possible without our hosting if necessary.

Coming Up Next

We've still got 2 weeks of funded work, and the next thing on our list is group chats and UI improvements like replies, reactions, and chatting in threads!

We are pretty close to group chats now, but, with the current implementation, the more members there are, the slower things will get. So we don't know how many users can join a group before things get inconveniently slow.

We do have ideas to optimize for larger groups, though! The goal right now is to see how far we can get without having to start hosting a more centralized sync service, like what is needed for private groups and chats.

We're super excited to get to work on this, and welcome feedback and questions on our Discord (for now!) and GitHub repo. Try it out at roomy.chat.