Pleroma and Moderation, a brief history

A little over 2 years ago, Pleroma was started. At the time, Pleroma was largely developed by one person, and they were busy working toward a MVP. This lead to an interesting post being noted in dzuk's controversial blocklist advisory post.

Of course, time has moved on, and Pleroma has gained moderation tools that, in the hands of a skilled admin, provide the best possible moderation experience on the fediverse today. But getting to where we are now from 2 years ago has been a long journey.

moderator role

A few months after the post where lain said that he was still working on basic functionality, Pleroma got the first moderation tool around December 2017. You can set the moderator role on a user using the CLI:

$ MIX_ENV=prod mix pleroma.user set kaniini —moderator

Moderators have the ability to do a few things, namely delete any post from the local instance. For a while, this got the job done for most Pleroma instances because this was a reasonably quiet period of existence for the fediverse.

April 2018: birth of the Message Rewrite Facility

In April 2018, a new instance launched called Switter in response to the FOSTA/SESTA bill which unfairly targeted sex workers. This lead to some new problems in the fediverse, because largely the fediverse had never been exposed to an instance designed around advertising before. There were many cultural conflicts as well which lead to many fights during the launch.

Eventually, Switter modified Mastodon so that their posts would federate in a way that always ensured that media was always marked sensitive while not requiring their local users to mark their media sensitive, but this was a point of contention for several months.

In the meantime, the very first version of MRF was written and integrated into Pleroma, allowing for admins to force incoming posts from Switter to be unconditionally marked sensitive.

This version of MRF was very limited by comparison to the MRF we know today. For example, it only allowed one policy module to be loaded at any given time. It also did not implement a proper Elixir behaviour so that the compiler could validate the policy module for correctness. It did get the job done however.

May 2018: MRF begins to resemble the framework we have today

The original version of MRF was a minimal patch intended to allow instance admins to be able to block content from a configured set of instances, but the implementation lacked flexibility. href (the admin of came along and expanded upon my initial patch by allowing policies to be chained. This was a serious advancement in terms of enabling MRF to turn into the fully-fledged framework we enjoy today.

June 2018: Accept lists

Some instances on the fediverse operate on an accept list basis, where your server has to be explicitly granted permission to federate with the instance. An example of this would be

Based on a request, this functionality was added to Pleroma's MRF in June. This allows admins to set up an instance operating on an accept list basis without having to do any major changes in the code.

December 2018: Large thread filter

Extremely large threads (colloquially referred to as “hellthreads”) cause significant problems for resource consumption on instances and were abused by some people to be very annoying. [Pleroma implemented a large thread filter][mrf_hellthread] in the form of the mrf_hellthread module that blocked these threads based on a configurable threshold.

January 2019: Anti-followbot module

Followbots are unpopular among many users in the fediverse because they are perceived as being a data mining vector, or perhaps just downright creepy. At one point, they were necessary to help bootstrap new instances and get them well-federated, but this niche has been better solved through the use of relays. As a mitigation for these concerns, an anti-followbot mitigation was introduced to MRF.

February 2019: Keyword module, user tags and tag module

Sometimes it is necessary to mark posts as sensitive if they contain certain keywords. On most platforms, this work has to be done manually, and it can take up a lot of time. As a solution to this problem, a module which matches messages based on keywords was added.

We also added an API which allowed for users to be labelled with various classifiers. This was leveraged inside the MRF framework with a module that acted based on the presence of specific user tags.

April 2019: Pleroma FE integration, Reporting

In April, we added integration for the moderation tools exposed by MRF into Pleroma FE. This mostly consisted of tagging users with the appropriate tags using the user tagging API, but allows for efficient moderation work to be done.

We also added support for a report system which allows people to report spam and other TOS violations to their admins.


As can be seen, most initiatives involving moderation circle around the MRF framework and the future of the MRF framework is bright. We are already planning to rework the MRF framework after Pleroma 1.x release to make it more cleanly behaved. This work involves splitting MRF into classifiers, mutators and subchains.

The idea is that you have modules which detect if messages meet certain criterion, and if so, they attach classifiers to the message. Mutators then act on the message, making whatever modifications are requested. This flow is controlled by the use of conditional subchains: if classifier X is present, then process the message through subchain Y.

I'll be writing more about this design in the near future, but it is promising because it allows for backward compatibility with policy modules written against MRF today.