Blog

rust fediverse

A technical intro to the fediverse

When I started a new fediverse app some weeks ago I did not know much about how the fediverse actually works.

Yes I am on Mastodon, I chose an instance at some point but never really digged deeper into the the technical details. I want to share what I learned and why I think it is one of the good things that happened to the internet in shorter history.

It is probably best to explain things using an example - what happens when you follow another user. If you think of a normal social media app you would think that it is as easy as putting some relationship in your database that says a user with one id follows another user id. In the fediverse there are two cases - if you follow someone on your instance (like mastodon.social) the process is the same, but it becomes more interesting when you follow someone on another instance (mastodon.online or even a different app).

So let’s say you want to follow @user@instance.social, when you are an actor on another instance @me@myinstance.social. These two things that look like emails but starting with another @ are webfingers. By requesting an instance’s webfinger endpoint https://instance.social/.well-known/webfinger?resource=acct:user@instance.social" you get more information about the actor behind the webfinger, especially the url for the actor activitypub data, for example https://instance.social/user. Without going into details, if you query this enpoint with the right headers you get information like user name, avatar, cover image etc, which your instance now pulls to mirror the user on your instance. So even while the user is on another instance you have the user on your instance and you take the local id to put the relationship in your database. But wait - how does the other user know you want to follow?

When you pulled the activitypub json for the user, one url you get is the inbox - this url you can use to send messages to the other user’s instance. A follow is an activity (hence the name activity pub), which is different to a Person (think user), which is called an object. The connection is that you do an activity with an object - you follow a person. You send an activitypub json to the inbox with the informations

  1. Actor: That is you, e.g. https://myinstance.social/me
  2. Object: The other user https://instance.social/user
  3. The type for the follow activity (Follow)
  4. A unique id that you need to store (reason follows)

But wait - can everybody just send these messages? Then everybody could just pretend to be you and send this exact payload to sign you up. That is why the messages need to be signed, so that the receiver can check that the actor in the payload actually sent the message.

The other instance receives the payload and now pulls your profile over, so that there is a local copy of your profile, and uses this local id to also store a relationship in the database, but for now the follow request is pending. To finish the process, the instance sends back an Accept activitiy that contains the id you created and sent along before. You look up this id in the accept you are receiving, get the follow relationship that was pending in your local database and mark it as accepted. At the end of the process on both instances there should be the exact same state in the databases, even if the database structure may be completely different.

So even with this short example, doing things decentralized is much more complicated than your “normal” social media app. Keeping multiple completeley independent apps in sync is no small feat. On top there are all the small differences in the implementation for the different fediverse citizens.

Why the hassle

With the fediverse you have a lot of choices - join a big instance and use it like the old twitter, join one or multiple small instances depending on a topic, host a fediverse app you like on your own domain or even create you own fediverse app. Because it is not centralized, there is no risk of being sold to a crazy person. The instance you are on could be shut down, but for mastodon you could at least migrate most of your data over to a new instance (not the posts apparantly). You can interact with other apps and their users without signing up on another closed platform.

The reason why I created another fediverse app? I wanted a mixture of the old myspace (there is now neocities) and the fediverse, that could easily be hosted on my domain (like the indie web). So I ended up starting an app that is low on resources, let’s you customize your profile like myspace and just needs a Sqlite database to function. It is still very much work in progress, but following should already work 😎

Things I (re)discovered writing this