diff --git a/proposals/3173-expose-stripped-state-events.md b/proposals/3173-expose-stripped-state-events.md new file mode 100644 index 00000000000..830a9388a6c --- /dev/null +++ b/proposals/3173-expose-stripped-state-events.md @@ -0,0 +1,195 @@ +# MSC3173: Expose stripped state events to any potential joiner + +It can be useful to view the partial state of a room before joining to allow a user +to know *what* they're joining. For example, it improves the user experience to +show the user the room name and avatar before joining. + +It is already allowed to partially view the room state without being joined to +the room in some situations: + +* If the room has `history_visibility: world_readable`, then anyone can inspect + it (by calling `/state` on it). +* Rooms in the [room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms) + expose some of their state publicly. +* [Invited users](https://matrix.org/docs/spec/server_server/r0.1.4#put-matrix-federation-v2-invite-roomid-eventid) + and [knocking users](https://github.com/matrix-org/matrix-doc/pull/2403) + receive stripped state events to display metadata to users. + +This MSC proposes formalizing that the stripped state that is currently available +to invited and knocking users is available to any user who could potentially join +a room. It also defines "stripped state" and consolidates the recommendation on +which events to include in the stripped state. + +## Background + +When creating an invite it is [currently recommended](https://matrix.org/docs/spec/server_server/r0.1.4#put-matrix-federation-v2-invite-roomid-eventid) +to include stripped state events which are useful for displaying the invite to a user: + +> An optional list of simplified events to help the receiver of the invite identify +> the room. The recommended events to include are the join rules, canonical alias, +> avatar, and name of the room. + +The invited user receives these [stripped state events](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientr0sync) +as part of the `/sync` response: + +> The state of a room that the user has been invited to. These state events may +> only have the `sender`, `type`, `state_key` and `content` keys present. These +> events do not replace any state that the client already has for the room, for +> example if the client has archived the room. + +These are sent as part of the [`unsigned` content of the `m.room.member` event](https://spec.matrix.org/unstable/client-server-api/#mroommember) +containing the invite. + +[MSC2403: Add "knock" feature](https://github.com/matrix-org/matrix-doc/pull/2403) +extends this concept to also include the stripped state events in the `/sync` response +for knocking users: + +> It is proposed to add a fourth possible key to rooms, called `knock`. Its value +> is a mapping from room ID to room information. The room information is a mapping +> from a key `knock_state` to another mapping with key events being a list of +> `StrippedStateEvent`. + +It is also provides an extended rationale of why this is useful: + +> These stripped state events contain information about the room, most notably the +> room's name and avatar. A client will need this information to show a nice +> representation of pending knocked rooms. The recommended events to include are the +> join rules, canonical alias, avatar, name and encryption state of the room, rather +> than all room state. This behaviour matches the information sent to remote +> homeservers when remote users are invited to a room. + +[MSC1772: Spaces](https://github.com/matrix-org/matrix-doc/pull/1772) additionally +recommends including the `m.room.create` event as one of the stripped state events: + +> Join rules, invites and 3PID invites work as for a normal room, with the exception +> that `invite_state` sent along with invites should be amended to include the +> `m.room.create` event, to allow clients to discern whether an invite is to a +> space-room or not. + +## Proposal + +The specification does not currently define what "stripped state" is or formally +describe who can access it, instead it is specified that certain situations (e.g. +an invite or knock) provide a potential joiner with the stripped state of a room. + +This MSC clarifies what "stripped state" is and formalizes who can access the +stripped state of a room in future cases. + +Potential ways that a user might be able to join a room include, but are not +limited to, the following mechanisms: + +* A room that has `join_rules` set to `public` or `knock`. +* A room that the user is in possession of an invite to (regardless of the `join_rules`). + +This MSC proposes a formal definition for the stripped state of a room[1](#f1): + +> The stripped state of a room is a list of simplified state events to help a +> potential joiner identify the room. These state events may only have the +> `sender`, `type`, `state_key` and `content` keys present. + +### Client behavior + +These events do not replace any state that the client already has for the room, +for example if the client has archived the room. Instead the client should keep +two separate copies of the state: the one from the stripped state and one from the +archived state. If the client joins the room then the current state will be given +as a delta against the archived state not the stripped state. + +### Server behavior + +It is recommended (although not required[2](#f2)) that +homeserver implementations include the following events as part of the stripped +state of a room: + +* Create event (`m.room.create`)[3](#f3) +* Join rules (`m.room.join_rules`) +* Canonical alias (`m.room.canonical_alias`) +* Room avatar (`m.room.avatar`) +* Room name (`m.room.name`) +* Encryption information (`m.room.encryption`)[4](#f4) +* Room topic (`m.room.topic`)[5](#f5) + +## Potential issues + +This is a formalization of current behavior and should not introduce new issues. + +## Alternatives + +A different approach would be to continue with what is done today for invites, +knocking, the room directory: separately specify that a user is allowed to see +the stripped state (and what events the stripped state should contain). + +## Security considerations + +This would allow for invisibly accessing the stripped state of a room with `public` +or `knock` join rules. + +In the case of a public room, if the room has `history_visibility` set to `world_readable` +then this is no change. Additionally, this information is already provided by the +room directory (if the room is listed there). Otherwise, it is trivial to access +the state of the room by joining, but currently users in the room would know +that the join occurred. + +Similarly, in the case of knocking, a user is able to trivially access the +stripped state of the room by knocking, but users in the room would know that +the knock occurred. + +This does not seem to weaken the security expectations of either join rule. + +## Future extensions + +### Revisions to the room directory + +A future MSC could include additional information from the stripped state events +in the [room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms). +The main missing piece seems to be the encryption information, but there may also +be other pieces of information to include. + +### Additional ways to access the stripped state + +[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) proposes including +the stripped state in the spaces summary. Not needing to rationalize what state +can be included for a potential joiner would simplify this (and future) MSCs. + +### Additional ways to join a room + +[MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083) proposes a new +join rule due to membership in a space. This MSC would clarify that the stripped +state of a room is available to those joiners. + +### Dedicated API for accessing the stripped state + +Dedicated client-server and server-server APIs could be added to request the +stripped state events, but that is considered out-of-scope for the current +proposal. + +This API would allow any potential joiner to query for the stripped state. If +the server does not know the room's state it would need to query other servers +for it. + +## Unstable prefix + +N/A + +## Footnotes + +[1]: No changes are proposed to +[the definition of `history_visibility`](https://matrix.org/docs/spec/client_server/latest#room-history-visibility). +The state of a room which is `world_readable` is available to anyone. This somewhat +implies that the stripped state is also available to anyone, regardless of the join +rules, but having a `world_readable`, `invite` room does not seem valuable. [↩](#a1) + +[2]: Privacy conscious deployments may wish to limit the metadata +available to users who are not in a room as the trade-off against user experience. +There seems to be no reason to not allow this. [↩](#a2) + +[3]: As updated in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772). [↩](#a3) + +[4]: The encryption information (`m.room.encryption`) is already sent +from Synapse and generally seems useful for a user to know before joining a room. +[↩](#a4) + +[5]: The room topic (`m.room.topic`) is included as part of the +[room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms) +response for public rooms. It is also planned to be included as part of [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) +in the spaces summary response. [↩](#a5)