MSC: Policy Servers
parent
a9153d8ef3
commit
8435393c5b
@ -1,5 +0,0 @@
|
||||
# MSC4284: PLACEHOLDER
|
||||
|
||||
An MSC number is needed for an experiment. This MSC is holding that number.
|
||||
|
||||
Details will follow soon (if the experiment is successful).
|
||||
@ -0,0 +1,189 @@
|
||||
# MSC4284: Policy Servers
|
||||
|
||||
**Note**: The concepts and architecture proposed by this MSC are rapidly iterating and will change.
|
||||
Review is appreciated with the understanding that absolutely nothing is set in stone. Where security
|
||||
issues are present, please use the [Security Disclosure Policy](https://matrix.org/security-disclosure-policy/)
|
||||
rather than leaving inline comments. This is to ensure application integrity for those opting to use
|
||||
highly experimental and changing implementations of this proposal.
|
||||
|
||||
Communities on Matrix are typically formed through [Spaces](https://spec.matrix.org/v1.14/client-server-api/#spaces),
|
||||
but can be made up of singular rooms or loose collections of rooms. These communities often have a
|
||||
desire to push unwelcome content out of their chats, and rely on bots like [Mjolnir](https://github.com/matrix-org/mjolnir),
|
||||
[Draupnir](https://github.com/the-draupnir-project/Draupnir), and [Meowlnir](https://github.com/maunium/meowlnir)
|
||||
to help manage their community. Many of these communities have additionally seen a large increase in
|
||||
abusive content being sent to their rooms recently. While these existing tools allow for reactive
|
||||
moderation (redactions after the fact), some impacted communities may benefit from having an option
|
||||
to use a server of their choice to automatically filter events at a server level, reducing the spread
|
||||
of abusive content. This proposal experiments with this idea, calling the concept *Policy Servers*.
|
||||
|
||||
This proposal does not seek to replace community management provided by the existing moderation bots,
|
||||
but does intend to supplement a large part of the "protections" concept present in many of these bots
|
||||
to the room's designated policy server.
|
||||
|
||||
At a high level, policy servers are *optional* recommendation systems which help proactively moderate
|
||||
communities on Matrix. Communities which elect to use a policy server advertise their choice through
|
||||
state events in individual rooms, and homeservers in the room may reach out to the chosen server for
|
||||
opinions on how to handle local and remote events *before* those events are delivered to their users.
|
||||
The functional role of being a policy server may be implemented by a dedicated server, typically
|
||||
optimized for moderation, or integrated within a homeserver implementation.
|
||||
|
||||
In the general case, a homeserver which honours a policy server's recommendation to flag an event as
|
||||
spam would [soft fail](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) remote events
|
||||
and reject local events to avoid delivering them to users. Servers which don't honour those recommendations
|
||||
may see redactions issued by a server/user in the room to help protect those users too, much as the
|
||||
moderation bots listed above already do today.
|
||||
|
||||
This tooling is entirely optional, and decided upon by the room/community itself, similar to moderation
|
||||
bots. The specific filtering behaviour is left as an implementation detail, and is expected to be
|
||||
configurable by the community using the policy server. Some examples may include preventing images
|
||||
from being sent to their rooms, disallowing lots of messages from being sent in a row, and limiting
|
||||
the number of mentions a user can make.
|
||||
|
||||
While there isn't anything which prevents policy servers from operating in private or encrypted rooms,
|
||||
the intended audience is public (or near-public) rooms and communities. Most communities may not need
|
||||
a policy server and can instead rely on moderation bots or other forms of moderation. Those which do
|
||||
decide to use a policy server may find that they have it disabled or in a low power state most of the
|
||||
time.
|
||||
|
||||
## Proposal
|
||||
|
||||
**This is a work in progress.**
|
||||
|
||||
A *Policy Server* (PS) is a server which implements the newly-defined `/check` API described below.
|
||||
This may be an existing logical server, such as matrix.org, or a dedicated host which serves no other
|
||||
purpose.
|
||||
|
||||
Rooms which elect to use a policy server would do so via the new `m.room.policy` state
|
||||
event (empty state key). The `content` would be something like:
|
||||
|
||||
```json5
|
||||
{
|
||||
"via": "policy.example.org"
|
||||
}
|
||||
```
|
||||
|
||||
**TODO**: Array for multiple policy servers?
|
||||
|
||||
Provided `policy.example.org` is in the room, that server receives events as any other homeserver
|
||||
in the room would, *plus* becomes a Policy Server. If `policy.example.org` is not in the room, the
|
||||
assignment acts as though it was undefined: the room does not use a policy server.
|
||||
|
||||
If a policy server is in use by the room, homeservers SHOULD call the `/check` API defined below on
|
||||
all locally-generated events before fanning them out and on all remote events before delivering them
|
||||
to local users. If the policy server recommends treating the event as spam, the event SHOULD be soft
|
||||
failed if remote and rejected if local. This means local users should encounter an error if they
|
||||
attempt to send "spam" (by the policy server's definition), and events sent by remote users will
|
||||
never make it to a local user's client. If the policy server recommends allowing the event, the event
|
||||
should pass unimpeded.
|
||||
|
||||
For Synapse homeservers, the above paragraph's consequences are natural behaviour of the spam checker
|
||||
module feature. A server could, with some performance penalty, deploy a module which calls the `/check`
|
||||
API to enact the consequences described above.
|
||||
|
||||
The new `/check` is described as follows:
|
||||
|
||||
```
|
||||
POST /_matrix/policy/v1/event/:eventId/check
|
||||
Authorization: X-Matrix ...
|
||||
Content-Type: application/json
|
||||
|
||||
{PDU-formatted event}
|
||||
```
|
||||
|
||||
The request body is *optional* but *strongly recommended* for efficient processing, as the policy
|
||||
server may not make efforts to locate the event over federation, especially during `/check`.
|
||||
|
||||
Authentication is achieved using normal [Federation API request authentication](https://spec.matrix.org/v1.14/server-server-api/#request-authentication).
|
||||
|
||||
Requests may be rate limited, but SHOULD have relatively high limits given event traffic.
|
||||
|
||||
The endpoint always returns `200 OK`, unless rate limited or a server-side unexpected error occurred.
|
||||
If the request shape is invalid, the policy server SHOULD respond with a `spam` recommendation, as
|
||||
shown below. If the event (or room) is not known to the policy server, it is left as an implementation
|
||||
detail for whether to consider that event as `spam` or `ok`.
|
||||
|
||||
```
|
||||
200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{"recommendation": "spam"}
|
||||
```
|
||||
|
||||
```
|
||||
200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{"recommendation": "ok"}
|
||||
```
|
||||
|
||||
```
|
||||
429 Rate Limited
|
||||
Content-Type: application/json
|
||||
|
||||
{"error":"Too many requests","errcode":"M_RATE_LIMITED"}
|
||||
```
|
||||
|
||||
```
|
||||
500 Internal Server Error
|
||||
Content-Type: application/json
|
||||
|
||||
{"error":"It broke","errcode":"M_UNKNOWN"}
|
||||
```
|
||||
|
||||
**TODO**: Figure out a way to expose which filters (if any) caused an event to be flagged as spam, to
|
||||
allow for more nuanced decision making by servers/bots. Also, if exposed, figure out a way to do so
|
||||
which doesn't expose that detail to potential attackers. Consider exposing with score metrics per filter.
|
||||
|
||||
As shown, `recommendation` may either be `spam` or `ok`. (**TODO**: Consider different keywords)
|
||||
|
||||
**TODO**: Support namespaced identifiers in an array for more recommendations? ie: `[ok, org.example.warn_user]`
|
||||
|
||||
Homeserver implementations SHOULD fail safely and assume events are *not* spam when they cannot reach
|
||||
the policy server. However, they SHOULD also attempt to retry the request for a reasonable amount of
|
||||
time.
|
||||
|
||||
In some implementations, a homeserver may cooperate further with the policy server to issue redactions
|
||||
for spammy events, helping to keep the room clear for users on servers which didn't check with the
|
||||
policy server ahead of sending their event(s). For example, `matrix.example.org` may have a user in
|
||||
the room with permission to send redactions and `/check`s all events.
|
||||
|
||||
## Potential issues
|
||||
|
||||
**TODO**: This section.
|
||||
|
||||
Broadly:
|
||||
* Lack of batching is unfortunate (**TODO**: Fix this)
|
||||
|
||||
## Safety considerations
|
||||
|
||||
**TODO**: This section.
|
||||
|
||||
## Security considerations
|
||||
|
||||
**TODO**: This section.
|
||||
|
||||
## Alternatives
|
||||
|
||||
**TODO**: This section. Many of the inline TODOs describe some alternatives.
|
||||
|
||||
An alternative was considered where, in a future room version, all events must be signed by the policy
|
||||
server before they're able to be added to the DAG. However, this results in compulsory centralization
|
||||
and usage, removing the room's agency to choose which moderation tools they utilize and that room's
|
||||
ability to survive network partitions. This alternative does have an advantage of reducing bandwidth
|
||||
spend across the federation (as there's no point in sending a spammy event if the policy server won't
|
||||
sign it), but would require that communities upgrade their rooms to a compatible room version, which
|
||||
typically take significant time to specify and deploy.
|
||||
|
||||
## Unstable prefix
|
||||
|
||||
While this proposal is not considered stable, implementations should use the following unstable identifiers:
|
||||
|
||||
| Stable | Unstable |
|
||||
|-|-|
|
||||
| `/_matrix/policy/v1/event/:eventId/check` | `/_matrix/policy/unstable/org.matrix.msc4284/event/:eventId/check` |
|
||||
| `m.room.server_assignments` | `org.matrix.msc4284.server_assignments` |
|
||||
| `m.policy` | `org.matrix.msc4284.policy` |
|
||||
|
||||
## Dependencies
|
||||
|
||||
This proposal has no direct dependencies.
|
||||
Loading…
Reference in New Issue