For the purpose of this document we will map the following concepts to the ActivityPub vocabulary in the following way:
An instance represents an Actor object on an ActivityPub service with the type
In the go-activitypub libraries, we use the following convention:
Service actor represents an ActivityPub capable server (for our use case, it is required for it to be C2S capable). Its inbox can be used as a global inbox for the other actors belonging to it.
Application actor represents a "frontend" to present the activitypub content to its users. It can be a web or standalone application.
An instance can belong to any of these two categories, but for the purpose of this document we will refer to the former as the "service" and to the later as the "instance".
A user represents an Actor on an ActivityPub service with the type
Person. Its lifetime is most likely related to the Instance, which represents the intermediary for creating, modifying and possibly removing the user.
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.
The moderation log is a list of activities that correspond to the following parameters:
Add(? to collection),
ActivityPub doesn't have the concept of a role that actors can fulfill. In the ActivityPub specification all actors can have the same behaviour, which is not limited in any way.
The only authorization related implication that can be deduced from the specification is that actors which are not part of an object's recipient list (and also, by convention, if the list does not include the Public ActivityStreams namespace) the actor can not view the object.
Outside of that there is no explicit mechanism of not allowing actors to operate
Undo, and other activity types with destructive side effects on other random activities or objects.
The common sense approach (which is already used in the go-activitypub 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.
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
Move it from the collection, or
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.
We chose to use tags to create these roles. The instance can then match them by their names (eg,
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 ActivityPub IRI.
The initial use cases for moderation are detailed here:
A user that is logged to an instance should be able to:
Blockother users, items, instances.
A user that is logged to an instance and has been tagged as
#moderator should be able to:
A user that is logged to an instance and has been tagged as a #sysop should be able to:
Rejectfollow requests from other instances.
#moderatorwhen viewing their ~user profile page.
Blockfor another instance.
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 them and can be used to actively moderate them.