GoActivityPub library

Moderation using the vanilla ActivityPub vocabulary

Tag

By convention a tag represents an Object that doesn’t have a specific Type property. To scope a tag to a specific instance, we can use the tag’s URL property which should point to the instance’s host, or it’s “attributedTo” property which should point to the instance actor.

Moderation log

The moderation log is a list of activities that correspond to the following parameters:

moderation log screenshot

Issues with the vanilla ActivityPub model

ActivityPub doesn’t have the concept of a role that actors can fulfill. In the ActivityPub specification all actors have the same behaviour: they can POST json(+ld) encoded Activities to collections.

The only authorization related implication that can be deduced - only deduced, because it’s not explicitly stated anywhere - from the specification is that actors which are not part of an object’s recipient list (and also, by convention, if said list does not include the Public ActivityStreams namespace) the actor can not view the object.

Outside of this fact there are no explicit mechanisms of forbidding actors to operate Update, Delete, Remove, Undo, and other activity types with destructive side effects on random activities or objects.

The common sense approach (which is already used in the GoActivityPub libraries, and pretty much in all other ActivityPub enabled services out there) is to limit the operation of these activities just for the actors which are “owning” the respective objects and activities.

Ownership

An actor can be said to be the owner of an activity or object if it can be found in the “actor” and “attributedTo” properties of an Activity, or in the “attributedTo” property of an Object.

However, based on the fact that ActivityPub is a federated ecosystem, besides the normative representation of an activity (which resides in the outbox of its creator) all recipients receive copies, of which it can be said that they own.

So based on this premise we can safely say that an actor “owns” all the activities that exist (as copies) in their inbox.

We can take it a little further and say that an actor owns any activity or object that is stored in a collection belonging to them, and as such can effect activities that manipulate those items in said collection.

This means they can Add/Remove/Move it from the collection, or Update, Delete it.

Solution

Due to the restrictions detailed in the previous paragraphs we need to find a way to create and assign roles for actors using a mechanism relying on the ActivityPub vocabulary but not intrinsic to the specification.

In BrutaLinks we have chosen to use tags to create these roles, so the members of the moderation team can be recognized by two such tags: #sysop and #mod.

As tags can be easily created by anyone (because they are simple objects) we need to ensure they are scoped for a single instance, and for this we can use either the URL matching mechanism for the instance’s host, or some more elaborate methods using the “attributedTo” property which should point to the instance’s actor ActivityPub ID.

Use cases

The scenarios for how moderation works are as follows:

Moderation request

Any user that is logged to an instance should be able to:

Moderation followup

A user that is logged to an instance and has been tagged as #mod should be able to:

Instance administration

A user that is logged to an instance and has been tagged as a #sysop should be able to:

Technical details about moderation

As we don’t want to rely on extensions to the specification for moderating ActivityPub content, we must ensure that at least one of the actors involved in the interactions we are planning will have onwership over the activities involved.

The best choice for this is probably the instance’s application actor.

This means that we need to build all of the operations we detailed in the “Use cases” section in such a way that the instance actor retains ownership over the created objects and can be used to actively moderate them.