Matrix: Migrate an encrypted room to a clear text one

Publié le 24/03/2022

Some time ago, the Matrix team was pushing hard E2EE and activated it for all created rooms. Believing encryption was the future, we kept this default for all of our rooms. But now that one of our room starts being popular, it appears that E2EE does not work well with public rooms:

  1. the history is not available to newcomers
  2. we can not search the history of an encrypted room (or at least, I never managed to make it work even with the desktop app)
  3. notification options are more limited
  4. scaling issues
  5. many additional minor issues

It seems that Matrix developers are aware of these problems as if you create a “public room” now, you will not be proposed to encrypt it. But for existing rooms, we still have a problem: for security reasons, you can’t disable encryption in a room. Our only option is to create a new room and to point the old one to the new one.

Thankfully, Matrix has a feature named Tombstone that helps redirecting users from one room to another. This feature is used for room version upgrade, but we can “abuse” it to redirect people to a completely different room.

First, you must create a new clear text room. To provide the best experience to your users, take time to configure its picture, description, and so on. Now, go to your old room, remove all its aliases to be able to set them on the new room. You can set a new alias for your old room and send a message containing it on your new room, to “connect it with the old one”, eg:

Hi, this is the beginning of the history of this room. If you want to go back even more in time, check the old room: #myroom-old:example.tld

Finally, you need the identifier of your new room. It starts with a !. For example: !ARbIZeDKGloDOnjyyw:deuxfleurs.fr. Keep it somewhere accessible, and we are done configuring our new room.

We can now prepare the tombstone for the old room. First, you should inform your users with a message, something like:

Hi @room, we are migrating to a new room to fix some issues with this one. You will not be able to post new messages here, please follow the provided redirection to join the new room. Sorry for the inconvenience.

Now we will prepare a state event that point to the new room, create a file named migration.json based on the following template:

{
  "body": "We migrated to a cleartext rooms as E2EE does not work well with large public rooms",
  "replacement_room": "!ARbIZeDKGloDOnjyyw:deuxfleurs.fr"
}

This event must be sent in the old room. Let’s say its identifier is !MFnHRRrCTMeHvfnNUD:deuxfleurs.fr. The URL template is thus:

https://im.deuxfleurs.fr/_matrix/client/v3/rooms/!MFnHRRrCTMeHvfnNUD:deuxfleurs.fr/state/m.room.tombstone

The last thing we need is to build an header file containing the required information for authentication onto the API. Create a file named hdrs.txt based on the following template.

Authorization: Bearer see_below_how_you_can_find_me
Content-Type: application/json

The authorization header can be extracted from an Element Web instance by opening the developer panel (F12) and going to the Network tab. Then select a request going to your matrix backend, on the right part of your screen search the “Authorization” line and copy/paste its value.

Finally you can send the request to the API by again adapting the following command template:

curl \
  -H @hdrs.txt \
  -X PUT \
  -d @migration.json \
  'https://im.deuxfleurs.fr/_matrix/client/v3/rooms/!MFnHRRrCTMeHvfnNUD:deuxfleurs.fr/state/m.room.tombstone'

And that’s all, you have migrated your old encrypted room to a new clear text one!

If you want to explore all the possibilities offered by the developer tools, you can read Matrix specification. For example, our tombstone event is documented here: m.room.tombstone