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

MSC4115: membership information on events #4115

Merged
merged 16 commits into from
Jun 3, 2024
131 changes: 131 additions & 0 deletions proposals/4115-membership-on-events.md
Copy link
Member

@turt2live turt2live Feb 26, 2024

Choose a reason for hiding this comment

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# MSC4115: membership metadata on events

## Background

Consider the following Event DAG:

```mermaid
graph BT;
B[Bob joins];
B-->A;
C-->A;
D-->B;
D-->C;
```

Bob has joined a room, but at the same time, another user has sent a message
`C`.

Depending on the configuration of the room, Bob's server may serve the event
`C` to Bob's client. However, if the room is encrypted, Bob will not be on the
recipient list for `C` and the sender will not share the message key with Bob,
even though, in an absolute time reference, `C` may have been sent at a later
timestamp than Bob's join.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

Unfortunately, there is no way for Bob's client to reliably distinguish events
such as `A` and `C` that were sent "before" he joined (and he should therefore
not expect to decrypt) from those such as `D` that were sent later.
andybalaam marked this conversation as resolved.
Show resolved Hide resolved

This issue is discussed in more detail at
https://github.com/element-hq/element-meta/issues/2268.

As a partial solution to this problem, we propose a mechanism for servers to
inform clients of room membership at each event.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

## Proposal

The `unsigned` structure contains data added to an event by a homeserver when
serving an event over the client-server API. (See
[specification](https://spec.matrix.org/v1.9/client-server-api/#definition-clientevent)).

We propose adding a new property, `membership`, which should contain the
Copy link
Member Author

Choose a reason for hiding this comment

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

Thoroughly unconvinced that membership is the best name here. "Whose membership?"

Suggestions?

Copy link
Member

Choose a reason for hiding this comment

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

my_membership is the top of my head answer

Copy link
Member

Choose a reason for hiding this comment

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

i think membership is good enough here, tbh - as long as the MSC itself is clearer that it's talking about the syncing user's membership rather than the sender's or similar.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's clear enough. The sender must be in the room at the time they sent the event, so it wouldn't make sense to send the sender's membership. membership might not be a great name, but I can't think of anything that's reasonably short, that makes it much clearer, and doesn't sound awkward. So I think membership is good enough.

membership of the user making the request, according to the state of the room
at the time of the event being returned. If the user had no membership at that
point (ie, they had yet to join or be invited), `membership` is set to `leave`.
Any changes caused by the event itself (ie, if the event itself is a
`m.room.member` event for the requesting user) are *excluded*.

In other words: servers should follow the following algorithm when serving an
event E to a user Alice:

1. Consider the room state just *before* event E landed (accounting for state
resolution accross E's `prev_events`, but not E itself).

Check warning on line 52 in proposals/4115-membership-on-events.md

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"accross" should be "across".
2. Within the state, find the event M with type `m.room.member` and `state_key`
set to Alice's user ID.
3. * If no such event exists, set `membership` to `leave`.
* Otherwise, set `membership` to the value of the `membership` property of
the content of M.

The new property should be *required* for all servers implementing a version of
the spec that includes this MSC. However, clients needing to maintain
compatibility with earlier versions of the spec will need to consider it as
optional.

For the avoidance of doubt, the new `membership` property is added to all
Client-Server API endpoints that return events, including
[`/sync`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3sync),
[`/messages`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3roomsroomidmessages),
[`/state`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3roomsroomidstate),
and deprecated endpoints such as
[`/events`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3events)
and
[`/initialSync`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3events).
richvdh marked this conversation as resolved.
Show resolved Hide resolved


Example event including the new property:

```json
{
"content": {
"membership": "join"
},
"event_id": "$26RqwJMLw-yds1GAH_QxjHRC1Da9oasK0e5VLnck_45",
"origin_server_ts": 1632489532305,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "@user:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1567437,
"membership": "leave",
KitsuneRal marked this conversation as resolved.
Show resolved Hide resolved
"redacted_because": {
"content": {
"reason": "spam"
},
"event_id": "$Nhl3rsgHMjk-DjMJANawr9HHAhLg4GcoTYrSiYYGqEE",
"origin_server_ts": 1632491098485,
"redacts": "$26RqwJMLw-yds1GAH_QxjHRC1Da9oasK0e5VLnck_45",
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@moderator:example.org",
"type": "m.room.redaction",
"unsigned": {
"membership": "leave",
"age": 1257
}
}
}
}
richvdh marked this conversation as resolved.
Show resolved Hide resolved
```

## Potential issues

* Depending on server implementation, it may be expensive or difficult to
implement? Feedback welcome from HS authors on this point.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

## Alternatives

https://github.com/element-hq/element-meta/issues/2268#issuecomment-1904069895
proposes use of a Bloom filter — or possibly several Bloom filters — to
mitigate this problem in a more general way. It is the opinion of the author of
this MSC that there is room for both approaches.

## Security considerations

None foreseen.

## Unstable prefix


## Dependencies

None.
Loading