Conversation
| An encrypted state event looks very similar to a regular encrypted room message: the `type` becomes | ||
| `m.room.encrypted` and the `content` is the same shape as a regular `m.room.encrypted` event. The |
There was a problem hiding this comment.
This doesn't seem to address the core problem with encrypted state events, where state events have a different lifecycle from timeline events. But I also don't see the problem mentioned on the MSC at all.
Say you have this timeline in a room with history visibility invite:
m.room.name <- A
m.room.message <-B
invite to X
X joins
To make the room name sent at A visible to X, you need to share the megolm key for it, which might include the key for decrypting message B as well.
To prevent that, you basically need a different megolm session for every (event_type, state_key) tuple. Otherwise you might leak an arbitrary set of past messages or states.
There was a problem hiding this comment.
Yes! I do not intend to address the issue of key-sharing in this MSC, except for what I've said about history sharing. I briefly covered my thoughts on how this would be done for the HMAC key distribution below, and I imagine we could re-use this infrastructure to resolve this..
| ### Room names and topics are not visible from outside | ||
|
|
||
| The name and topic of a room with encrypted state will not be visible without access to the keys | ||
| used to encrypt them. Without additional proposals, this will make it impossible to provide a room | ||
| directory entry, list the room inside a space, or display room details when invited. |
There was a problem hiding this comment.
Would it be worth mentioning potential fixes for these limitations in the content of this MSC, or is that generally handled elsewhere? We previously discussed the potential of a m.space.child_info event to mitigate this, which I included in my earlier draft.
There was a problem hiding this comment.
I feel like it's still quite open how we could deal with this, which is why I removed that part - it's just one example of what we could do. But if you want to put it in, that's fine by me.
| Upon joining a room with encrypted state, new users will not be able to decrypt room state, making | ||
| the room name, topic and other information (e.g. ongoing whiteboard sessions or call) inaccessible. | ||
|
|
||
| This limitation does not apply if | ||
| [MSC4268](https://github.com/matrix-org/matrix-spec-proposals/pull/4268) is available and the room | ||
| settings allow sharing the relevant events. |
There was a problem hiding this comment.
Do you think it's worth clarifying that we allow state event encryption to be enabled at any time, like message encryption? We don't state that anywhere in the proposal at the moment, although it can be assumed since we're using the existing m.room.encryption.
There was a problem hiding this comment.
Yes, that is a good idea.
Also, I feel like I heard that you can't send more than one m.room.encryption event in the entire history of a room (later ones would be ignored) but I just checked the spec and I can't see that anywhere. Maybe I'm making it up.
It would be a good idea to decide whether it is possible to turn on state encryption later in the history of a room, after encryption was already turned on, and whether it's possible to turn it off again by sending another m.room.encryption later.
|
|
||
| Clients receiving this event will use the packed state key to determine which state event it | ||
| represents, decrypt the payload, and verify that the decrypted `type` and `state_key` match the | ||
| packed state key. |
There was a problem hiding this comment.
Also, because the packed state key is unique for a given type, state_key pair, with no server changes, server provided state will contain the latest state event for each pair (subject to state resolution as normal).
There was a problem hiding this comment.
In rooms with encrypted state, clients MUST prefer encrypted state over unencrypted state if both are present for a given type, state_key pair.
There was a problem hiding this comment.
^ Maybe this should go elsewhere, but these worked examples are a nice way to explain what's happening.
There was a problem hiding this comment.
Also, because the packed state key is unique for a given type, state_key pair, with no server changes, server provided state will contain the latest state event for each pair (subject to state resolution as normal).
I think we cover this in the second paragraph of the proposal
The
state_keyfor encrypted state events is constructed from the plaintexttypeandstate_key
fields, formatted as{type}:{state_key}, preserving the uniqueness of thetype-state_key
mapping required for the server to perform state resolution.
There was a problem hiding this comment.
In rooms with encrypted state, clients MUST prefer encrypted state over unencrypted state if both are present for a given type, state_key pair.
To me, this seems relevant to include in the core proposal content? I'll make a change.
There was a problem hiding this comment.
I think we cover this in the second paragraph of the proposal
Yeah, but I thought it was worth re-iterating here since we're talking through what happens. (Feel free to leave out)
| - `m.room.encryption` | ||
|
|
||
| An encrypted state event looks very similar to a regular encrypted room message: the `type` becomes | ||
| `m.room.encrypted` and the `content` is the same shape as a regular `m.room.encrypted` event. The |
There was a problem hiding this comment.
When so many state events then have the type m.room.encrypted the server behavior also needs to change. Right now every homeserver checks the type to determine if a user is allowed to push a state event but here the real type is now in the first half of the state_key, so the server needs to support a logic like this:
- Is event.type ==
m.room.encrypted? - No: Use event.type to calculate permission to change the event
- Yes: Use
event.state_key.split(':').firstto calculate permission to change the event
There was a problem hiding this comment.
A possible solution would be to switch out type and state key here. So that we have a normal type of for example m.room.name and the state key becomes m.room.encrypted:
There was a problem hiding this comment.
Yes, I think that might work, but it would require more changes on the client side: with the type being m.room.encrypted it was relatively easy to persuade clients to decrypt these events.
But that's not an in-principle objection, and might not actually be a big issue either.
Rendered
Implementations:
matrix-js-sdk: Implement experimental encrypted state events. matrix-js-sdk#4994matrix-rust-sdk: There are quite a lot of PRs involved in this implementation, you can view the list here.element-web: Support encrypted state events MSC4362 element-hq/element-web#30877, Netlify deployment