RATP : a generic ActivityPub server

Yet another project…

It has been almost two years since I started working on Plume. It is really great to work on a relatively important project, that real people use. But working with ActivityPub is not always a pleasure…

The protocol is not very well specified, too vague, to be correctly implemented. It misses a few important features to provide true confidentiality and security. However, the idea of federation still is amazing, and I really believe it is the way free/libre software should take if they want to reach as much people as possible and create real alternatives to proprietary applications.

But, the way ActivityPub is currently implemented is not satisfying to me. As I said, the protocol is too vague to have coherent implementations, and the new projects are forced to copy what the previous ones are doing to make sure they are all compatible. On top of that, each implementation is focusing on only one "activity" (as they are called in the specification) type : Mastodon for micro-blogging, Pixelfed for pictures, Funkwhale for audio, etc. Only Pleroma handles, technically, any kind of activity (in practice, it mostly does micro-blogging).

One server to rule them all

That's how the idea of creating a trully generic server was born. A server able to handle all the activities. And because it will be written in Rust (what a surprise), @wxcafe@social.wxcafe.net suggested to call it RATP : Rust ActiviTyPub (it is a pun with the RATP).

To make it short, RATP would just act as a big database, storing all the received activities. On top of that, the server would handle account management, and why not media processing. That way, a lot of redundant code between the different ActivityPub implementations could be shared. For the users, it would mean that you would only need one account to access all of the Fediverse: no need to register on six different platforms to get all the potential of the Fediverse.

But how will it be possible to access all the different activities from one interface? A video and a private chat shouldn't show the same way ! And it is not possible to make an exhaustive list of all the possible activity types since anyone can define their own. To handle this issue, RATP would have a plugin system : by default, no interface would be provided, and instance administrators will have to choose which plugin to install to provide various interfaces. The plugins will be able to interact with the database, expose a REST API for a specific kind of activity, and eventually a specific front-end.

Questions that still need to be answered

Even if I have a general idea of how everything will work, there a few details that are not clear yet, and on which I would appreciate feedback and ideas.

First of all, how should plugins be implemented? Ideally, you should be able to use any language to write them. That's why I thought of using WebAssembly, that would technically allow to run plugins written in any language (well, almost). On top of that, the WebAssembly virtual machine would offer a sandbox to limit system access to plugins, avoiding malicious plugins to have too much access to your server. Another solution would be to have plugins as standard binaries, launched by RATP.

Then, we would have to make RATP and plugins communicate. If they are implemented in WebAssembly, all you would have to do would be to expose a set of functions on both sides, and the problem would be solved. But if we use "traditional" programs, there should be a protocol to exchange messages over network, sockets, or stdin and stdout, which means more work both for me and for plugin developers, but which would also be much slower than function calls.

Thus, I would prefer to use WebAssembly, but I'm not sure it really is a great idea, despite its good security and performances.

The last question I'm asking myself is about the database format. I would like to create a custom format, perfectly adapted to JSON-LD (the data format ActivityPub uses), that would allow to add features that are useful in an ActivityPub context, like storing an history of each object, which would for example make it possible to hide your previous "private" posts to a new follower. However, it is a quite big project, and I'm not at all a database expert, so I fear to make mistakes. I think I will start with a custom format, making it evolve as I need new features, and if it actually is too complex, I will go back to a "classical" solution.

And… that's it! I don't know if what I plan to do is clear or not, nor if there are things I forgot. And for Plume, I will still maintain it next to RATP, this new project only is an experiment for now.