mirror of
https://codeberg.org/fediverse/fep.git
synced 2026-08-09 05:56:10 +00:00
FEP-5219: Groups and permissions (#859)
Reviewed-on: https://codeberg.org/fediverse/fep/pulls/859
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
---
|
||||
slug: "5219"
|
||||
authors: silverpill <@silverpill@mitra.social>
|
||||
type: implementation
|
||||
status: DRAFT
|
||||
discussionsTo: https://codeberg.org/silverpill/feps/issues
|
||||
dateReceived: 2026-06-11
|
||||
---
|
||||
# FEP-5219: Groups and permissions
|
||||
|
||||
## Summary
|
||||
|
||||
This document describes a permission system for [ActivityPub] groups.
|
||||
|
||||
It is inspired by [XEP-0045: Multi-User Chat][XEP-0045], which defines a comprehensive permission system for XMPP group chats.
|
||||
|
||||
## Motivation
|
||||
|
||||
The most widely used ActivityPub group implementation is described in [FEP-1b12 (Group federation)][FEP-1b12]. That document was focused on public groups, and private FEP-1b12 groups were later proposed in [Lemmy RFC-0005 (Private Communities)][LemmyRFC-0005]. However, the mechanism for controlling user permissions in such groups has not been clearly defined.
|
||||
|
||||
This FEP formalizes the mechanisms that are already used in FEP-1b12 groups, and extends them to accommodate new group types, such as semi-private groups and group chats. The proposed permission system can also be used in other contexts, such as when designating server moderators or establishing organizational hierarchies.
|
||||
|
||||
## Requirements
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC-2119].
|
||||
|
||||
## Affiliation
|
||||
|
||||
**Affiliation** is a long-lived association with a group.
|
||||
|
||||
The default set of affiliations includes:
|
||||
|
||||
- `admin` - an actor who has all possible privileges.
|
||||
- `moderator` - an actor who can remove posts and other actors from a group.
|
||||
- `member` - an actor who has only the basic privileges.
|
||||
- `outcast` - an actor who was banned from a group.
|
||||
|
||||
This list is not exhaustive, and implementations MAY support additional affiliations if necessary. It is also possible to have no affiliation with a group.
|
||||
|
||||
The group actor itself is considered to have an `admin` affiliation.
|
||||
|
||||
Affiliations can be specified using the `affiliations` collection attached to a `Group` actor. It is an ordered collection where each item is a `Relationship` object that represents a relationship between a user and a group. This object has the following fields:
|
||||
|
||||
- `type`: the `Relationship` string.
|
||||
- `subject`: the identifier of an actor.
|
||||
- [`relationship`](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-relationship-term): the affiliation name (`admin`, `moderator`, `member`, `outcast` or a custom affiliation identifier).
|
||||
|
||||
The `affiliations` collection is sorted from most privilege to least privilege.
|
||||
|
||||
When adding a `Relationship` for a custom affiliation, a fallback representation SHOULD also be included. This fallback representation MUST specify an affiliation from the default set that has equal or fewer privileges compared to the custom affiliation.
|
||||
|
||||
Consumers MUST ignore relationships that represent unsupported affiliations.
|
||||
|
||||
The `affiliations` collection supersedes the collection of moderators defined in [FEP-1b12]. Consumers MUST read the `affiliations` collection when both collections are present.
|
||||
|
||||
Example of an `affiliations` collection:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "https://social.example/group/affiliations",
|
||||
"type": "OrderedCollection",
|
||||
"attributedTo": "https://social.example/group",
|
||||
"items": [
|
||||
{
|
||||
"type": "Relationship",
|
||||
"subject": "https://social.example/alice",
|
||||
"relationship": "admin"
|
||||
},
|
||||
{
|
||||
"type": "Relationship",
|
||||
"subject": "https://social.example/bob",
|
||||
"relationship": "member"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The collection is modified using `Add` and `Remove` activities. They have the following properties:
|
||||
|
||||
- `object`: an embedded `Relationship` object.
|
||||
- `target`: the identifier of the `affiliations` collection.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "https://social.example/activities/1",
|
||||
"type": "Add",
|
||||
"object": {
|
||||
"type": "Relationship",
|
||||
"subject": "https://social.example/bob",
|
||||
"relationship": "member"
|
||||
},
|
||||
"target": "https://social.example/group/affiliations",
|
||||
"to": [
|
||||
"https://social.example/group/followers"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Participation
|
||||
|
||||
**Participation** refers to the ability to read or write to a group.
|
||||
|
||||
There are two levels of participation:
|
||||
|
||||
- `follower` - someone who reads group activities.
|
||||
- `participant` - someone who creates activities in a group.
|
||||
|
||||
The participation status is distinct from affiliation. Affiliations MAY be preserved when users leave and re-join the group.
|
||||
|
||||
A group where anyone can participate is a **public group**.
|
||||
|
||||
A group where only members can participate is a **private group**.
|
||||
|
||||
A group which anyone can follow but where only members can participate is a **semi-private group**.
|
||||
|
||||
Group actors MUST have a `followers` property pointing to the collection of group followers.
|
||||
|
||||
Semi-private group actors MUST have a `participants` property pointing to the collection of group participants. In public and private groups, the collection of participants is identical to the collection of followers.
|
||||
|
||||
## Privileges
|
||||
|
||||
| Privilege | Activity | Admin | Moderator | Member | None | Outcast |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Follow a public group | `Follow` | Yes | Yes | Yes | Yes | No |
|
||||
| Participate in a public group | - | Yes | Yes | Yes | Yes | No |
|
||||
| Follow a semi-private group | `Follow` | Yes | Yes | Yes | Yes | No |
|
||||
| Participate in a semi-private group | `Join` | Yes | Yes | Yes | No | No |
|
||||
| Follow a private group | `Join` or `Follow` | Yes | Yes | Yes | No | No |
|
||||
| Participate in a private group | `Join` or `Follow` | Yes | Yes | Yes | No | No |
|
||||
| Remove posts of other participants | `Delete` | Yes | Yes | No | No | No |
|
||||
| Remove participants | `Reject` | Yes | Yes | No | No | No |
|
||||
| Ban participants | `Block` | Yes | Yes | No | No | No |
|
||||
| Add or remove members | `Add` or `Remove` | Yes | Yes | No | No | No |
|
||||
| Add or remove moderators | `Add` or `Remove` | Yes | No | No | No | No |
|
||||
| Update group metadata | `Update` | Yes | No | No | No | No |
|
||||
|
||||
This list of privileges is not exhaustive. Additional privileges MAY be associated with the affiliations from the default set.
|
||||
|
||||
## Activities
|
||||
|
||||
Group activities (such as [FEP-1b12] `Announce` activities) MUST be addressed to the group's `followers` collection or to its `participants` collection.
|
||||
|
||||
Recipients of a group activity SHOULD resolve the group's `affiliations` collection.
|
||||
|
||||
All participants are allowed to update and delete their own posts, and to remove themselves from the group. Actions that affect other participants MAY be authorized if the actor has the necessary privileges.
|
||||
|
||||
## References
|
||||
|
||||
- Christine Lemmer-Webber, Jessica Tallon, Erin Shepherd, Amy Guy, Evan Prodromou, [ActivityPub], 2018
|
||||
- S. Bradner, [Key words for use in RFCs to Indicate Requirement Levels][RFC-2119], 1997
|
||||
- Peter Saint-Andre, [XEP-0045: Multi-User Chat][XEP-0045], 2002
|
||||
- Felix Ableitner, [FEP-1b12: Group federation][FEP-1b12], 2022
|
||||
- Nutomic, [Private Communities][LemmyRFC-0005], 2024
|
||||
|
||||
[ActivityPub]: https://www.w3.org/TR/activitypub/
|
||||
[RFC-2119]: https://datatracker.ietf.org/doc/html/rfc2119
|
||||
[XEP-0045]: https://xmpp.org/extensions/xep-0045.html
|
||||
[FEP-1b12]: https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md
|
||||
[LemmyRFC-0005]: https://github.com/LemmyNet/rfcs/blob/main/0005-private-communities.md
|
||||
|
||||
## Copyright
|
||||
|
||||
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
||||
|
||||
To the extent possible under law, the authors of this Fediverse Enhancement Proposal have waived all copyright and related or neighboring rights to this work.
|
||||
Reference in New Issue
Block a user