|
|
|
# MSC2313: Moderation policies as rooms (ban lists)
|
|
|
|
|
|
|
|
Matrix is an open network and anyone can participate in it. As a result, a
|
|
|
|
very wide range of content exists, and it is important to empower users to be
|
|
|
|
able to select which content they wish to see, and which they wish to block. By
|
|
|
|
extension, room moderators and server admins should also be able to select
|
|
|
|
which content they do not wish to host in their rooms and servers.
|
|
|
|
|
|
|
|
The protocol's position in this solution should be one of neutrality: it
|
|
|
|
should not be deciding what content is undesirable for any particular entity and
|
|
|
|
should instead be empowering those entities to make their own decisions. This
|
|
|
|
proposal introduces "moderation policy rooms" as a basic mechanism to help users
|
|
|
|
manage this process, by providing a way of modelling sets of servers, rooms and users
|
|
|
|
which can then be used to make filtering decisions. This proposal makes no
|
|
|
|
attempt at interpreting the model and actually making those decisions however.
|
|
|
|
|
|
|
|
To reaffirm: where this proposal says that some content is undesirable it does not intend to
|
|
|
|
bias the reader into what that could entail. Undesirability is purely in the hands of the
|
|
|
|
entity perceiving the content. For example, someone who believes birthday cake is undesirable
|
|
|
|
is perfectly valid in taking that position and is encouraged by this proposal to set up or
|
|
|
|
use a policy room which prevents birthday cake from coming across their field of view.
|
|
|
|
|
|
|
|
## Proposal
|
|
|
|
|
|
|
|
Moderation policy lists, also known as ban lists in this proposal, are stored as room state events,
|
|
|
|
allowing for structures and concepts to be reused without defining a new room version. This
|
|
|
|
proposal does not make any restrictions on how the rooms are configured, just that the state
|
|
|
|
events described here are represented in a room. For example, a room which is invite only is
|
|
|
|
just as valid as a room that is not: the important details are specific state events and not
|
|
|
|
the accessibility, retention, or other aspects of the room.
|
|
|
|
|
|
|
|
Ban lists are stored as `m.policy.rule.<kind>` state events, with state keys being arbitrary IDs
|
|
|
|
assigned by the sender. The `<kind>` is currently one of `user`, `room`, and `server`. Three
|
|
|
|
fields are defined in `content`:
|
|
|
|
|
|
|
|
* `entity` (`string`) - **Required.** The entity/entities the recommendation applies to. Simple globs are supported
|
|
|
|
for defining entities (`*` and `?` as wildcards, just like `m.room.server_acl`).
|
|
|
|
* `recommendation` (`enum`) - **Required.** The action subscribed entities should take against
|
|
|
|
the described entity. Currently only `m.ban` is defined (see below).
|
|
|
|
* `reason` (`string`) - **Required.** The human-readable description for the recommendation.
|
|
|
|
|
|
|
|
Invalid or missing fields are to be treated as though the rule doesn't exist. This is to
|
|
|
|
allow for rules to be deleted while state events cannot be deleted in Matrix.
|
|
|
|
|
|
|
|
An example set of minimal state events for banning `@alice:example.org`, `!matrix:example.org`,
|
|
|
|
`evil.example.org`, and `*.evil.example.org` would be:
|
|
|
|
|
|
|
|
```json
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"type": "m.policy.rule.user",
|
|
|
|
"state_key": "rule_1",
|
|
|
|
"content": {
|
|
|
|
"entity": "@alice:example.org",
|
|
|
|
"recommendation": "m.ban",
|
|
|
|
"reason": "undesirable behaviour"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"type": "m.policy.rule.room",
|
|
|
|
"state_key": "rule_2",
|
|
|
|
"content": {
|
|
|
|
"entity": "!matrix:example.org",
|
|
|
|
"recommendation": "m.ban",
|
|
|
|
"reason": "undesirable content"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"type": "m.policy.rule.server",
|
|
|
|
"state_key": "rule_3",
|
|
|
|
"content": {
|
|
|
|
"entity": "evil.example.org",
|
|
|
|
"recommendation": "m.ban",
|
|
|
|
"reason": "undesirable engagement"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"type": "m.policy.rule.server",
|
|
|
|
"state_key": "rule_4",
|
|
|
|
"content": {
|
|
|
|
"entity": "*.evil.example.org",
|
|
|
|
"recommendation": "m.ban",
|
|
|
|
"reason": "undesirable engagement"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
|
|
|
When the entity is a room, it can be a room alias or ID - the subscriber is responsible for
|
|
|
|
resolving it to a room ID (if it wants to).
|
|
|
|
|
|
|
|
Non-standard recommendations are permitted using the Java package naming convention for
|
|
|
|
namespacing. A `recommendation` is just a recommendation: how implementations apply the rules
|
|
|
|
is left as a concern for those implementations. The only standard `recommendation` currently
|
|
|
|
defined is `m.ban`: The `entity` should be banned from participation where possible.
|
|
|
|
|
|
|
|
The enforcement mechanism of `m.ban` is deliberately left as an implementation detail to avoid the
|
|
|
|
protocol imposing its opinion on how the lists are interpreted. However, a suggestion for
|
|
|
|
a simple implementation is as follows:
|
|
|
|
|
|
|
|
* Is a user...
|
|
|
|
* Applied to a user: The user should be added to the subscriber's ignore list.
|
|
|
|
* Applied to a room: The user should be banned from the room (either on sight or immediately).
|
|
|
|
* Applied to a server: The user should not be allowed to send invites to users on the server.
|
|
|
|
* Is a room...
|
|
|
|
* Applied to a user: The user should leave the room and not join it
|
|
|
|
([MSC2270](https://github.com/matrix-org/matrix-doc/pull/2270)-style ignore).
|
|
|
|
* Applied to a room: No-op because a room cannot ban itself.
|
|
|
|
* Applied to a server: The server should prevent users from joining the room and from receiving
|
|
|
|
invites to it (similar to the `shutdown_room` API in Synapse).
|
|
|
|
* Is a server...
|
|
|
|
* Applied to a user: The user should not receive events or invites from the server.
|
|
|
|
* Applied to a room: The server is added as a denied server in the ACLs.
|
|
|
|
* Applied to a server: The subscriber should avoid federating with the server as much as
|
|
|
|
possible by blocking invites from the server and not sending traffic unless strictly
|
|
|
|
required (no outbound invites).
|
|
|
|
|
|
|
|
Other entities could be represented by this recommendation as well, however as per the
|
|
|
|
introduction to this proposal they are strictly out of scope. An example would be an integration
|
|
|
|
manager which doesn't want to offer integrations to banned entities - this is an implementation
|
|
|
|
detail for the integration manager to solve.
|
|
|
|
|
|
|
|
A new event type is introduced here instead of reusing existing events (membership, ACLs, etc)
|
|
|
|
because the implication of a recommendation/rule is less clear when using the more narrow-scoped
|
|
|
|
events. For example, a philosophical question arises over what a `membership` of `ban` means to a server
|
|
|
|
subscribed to the list. More questions get raised when the `membership` of a user isn't `ban`,
|
|
|
|
but is `join` or similar instead - if the subscriber was mirroring events, it would be inclined
|
|
|
|
to try and sync membership lists, which this proposal attempts to avoid by using a more generic
|
|
|
|
and neutral event type.
|
|
|
|
|
|
|
|
How subscriptions to ban lists are handled is also left as an implementation
|
|
|
|
detail (to avoid unnecessarily blocking progress on this MSC). The subscriber
|
|
|
|
could be anything that speaks Matrix, therefore this proposal makes no attempt
|
|
|
|
to describe how this should work for everything. Some ideas for how this could
|
|
|
|
be implemented include joining the ban list room to watch for updates and
|
|
|
|
applying them automatically, however there is no requirement that the
|
|
|
|
subscriber needs to join the room: they could peek or poll at an interval
|
|
|
|
instead, which is just as valid.
|
|
|
|
|
|
|
|
To ease sharing of these ban list rooms, a system very similar to [MSC1951's sharable URLs](
|
|
|
|
https://github.com/matrix-org/matrix-doc/pull/1951/files#diff-4ee6ed0ee1f2df73efac5fa9a9835642R50-R70)
|
|
|
|
is defined. There are two ways to share the ban list: a link to the room as one would when
|
|
|
|
sharing any reference to any other room ("please add `#bans:example.org` to your block list"),
|
|
|
|
or by using plain `http` or `https` URLs. Just like in MSC1951, the URL when approached with
|
|
|
|
a `Accept: application/json` header or has `.json` appended to the end of the URL should return
|
|
|
|
a `room_uri` which is a reference to the ban list room. Currently, the reference would be a
|
|
|
|
`matrix.to` URI, however in the future this could be a `mx://` or similar URL. When not approached
|
|
|
|
with the intent of JSON, the service could return a user-friendly page describing what is included
|
|
|
|
in the ban list.
|
|
|
|
|
|
|
|
## Future considerations
|
|
|
|
|
|
|
|
This proposal notably does not define specific behaviour for AI or machine learning applications.
|
|
|
|
Implementations are currently able to apply AI/ML to their systems if they see fit (for example,
|
|
|
|
spam detection or undesirable content being uploaded), however no specification is proposed
|
|
|
|
here to make the interaction standardized.
|
|
|
|
|
|
|
|
This proposal additionally does not describe how a server could subscribe to a ban list: this
|
|
|
|
is left for the server to figure out (possibly by using a utility user account?) potentially
|
|
|
|
with the support of other proposals, such as [MSC1777](https://github.com/matrix-org/matrix-doc/pull/1777).
|
|
|
|
|
|
|
|
Further work on reputation systems could enhance ban lists by adding additional metrics to
|
|
|
|
assert their validity. This proposal assumes social trust ("don't use it if you
|
|
|
|
don't trust the creator") over verifiable/provable trust - a future proposal can easily add
|
|
|
|
such systems to these ban lists.
|
|
|
|
|
|
|
|
This proposal intentionally does not handle how a server could assist the user in preventing
|
|
|
|
undesirable content or subscribing to ban lists. Users already have some tools at their disposal,
|
|
|
|
such as being able to ignore other users, and are encouraged to make use of those first. Other
|
|
|
|
proposals are encouraged to specify what additional tools might look like to better handle
|
|
|
|
ban lists.
|
|
|
|
|
|
|
|
Media (uploaded content) is not handled by this proposal either. This is a concern left for
|
|
|
|
other proposals like [MSC2278](https://github.com/matrix-org/matrix-doc/pull/2278) and
|
|
|
|
[MSC701](https://github.com/matrix-org/matrix-doc/issues/701).
|
|
|
|
|
|
|
|
## Security considerations
|
|
|
|
|
|
|
|
Using this solution one can build a social system of shared blacklists, which
|
|
|
|
may create a divide within established communities if not carefully deployed.
|
|
|
|
This may well not be a suitable answer for all communities.
|
|
|
|
|
|
|
|
Depending on how the implementations handle subscriptions, user IDs may be linked to ban
|
|
|
|
lists and therefore expose the views of that user. Using the example from the introduction,
|
|
|
|
if a user who does not like birthday cake were to join the ban list room for blocking
|
|
|
|
birthday cake, that user's preference would be exposed to any other observers of that ban
|
|
|
|
list. Proposals like [MSC1228](https://github.com/matrix-org/matrix-doc/issues/1228) and
|
|
|
|
[MSC1777](https://github.com/matrix-org/matrix-doc/pull/1777) could help solve this.
|
|
|
|
|
|
|
|
## Implementation notes
|
|
|
|
|
|
|
|
This proposal is partially implemented by [mjolnir](https://github.com/matrix-org/mjolnir)
|
|
|
|
using the `org.matrix.mjolnir.*` namespace until this becomes stable. This results in
|
|
|
|
the following mappings:
|
|
|
|
|
|
|
|
* `m.policy.rule.user` => `org.matrix.mjolnir.rule.user`
|
|
|
|
* `m.policy.rule.room` => `org.matrix.mjolnir.rule.room`
|
|
|
|
* `m.policy.rule.server` => `org.matrix.mjolnir.rule.server`
|
|
|
|
* `m.ban` => `org.matrix.mjolnir.ban`
|