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

MSC3061: Sharing room keys for past messages #3061

Merged
merged 5 commits into from
Aug 14, 2023
Merged
Changes from 2 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
78 changes: 78 additions & 0 deletions proposals/3061-shareable-room-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# MSC3061: Sharing room keys for past messages

In Matrix, rooms can be configured via the `m.room.history_visibility` state
event such that historical messages can be visible to all Matrix users
(`world_readable`), all room members (`shared`), room members from the time
that they are invited to a room (`invited`), or room members from the time that
they join a room (`joined`). However, currently in encrypted rooms, rooms with
the history visibility set to `world_readable` or `shared` are effectively
set to `invited` since other members generally do not send new members the keys
to decrypt messages sent before they were invited or joined a room.

We define a "shared-history" flag that identifies keys for messages that were
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
sent when the room's visibility setting was set to `world_readable` or
`shared`. This allows clients to know which keys are "safe" to share with new
members so that they can decrypt historical messages. We also give examples of
ways in which this flag can be used.


## Proposal

A room key (such as a megolm session) is flagged as having been used for shared
history when it was used to encrypt a message while the room's history
visibility setting was set to `world_readable` or `shared`. Internally, a
client may use any mechanism it wants to keep track of this flag. When a room
key is marked as such:

- `m.room_key` and `m.forwarded_room_key` messages used to share this key have
a `shared_history` property set to `true`,
- the `session_data` field in key backups of this key has a `shared_history`
property set to `true` in the decrypted JSON structure, and
- the `SessionData` type used in key exports has a `shared_history` property
that is set to `true` for this key.
uhoreg marked this conversation as resolved.
Show resolved Hide resolved

When a client obtains a key that has the `shared_history` property set to
`true`, then it flags the key internally as having been used for shared
history. Otherwise, the key should not be flagged as such.

When the room's history visibility setting changes to `world_readable` or
`shared` from `invited` or `joined`, or changes to `invited` or `joined` from
`world_readable` or `shared`, senders that support this flag must rotate their
megolm sessions.

Clients may use this flag to modify their behaviour with respect to sharing
keys. For example:

- when the user invites someone to the room, they may preemptively share keys
that have this flag with the invited user.
- when the user receives a key share request, they may share the key with the
requester if the user is a current member of the room. The key may be shared
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
from the first available ratchet index, not just the requested index.
ara4n marked this conversation as resolved.
Show resolved Hide resolved
- when sending a message after a new user has joined the room, a sender may
share the megolm session from the first available index, rather than from the
current ratchet index.

## Potential issues
uhoreg marked this conversation as resolved.
Show resolved Hide resolved

Room keys from clients that do not support this proposal will not be eligible
for the modified client behaviour.

## Alternatives

Rather than having the sender flagging keys, a client can paginate through the
room's history to determine the room's history visibility settings when the
room key was used. This would not require any changes, but has performance
problems. In addition, the server could lie about the room history while the
user is paginating through the history. By having the sender flag keys, this
ensures that the key is treated in a manner consistent with the sender's view
of the room.

## Security considerations

Clients should still ensure that keys are only shared with authorized users and
devices.
Copy link
Contributor

Choose a reason for hiding this comment

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

How does this work? How does the client know, that a user should be in the room and wasn't maliciously added by the homeserver? Even if you set a room to shared history, you probably only want members to read the history, that you accepted as having been allowed into the room. Considering the end aspect in e2ee, we want the client to approve of a member having joined the room, before sharing history. We don't want to automatically share keys with anyone, who joins the room, because the server could for a short time "fake" a user in the room and as such get access to all the history and then make the user disappear again. Then encrypting the room would be useless. Should we require prompting the user once before sharing past history with a new user in the room?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is sort of a generic "make sure that you don't accidentally over-share when you implement this". In this case, clients only share the keys with users that the client invites, so it's decided that the user should be authorized. For determining which devices are authorized, in general, the client should probably just do what it normally does for determining which devices to send keys to.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is a really scary trap, because a client dev might forget, that the servers device list and member list isn't really that trustworthy. We somewhat get around that by warning for unverified devices, when sending a message, but that will never work for sharing past message keys.

Copy link
Member

Choose a reason for hiding this comment

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

The proper solution here is to base the decision whether to share on the trust state of the user we're inviting.

If the invited user is untrusted (in cross-signing terms), the client should at least display a warning along with a list of devices that would get the keys. This would allow the inviter to at least review the list and consciously proceed with the action if they want to do so.

If the invited user is trusted, but some of their devices are not verified yet, the client should again display a warning with a list of those devices, again asking whether to proceed.

If the user is trusted and all of their devices are verified, then no warning is necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

So only the inviter will ever share keys?

Copy link
Member Author

Choose a reason for hiding this comment

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

It doesn't have to be just the inviter who shares keys; others can share keys as well, but it's up to them to ensure that they do so securely. Spec-wise, we try to avoid telling clients exactly how to handle keys, as different clients may wish to make different tradeoffs. But I will add a comment about checking device trust before sharing.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've added some more words here. Hopefully it's clearer now.


## Unstable prefix

Until this feature lands in the spec, the property name to be used is
`org.matrix.msc3061.shared_history` rather than `shared_history`.