RATP : un serveur ActivityPub générique

Encore un nouveau projet…

Ça fait presque deux ans que j’ai commencé à travailler sur Plume. C’est vraiment extraordinaire de travailler sur un projet assez important, utilisé dans la réalité, mais travailler avec ActivityPub n’est pas tout le temps une partie de plaisir.

Le protocole n’est pas très bien spécifié, trop vague, pour être bien implémenté. Il manque certaines fonctionnalités assez importantes pour garantir une vraie confidentialité et une vraie sécurité. Mais malgré ça, l’idée de fédération est extraordinaire et je pense que c’est vraiment dans cette direction que les logiciels libres doivent se diriger s’ils veulent toucher un public le plus large possible, et proposer de vraies alternatives aux applications privatrices.

Cependant, la façon dont ActivityPub est implémenté actuellement ne me satisfait pas. Comme je l’ai dit, le protocole est trop vague pour avoir des implémentations cohérentes, et les nouvelles implémentations sont obligées de copier ce que font les précédentes pour assurer leur inter-compatibilité. En plus, chaque implémentation se concentre sur un type « d’activité » (comme elles sont appelées dans la spécification) spécifique : Mastodon pour le micro-blogging, Pixelfed pour les photos, Funkwhale pour l’audio, etc. Seul Pleroma gère, en théorie, n’importe quel type d’activité (en pratique, c’est avant tout du micro-blogging).

Un serveur pour les gouverner tous

C’est de là que naît l’idée de créer un serveur réellement générique. Un serveur capable de gérer toutes les activités. Et comme il sera écrit en Rust (forcément), @wxcafe@social.wxcafe.net a suggéré le nom RATP : Rust ActiviTyPub.

Globalement, RATP se comporterait juste comme une grosse base de données, capable de stocker toutes les activités reçues. En plus de ça, le serveur s’occuperait de la gestion des différents comptes, et éventuellement du stockage des médias envoyés. Ainsi, beaucoup de code redondant entre les différentes implémentations (fédération, gestion des utilisateurs, images) seraient mis en commun. Pour les utilisateurs, cela voudrait aussi dire un seul compte pour toutes les « activités » : plus besoin de s’inscrire sur cinq ou six services différents pour profiter de tout le potentiel du Fédiverse.

Mais comment permettre d’accéder à tous les types d’activités possibles depuis une même interface ? Une vidéo et une conversation privée ne s’affichent pas du tout de la même façon ! Et ce n’est pas possible de faire une liste exhaustive de toutes les activités qui pourraient exister, étant donné que n’importe qui peut créer son propre type d’activité. Pour répondre à ce problème, RATP aura un système de plugin : par défaut il n’y aura aucune interface, et les administrateurs d’instance choisiront quels plugins installer pour offrir telle ou telle interface. Les plugins pourront interagir avec la base de données, exposer une API REST adaptée à un certain type d’activités, et/ou un front-end spécifique.

Les questions restantes

Même si j’ai une bonne idée générale de comment tout ça va s’organiser, il reste quelques questions pour lesquelles je n’ai pas de réponse, et j’aimerais avoir des avis dessus.

Déjà, comment les plugins devraient être implémentés ? Idéalement, ils devraient pouvoir être écrits avec n’importe quel langage. J’ai donc pensé à utiliser WebAssembly, ce qui permettrait de techniquement faire tourner des plugins écrit dans n’importe quel langage (ou presque). En plus de ça, en exécutant les plugins dans une machine virtuelle WebAssembly, on peut limiter l’accès au système que les plugins ont, n’autorisant l’accès au système de fichier que sous certaines conditions par exemple, permettant ainsi d’éviter les plugins malveillants. Une autre solution serait d’avoir des plugins qui sont simplement des programmes normaux, lancés par RATP.

Il faudrait ensuite assurer la communication entre RATP et les plugins. Si ces derniers sont implémentés en WebAssembly, il suffira d’exposer un certain ensemble de fonctions des deux côtés et le problème sera résolu. Mais si on utilise plutôt des programmes « classiques », il faudrait définir un protocole pour échanger des messages, qui devra passer par le réseau, des sockets, ou les entrées et sorties standards, ce qui représente plus de travail et qui sera sans doute plus lent que d’appeler des fonctions.

Donc, je préférerais passer par du WebAssembly pour ces raisons, mais je ne sais pas si c’est vraiment une bonne idée, malgré les avantages de la sécurité et des bonnes performances.

Le dernier point qui n’est pas parfaitement clair est le format de la base de données. J’aimerais créer un format « maison », parfaitement adapté pour stocker du JSON-LD (le format de données utilisé par ActivityPub), ce qui permettrait d’ajouter des fonctionnalités utiles dans le contexte d’ActivityPub, comme la sauvegarde de différentes versions d’un même objet dans le temps, permettant par exemple d’assurer qu’un nouvel abonné ne puisse pas voir vos anciens messages « privés ». Cependant, c’est un assez gros projet, et je ne suis pas du tout experte en base de données, donc j’ai peur de faire des erreurs dans l’architecture de celle-ci. Je pense que j’expérimenterais avec un format spécial RATP au départ, faisant évoluer le format de fichier au fur-et-à-mesure des besoins, et si jamais je vois que c’est trop complexe, je me rabattrais sur une solution plus classique.

Voilà, je crois que c’est tout, je ne sais pas si ce que je veux faire est clair, ou s’il y a des choses auxquelles je n’ai pas pensé. Et pour ce qui est de Plume, je continuerais à le maintenir en parallèle, RATP n’est qu’une expérimentation pour le moment.