Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC4206: Moderation policy auditing and context #4206

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions proposals/4206-policy-reason-auditing.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Client sending context
  • Client using context

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# MSC4206: Moderation policy auditing and context

Moderation policies provide a `reason` field.
While this is designed as a free-text field, there are a number
of reasons why it is not appropriate to do so.

* The `reason` is public, and moderators may not want to provide
context about the ban in public. But still need to keep the context
on record. They may also need to share context with other
moderators, but not the wider community.

* Moderation bots such as Draupnir and Mjolnir use the `reason`
field in `m.policy.rule.user` to determine whether the user's
events and profile should be redacted. This stops the reason
field being used to provide context.

## Proposal

Standard Matrix, encrypted messaging threads are used to provide
context about moderation policies.

A new policy event `m.policy.rule.context` is introduced. This is
almost identical to `m.policy.rule.*` events, except it servers as an
anchor point to open threads. The reason why the existing policy is
not used to act as an anchor point is so that context can be provided
in a separate, private, and encrypted policy room. And also so that
when the original policy is rescinded or expires, the context is still
available.

```json
"type": "m.policy.rule.context",
"content": {
"recommendation": "m.ban",
"entity": "@yarrgh:example.com",
"rule_type": "m.policy.rule.user",
},
```

### Flow from a moderation bot

In order to provide an example of how this proposal will work,
we are going to discuss a possible UX flow for a moderation bot.

Alice is a room moderator, and Neighnir is a moderation bot.

Alice has recently banned `@yarrgh:example.com` and wants to provide
some context for the ban to the other moderators in her community.

Alice repeats the arguments to the ban command to Neighnir in
the context command.

`!neighnir context ban @yarrgh:example.com`.

Neighnir then creates a new `m.policy.rule.context` policy
in a pre-configured and private policy room. If a context
policy already exists for the `recommendation` and `entity`
combination, then this step is skipped.

Neighnir then creates a threaded message referring to the
policy context. This step is skipped if a thread is already open.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be expensive to find existing events in large policy lists given that you have to scan content on every context event? The bot could possibly work around that by keeping its own index.


```json
{
"m.relates_to": {
"rel_type": "m.thread",
"event_id": "$the_context_policy_event"
},
"msgtype": "m.notice",
"body": "`@yarrgh:example.com` context starts here."
}
```

Neighnir then returns a link to the thread as a response
to Alice's command.

Alice can then send normal Matrix messages in the thread in
order to provide any context, including screenshots.

## Potential issues
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If m.policy.rule.context is also meant to be a state event, existing chat clients might not be able to render the context thread as they likely won't support threading on state events. This might not be a terrible problem other than being able to browse context rooms from a non-specialized client possibly being convenient.


### GDPR compliance

It's unclear to me how this context will interact with GDPR legislation
and I have received no legal advice.

The risk is that in some cases it may be possible for the considered
`entity` to demand the messages in the context thread?

Moderators will have to be warned of this possibility.

### Old irrelevant context

Some context may actually be old, irrelevant, or taken out of
context itself. Moderators may need to be actively encouraged to
redact old context.

## Alternatives

### Local storage

Context could be stored locally in moderation tools, but this
restricts collaboration between different tools and moderators.
It also prevents the context being viewed as a normal matrix thread.
The context would also not necessarily be encrypted.

## Security considerations

### Access to context

An attacker gaining access to private policy lists containing context
could be a serious data breach. However, as the threads in the policy
lists are encrypted, they would need to obtain the decryption keys.

## Unstable prefix

`org.matrix.msc4206.context` -> `m.policy.rule.context`