Signal Web
Building a web version of Signal
Signal is a privacy-conscious[1] messaging platform that has gained popularity in the past years. It is available on mobile, desktop andβ¦ thatβs all. There is no official web client of Signal, although this a popular request from the community, and this is on purpose.
Well, I understand the reasons behind their choice but a web version has a lot of benefits:
- lightweight (the desktop application weighs 250MB)
- available even on restricted computers
- no need to install an application
For all these reasons, I stayed home on a sunny Sunday afternoon to set up my version of Signal Web.
The objectives
It should be simple. Although porting libsignal, the underlying library powering all Signal clients, to the web with WebAssembly seems possible[2], this was not my intention and I wanted to rely on existing tools to avoid transforming this busy Sunday afternoon into a whole month project.
I also wanted to keep the solution as secure as possible as the βend-to-end encryptionβ feature of Signal is one of its core features.
Finally, the solution should be user-friendly (simple interface, easy to navigate) and have as much feature-parity as possible with the other Signal clients (messages, media, reactions, calls).
Enter the matrix
Matrix is a very powerful messaging protocol which allows federation, self-hosting and, most importantly, bridging with other applications (which means that you can receive and send messages that lives on another platform such as WhatsApp, Telegram or⦠Signal).
This seems like the perfect solution for me. Letβs install Matrix and we are done. Easy no? Wellβ¦ You cannot install Matrix. Matrix is just the protocol. What you need is a Matrix server[3], that will host the messages, a Matrix-Signal bridge that will connect the server to Signal, and a Matrix client that will display them to the user. Thankfully, there is only one Signal bridge, but there a few possibilities for the Matrix server and a lot of them for the Matrix client.
So here goes choosing the best Matrix server and client for our purpose. For the client, I went with the most popular one, Element. It supports most of the features and seems like a good fit.
For the server, I went with Dendrite first as it was advertised as the βsecond-generationβ server by the creator of Matrix with a lightweight footprint which was important to me as it would be installed on a RaspberryPi in my home with limited resources. The Signal Bridge does not support this home server however[4], so I went with Tuwunel[5] which seems to have the same purpose as dendrite.
Note: If I add to start again, I would have gone with Synapse, the oldest and most complete server. Tuwunel is still missing some features[6] and even though Synapse was fairly heavy to run at the beginning, it seems fairly light now and should run on my Raspberry Pi.
Architecture
The architecture with the Signal application is simple, the application connects with end-to-end encryption to the Signal servers. βββββββββββββ End-to-end encryption
βββββββββββββββ βββββββββββββββ
β Signal β ββββββββββββββββ£ Signal β
β servers β β application β
βββββββββββββββ βββββββββββββββ
In this case, the bridge acts as a Signal client so the messages are end-to-end encrypted between Signal servers and the bridge. Then, the Matrix client talks to the Signal bridge through the Matrix server. The messages are also end-to-end encrypted and the Matrix server does not see the content. βββββββββββββ End-to-end encryption
βββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββ β βββββββββββββββββ βββββββββββββββββ β ββββββββββββββ
β Signal β βββͺββ£ Matrix signal β ββββββββββββββββββββββββͺβββ£ Matrix β
β servers β β β bridge β β Matrix server β β β client β
βββββββββββββββ β βββββββββββββββββ βββββββββββββββββ β ββββββββββββββ
β Home server β
βββββββββββββββββββββββββββββββββββββββββββ
Wrap up
In the end, I am pretty satisfied with the result. Element has a polished interface and I can read and send Signal messages seamlessly. The security model is a bit weak as all messages are in clear text at some point on my server but this is acceptable for my threat model.
The big limitation compared to the initial objectives is calls are not supported. This is not the primary usage of Signal I had in mind and other web clients (such as WhatsApp Web) do not support them either so I guess this was to be expected.
Happy messaging!
There are some detractors, mainly about the fact that it requires a phone number to register, but as a mainstream messaging platform, I think it fulfills its goal pretty well. β©
A port of libsignal was achieved by some people from INRIA, but it has not been updated for 6 years. More recently, an issue on GitHub is optimistic about the current feasibility, but it would be considered as unofficial and no-one stepped up for this mission yet. β©
Public matrix servers are also available but the only existing Signal bridge (yes there can be several depending on the service) requires being able to edit the home server configuration which means self-hosting. β©
Well, apparently it can as described in this issue, but I only found out when writing this article. β©
At the time of publication, I was using Conduwuit, recommended by the Signal bridge, but it was discontinued. Tuwunel is the continuation of Conduwuit work. β©
When a message is read on the Matrix client, the βread statusβ is not transmitted back to Signal so the message is still unread on the phone. GitHub issue. β©