How, if at all, can we achieve federated roles with permissions?

Right now, instances use various systems to decide how to assign permissions to users. It’s hard to standardize permissions, as it’s not clear (1) what permissions should exist and (2) how to make other instances aware of those permissions.

I’m especially curious about how you might implement a role-based access control system in a fediverse instance. I know that Mastodon has a concept of roles and permissions, but none of the permissions have anything to do with any federated content, so a Mastodon instance does not need to worry about making other instances aware of its roles or permissions. It is essentially local-only roles/permissions.

Lemmy uses a very coarse system where roles are pre-defined with pre-defined permissions - there are site-wide administrators, who are essentially moderators in all communities, and then there are moderators that only have powers within a single community.

Lemmy uses the attributedTo field on Groups to indicate the mods to other instances. For example, https://feddit.dk/c/fedditdk’s attributedTo field points to https://feddit.dk/c/fedditdk/moderators which is an ordered collection of actors (users). This is actually part of the Group Federation FEP.

There is also an example of making permissions available to other instances. In Lemmy, moderators may “lock” a community to make it so that only moderators can post in that community. This is communicated to other instances via a postingRestrictedToMods field on the community actor. Other Lemmy instances detect this field and prevent their local users from posting in the community. This field does not seem to be standardized in any FEPs though, AFAIK.

However, this system feels brittle and “hardcoded”. For example, Mastodon seems to not know anything about the attributedTo field containing the community moderators (AFAICT), nor does it seem to check the postingRestrictedToMods field (to be clear I don’t blame or expect Mastodon for this).

I assume that if a Mastodon user tried to post to a community where postingRestrictedToMods == true, that the toot would appear locally and might even be federated to the poster’s followers, but the remote instance where the group lives would reject the toot and would not federate it to the group followers. This results in inconsistent states between various services. This seems undesirable.

How could we resolve this situation, if at all? It doesn’t seem viable to continue using very coarse, pre-defined roles and permissions, like Lemmy currently does. Then again, it seems impossible for instances to communicate permissions if we do not agree on a standard of what permissions exist and how permissions are assigned to users (i.e. via roles for example).

In the ideal world that I am imagining, it would be possible for a fediverse group (like a Lemmy community) to define its own roles, assign each role permissions (where the permissions are a set of pre-determined agreed-upon standard permissions across the fediverse) and assign each user with roles, and these roles, permissions and role assignments would be communicated somehow to other instances, so there is a shared understanding of the permissions for a user and group.

However, the devil is in the details. I would love to hear your thoughts, potential problems, pitfalls or whether you think this is possible at all.

1 Like

Idunno, a FEP that retro-specifies a few coarse-grained permissions for BROAD interop (say, non-thread interop for Mastodon and Misskey and the like) doesn’t have to be either/or with more fine-grained (and per-instance configurable) permissions Discord style. I think having AP-wide support for the latter might be a fool’s errand, and having different levels of support within and beyond the Threaded world developed in parallel by the same group is probably a good precedent to set…

I’m not sure if roles should be federated, but permissions definitely should be and there’s a growing amount of different proposals and implementations. For example, reply permissions: FEP-5624: Per-object reply control policies

I don’t think 5624 deals with permissions in the same sense as what is being discussed above with RBAC. There’s a difference between something like canReply as a signal ahead-of-time that your reply will likely be added or not, vs. something dynamic that allows managing when an action is allowed or not.

More generally, you could do this with either ACL type stuff WebAccessControl - W3C Wiki for at least read write append cases, or if you wanted to be robust, then an object capability system where for example you require an Authorization header with a certain bearer token in order to consider the activity valid. But the latter also means you have to spec out a token management system, in-band or out-of-band.

I guess a fundamental problem is that, even if you write an FEP to try to specify some kind of standard permissions and a way to communicate permissions for users (whether that be through roles or whatever), you’ll still have the issue of instances that do not implement the FEP and will thus be totally unaware of any restricted permissions, which will lead to inconsistent states between instances anyway (since the instance implementing the permission will reject the action while the non-implementing instances will accept the action).

In that way it kinda feels hopeless to try to retrofit anything onto ActivityPub for this purpose - it feels like it must have been part of the core spec for it to work. Or am I missing something and is there a way to make this work?

The way I imagine such an FEP would be to define a standard set of permissions. Perhaps it would be possible to specify something quite generic, like a permission essentially being “an Actor with this permission is allowed to send an Activity satisfying this predicate”. In that way, you could imagine the ability to encode lots of different types of permissions and depending on how you specify the predicate, you may not even have to make a list of all permissions.

I wonder if it would be possible to use JSON Schemas for this somehow? Like any Activity that an actor is allowed to produce is specified by a JSON Schema which specifies how the Activity may look. Like using the Schema to specify that the content field may only be up to a certain length or that the type of Activity may only be certain options. But I’m not sure JSON Schema is rich enough to encompass all the kinds of permissions that you would like to encode.

But anyways as I said at first, not sure if even trying to do this makes sense considering the presence of non-implementing instances.

It’s difficult to prevent actor from generating an activity, but you can make an object that represents a result of activity (or a set of activities) and enforce permissions there.

For example, replies collection. Anyone can generate a Note with inReplyTo property, but original post author can control the contents of replies collection.

I was referring mainly to the discussion surrounding FEP-5624, which seems relevant.

Two things:

  1. Describing the shape of activities is probably better done via SHACL. I’m leaving the exact semantics and purpose of those shapes as out-of-scope, because there are several things you could do with these shapes — this all depends on the predicate used to link between the subject and object

  2. In an open world system, you have to think about “permissions” completely differently. There will be conflicts, of course. You can only control what is in your authority and what you claim. Anyone else can claim anything they want. And anyone else is free to ignore your claims entirely as well. There is no technical solution to this; the solution is conventional. For example, if posting is restricted to mods, then all you can do is maintain a collection of posts that are valid according to you, with the expectation that anyone who cares can check that collection. Of course, they are free to not care for the contents of the collection.