ActivityPub in Pleroma

4 minute read Published:

Implementing ActivityPub in Pleroma

After some work, ActivityPub support will be merged into the develop branch of Pleroma in the next days.

This change will add the following user facing features:

  • Support for Mastodon’s visibility suggestion settings, like private posts and direct messages.
  • Slightly faster federation

Not too much for a few weeks of work. Anyway, here are my thoughts about the whole process.

For Server Admins

After the ActivityPub support is merged, you’ll have do a rather costly migration. This took a few hours on Soykaf, but only a few minutes on Expect some downtime. Also, you’ll need to run this command:

mix deps.clean --build mime

This will rebuild the mime type cache and enable the new types necessary for ActivityPub.

There are no further steps. User upgrade will happen automatically.

Notes on the implementation

Pleroma is a bit special when it comes to ActivityPub. When I started it nearly a year ago, I wanted to experiment with PostgreSQL’s jsonb data type. This allows you to use PostgreSQL to store arbitrary json, but still have the nice SQL features like indexes, full text search and so on. Because of this, Pleroma has internally been ActivtyPub since the beginning. AP activities are actually saved as json in the database.

Back then, neither GNU Social nor Mastodon supported ActivityPub, so it didn’t make much sense to talk ActivityPub for federation. Instead, we implemented the OStatus federation mechanism.

Some time down the line, Mastodon decided to implement ActivityPub to solve some problems with their OStatus implementation. This lead to them only partially federating over OStatus, as their ‘private’ posts would now only federate over AP.

We have now implemented a working ActivityPub federation module in Pleroma. If another user is detected to live on an AP server, federation will only happen over ActivityPub.


In a previous post, I wrote that you’d have to implement whatever Mastodon has to be compatible to it. This is absolutely true.


While the standard doesn’t mandate any signatures, Mastodon has two of them: HTTP Signatures, which can tell you that a message came from a certain account, and Linked Data Signatures, which can do the same in a different way, and can be relayed (that is, a server can share posts of another server, and you can validate them).

For basic Mastodon support, you’ll only need to implement HTTP Signatures. You’ll miss out on relayed messages, but those can usually be fetched anyway. Mastodon will throw away messages without signature.


You will also need to implement Webfinger, which is the mechanism that turns IDs into ActivityPub IDs. This was explicitly rejected by the AP standardizers, but as it’s rather obviously needed, you’ll have to implement it anyway.


Another thing you’ll have to implement is Mastodon’s visibility model. Mastodon signals post visibility by the adresses it puts into the to and cc fields of the activity. These visibility suggestions are not enforced by any encryption. Other servers are expected to respect them, but there’s no guarantee.

Mastodon has four visibily modes:

  • Public. This is signalled by having the special public address ( in the to field.
  • Unlisted. This is signalled by having the special public address in the cc field.
  • Private (aka “Friends Only”). This is signalled by NOT having the public address in the recipient fields, but having the user’s follower address in the to field.
  • Direct. This is signalled by having just the recipients’ IDs in the to field and NO public address.

You should probably implement your to and cc fields the same way, or your posts will look weird on Mastodon.


Following another user is a two part process in ActivityPub. First, you genereate a Follow activity and send it to the user you want to follow. This user will then respond with an Accept (or Reject) activity that has the ID of the Follow activity as its object.

Now, Mastodon doesn’t actually have activities internally, it just has a Status model that keeps post data. Because of that, Follows actually don’t have a real ID in Mastodon. This isn’t much of a problem for outgoing follows from Mastodon. They make up an ID according to some scheme (e.g.:, you use that in your Accept, and all is well.

The other way around is problematic though. Mastodon won’t save your Follow activity ID (because it doesn’t save the Follow activity) and will return an made up object ID in their Accept activity, which will look similar to the one above. You will have to work around this in your code somehow, or you won’t be able to follow people on Mastodon.

ActivityPub in Pleroma

With Pleroma, another former OStatus system is now capable of talking ActivityPub. For the first few weeks, expect some small federation problems from time to time, although those should be fixed fast. I’ve been running the AP branch on my servers for a few weeks now, and overall it’s fine.

Have fun sending pseudo-private messages around to your Mastodon friends now!