Skip to content

Conversation

@kaylendog
Copy link

@kaylendog kaylendog commented Sep 25, 2025

Rendered

Implementations:

@kaylendog kaylendog self-assigned this Sep 25, 2025
@kaylendog kaylendog added e2e feature Suggestion for a significant extension which needs considerable consideration proposal A matrix spec change proposal client-server Client-Server API kind:core MSC which is critical to the protocol's success implementation-needs-checking The MSC has an implementation, but the SCT has not yet checked it. labels Sep 25, 2025
@turt2live turt2live added needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. and removed implementation-needs-checking The MSC has an implementation, but the SCT has not yet checked it. labels Sep 25, 2025
@kaylendog kaylendog changed the title Initial draft of simplified encrypted state events. 4362: Simplified Encrypted State Events Sep 25, 2025
@kaylendog kaylendog changed the title 4362: Simplified Encrypted State Events MSC4362: Simplified Encrypted State Events Sep 25, 2025
Comment on lines +46 to +47
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

Choose a reason for hiding this comment

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

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.

Copy link
Author

Choose a reason for hiding this comment

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

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..

Comment on lines +81 to +85
### 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.
Copy link
Author

Choose a reason for hiding this comment

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

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.

Copy link
Member

Choose a reason for hiding this comment

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

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.

Comment on lines +205 to +210
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.
Copy link
Author

Choose a reason for hiding this comment

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

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.

Copy link
Member

Choose a reason for hiding this comment

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

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.
Copy link
Member

Choose a reason for hiding this comment

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

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).

Copy link
Member

@andybalaam andybalaam Nov 13, 2025

Choose a reason for hiding this comment

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

In rooms with encrypted state, clients MUST prefer encrypted state over unencrypted state if both are present for a given type, state_key pair.

Copy link
Member

Choose a reason for hiding this comment

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

^ Maybe this should go elsewhere, but these worked examples are a nice way to explain what's happening.

Copy link
Author

Choose a reason for hiding this comment

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

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_key for encrypted state events is constructed from the plaintext type and state_key
fields, formatted as {type}:{state_key}, preserving the uniqueness of the type-state_key
mapping required for the server to perform state resolution.

Copy link
Author

@kaylendog kaylendog Nov 13, 2025

Choose a reason for hiding this comment

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

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.

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 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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client-server Client-Server API e2e feature Suggestion for a significant extension which needs considerable consideration kind:core MSC which is critical to the protocol's success needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants