-
Notifications
You must be signed in to change notification settings - Fork 434
WIP: MSC3277: Scheduled messages #3277
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
base: old_master
Are you sure you want to change the base?
Changes from 9 commits
1611d96
a19cc2f
441725a
5fdcfe6
f20bb9b
cca55d2
1e713b1
d9271ab
9708232
9dfbb46
5723c4f
ddf843d
10801ed
e19c4d1
3b91f08
7361aa5
206c52f
a8e1b37
938212b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,21 +18,20 @@ A new query parameter, `at`, is added to the [/send](https://matrix.org/docs/spe | |
| and [PUT /state](https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey) | ||
| endpoints to indicate when the origin server should aim to send the event | ||
| (milliseconds since the unix epoch). The message is added to the room DAG | ||
| when the sender creates the event, but is only relayed to other members of | ||
| the room at the scheduled `at` time (or as close to it as the server can | ||
| manage). | ||
|
|
||
| The event is effectively treated as if it had been received over federation | ||
| after a federation delay. As such, all event types can be scheduled in this | ||
| manner, including state events. Normal event ID and redaction behaviour | ||
| applies. At the scheduled time, the server re-auths the event, and then | ||
| sends it on to the users in the room (if appropriate, otherwise it soft-fails | ||
| it), including the sender. Therefore if the event is no longer acceptable in | ||
| the room at its scheduled time (e.g. if the sender is no longer in the room, | ||
| or no longer has PL to send events) then the event is soft-failed - just as | ||
| if a federated server tried to circumvent a user ban by sending old messages | ||
| into the DAG. Scheduled events are sent out over federation at the scheduled | ||
| time in order to minimise embargo leaks. | ||
| when the sender creates the event, and is immediately relayed to the sender's | ||
| devices (as a remote echo) but not the other members in the room. | ||
|
|
||
| It is then effectively soft-failed until the scheduled `at` time (or as close | ||
| to it as the server can manage), when it is then re-authed and relayed as | ||
| normal to all room members (both local and remote, including the sender). | ||
| Scheduled events are sent out over over federation at this point rather than | ||
| creation time in order to minimise embargo leaks. If the event can't be | ||
| re-authed (e.g. due to the sender no longer being in the room, or no longer | ||
| has sufficient PL to send the event) then the event is soft-failed. As such, | ||
| the event effectively appears as if it had been received over federation | ||
| after a federation delay. This means all event types can be scheduled in | ||
| this manner, including state events. Normal event ID and redaction behaviour | ||
| applies. | ||
|
|
||
| The server must set the `origin_server_ts` of the message is set to be its | ||
| `at` time, given in practice this is the label used for clients to display | ||
|
Comment on lines
+36
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should only be done if the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "server should clamp past time stamps" can get finicky if the clocks of the server and the client aren't synchronized.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree but I don't think the server always trusts the client enough to pick arbitrary timestamps. This could lead to confusing behaviour. I get that this is possible over federation with a malicious server anyways but it seems like this confusing behaviour should be avoided when it is simple to do a pretty good job. We are already trusting the server clock for when to publish the message so it seems that the server slot is expected to be vaguely in sync anyways. TL;DR if the field is called |
||
|
|
@@ -50,10 +49,11 @@ creation time). | |
|
|
||
| The sender's clients will want to track the unsent scheduled messages in its | ||
| various rooms, such that the sender can cancel them by redacting them, or | ||
|
ara4n marked this conversation as resolved.
|
||
| edit them (optionally redacting earlier versions, providing private | ||
| drafting). We propose using the same mechanism as for tracking 'starred' | ||
| (aka 'favourited' or 'flagged') messages, to avoid sprouting two different | ||
| APIs for almost identical functionality. This is deferred to a future MSC. | ||
| edit them (optionally redacting earlier versions <sup id="a1">[1] | ||
| (#f1)</sup>, providing private drafting). We propose using the same | ||
| mechanism as for tracking 'starred'(aka 'favourited' or 'flagged') messages, | ||
|
ara4n marked this conversation as resolved.
Outdated
|
||
| to avoid sprouting two different APIs for almost identical functionality. | ||
| This is deferred to a future MSC. | ||
|
|
||
| ## Encryption considerations | ||
|
|
||
|
|
@@ -69,9 +69,6 @@ The megolm session must be a one-off used just for this scheduled message | |
| the session used to encrypt that particular message rather than any surrounding | ||
| non-scheduled ones). | ||
|
|
||
| E2EE implementations must not discard 'unused' megolm sessions, given they | ||
| may be shared long in advance of the scheduled message. | ||
|
|
||
| Sender's clients may optionally attempt to wake themselves up at the deadline | ||
| in order to re-share the megolm session to the current participants in the | ||
| room (and/or be available to respond to keyshare reqs), in order to reduce | ||
|
|
@@ -86,6 +83,10 @@ received. Therefore we add a `m.forward_until: timestamp` field to the | |
| timestamp should be that of the scheduled event; users who join the room | ||
| after that timestamp should not be able to read the message. | ||
|
|
||
| E2EE implementations must not discard 'unused' megolm sessions for scheduled | ||
| messages (i.e. megolm sessions with `m.forward_until` fields), given they may | ||
| be shared long in advance of the scheduled message. | ||
|
|
||
| ## Possible issues | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This MSC allows the server to set |
||
|
|
||
| A risk is that E2EE key distribution mechanisms which rely on clients seeing | ||
|
|
@@ -101,18 +102,46 @@ keys from bystanders - but this may be an acceptable tradeoff to improve | |
| the chances of the message being decryptable in the distant future. | ||
| Alternatively, MLS may solve this(??) | ||
|
|
||
| Users who send a scheduled message and are then kicked out of a room will have | ||
| no way of being able to cancel their scheduled message. This could either be | ||
| a feature (ex-employees shouldn't be able to destroy their scheduled | ||
| messages), or a bug (i want to GDPR erase my scheduled messages!). We | ||
| consider it a feature. | ||
|
|
||
| Another problem is that because we share E2EE to users at msg authoring time, if | ||
| users subsequently leave the room, they will still have the keys to read the | ||
| scheduled message when it's revealed. This is probably inevitable. Clients could | ||
| try to solve it by redacting the scheduled message and resending it with a new megolm | ||
| session whenever they spot that users (or devices?) have left the room. | ||
|
|
||
| ## Example | ||
|
|
||
| ``` | ||
| PUT /_matrix/client/r0/rooms/!wherever:example.com/send/m.room.message/123?at=1636197454551 | ||
| { | ||
| "body": "a note to my future self", | ||
| "msgtype": "m.text" | ||
| } | ||
| ``` | ||
|
|
||
| ...would result in the origin server sending the following event to room | ||
| recipients at Sat Nov 6 10:17:34 2021 UTC (assuming the event still passed | ||
| auth checks): | ||
|
|
||
| ```json | ||
| { | ||
| "content": { | ||
| "body": "a note to my future self", | ||
| "msgtype": "m.text" | ||
| }, | ||
| "origin_server_ts": 1636197454551, | ||
| "sender": "@matthew:matrix.org", | ||
| "type": "m.room.message", | ||
| "unsigned": { | ||
| "age": 391 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to add |
||
| }, | ||
| "event_id": "$FC9MwqLPBzRl1AzLi-qOJbdYeMJFzugORlF6yPJkyII", | ||
| "room_id": "!xYvNcQPhnkzdUmYczI:matrix.org" | ||
| } | ||
| ``` | ||
|
|
||
| N.B. there's nothing interesting in this event other than its | ||
| `origin_server_ts` being set to the `at` parameter, and obviously being | ||
| sent out at the scheduled time. | ||
|
|
||
| ## Alternatives | ||
|
|
||
|
|
@@ -136,7 +165,8 @@ still be running at the scheduled time. On the other hand, it means that you | |
| are much more likely to break embargos, as one-person homeservers will get | ||
| the message ahead of schedule. We've gone for the more privacy preserving | ||
| option (send over federation at the scheduled time). Plus it acts as an | ||
| incentive for people to keep the origin server running ;P | ||
| incentive for people to keep the origin server running ;P. <sup id="a2">[2] | ||
| (#f2)</sup> | ||
|
|
||
| Another alternative would be to use an API shape where you put a field on the | ||
| event contents (e.g. `m.pts` for presentation timestamp) to tell servers and | ||
|
|
@@ -157,14 +187,20 @@ This MSC allows for spammers to potentially pre-plan their attacks for | |
| off-peak hours when the moderators may not be present. It also potentially | ||
| allows a user to stack up a large number of pending events which all get sent | ||
| throughout the day as a disruption attempt. Servers should impose harsh | ||
| limits to the number of events a user may schedule, such as a maximum of 3 | ||
| pending events, to reduce the potential for abuse while still maintaining an | ||
| amount of usability for common scenarios. | ||
| limits to the number of events a user may schedule, such as a maximum of N | ||
| pending events per room (where N < ~5), to reduce the potential for abuse | ||
| while still maintaining an amount of usability for common scenarios. | ||
|
|
||
| Users could also try to schedule many events at once or schedule such that | ||
| they all get sent at once - servers should apply rate limiting on both the | ||
| scheduling and sending sides to limit the user’s ability to spam a room. | ||
|
|
||
| There's a risk that an attacker could DoS a user with fake megolm sessions | ||
| for scheduled messages which never arrive. This could be mitigated in the | ||
| receiving client by enforcing similar limits to those on the server (e.g. | ||
| if you receive more than N megolm sessions for scheduled messages from | ||
| a given user in the room, the client could warn and discard them). | ||
|
|
||
| This proposal relies on absolute timestamps, and so for it to work sensibly | ||
| servers need to have an accurate (e.g. NTP-synced) clock. | ||
|
ara4n marked this conversation as resolved.
|
||
|
|
||
|
|
@@ -174,3 +210,16 @@ Implementations should use `org.matrix.msc3277.at` in place of the at query | |
| parameter, and expose/look for `org.matrix.msc3277` in the | ||
| unstable_features` of `/versions` while this MSC is not in a released | ||
| version of the spec. | ||
|
|
||
| ## Footnotes | ||
|
|
||
| <a id="f1"/>[1]: A smart server could stop earlier redacted drafts ever | ||
| being sent to the destination servers by placing new drafts as siblings | ||
| to the old drafts in the DAG rather than as children. This means that | ||
| recipients wouldn't be able to see that the scheduled message was | ||
| drafted. This is a bit of an overenthusiastic optimisation though. | ||
|
|
||
| <a id="f2"/>[2]: For P2P, it's likely that the origin server/client will not | ||
| be online at the designated time, so we'll want to special-case scheduled | ||
| messages for P2P such that they are queued on a privacy-preserving relay | ||
| server of some kind rather than queuing on the origin server/client. | ||
Uh oh!
There was an error while loading. Please reload this page.