Merge f0644a004e
into ecf996389f
commit
ba920a6407
@ -0,0 +1,187 @@
|
||||
# Proposal for self-destructing messages
|
||||
|
||||
It's useful for users to be able to send sensitive messages within a
|
||||
conversation which should be removed after the target user(s) has read them.
|
||||
This can be achieved today by the sender redacting the message after the
|
||||
receipient(s) have read them, but this is a tedious manual process. This
|
||||
proposal provides a way of automating this process.
|
||||
|
||||
Originally [MSC1763](https://github.com/matrix-org/matrix-doc/pull/1763)
|
||||
attempted to solve this by applying retention limits on a per-message basis
|
||||
and purging expired messages from the server; in practice this approach is
|
||||
flawed because purging messages fragments the DAG, breaking back-pagination
|
||||
and potentially causing performance problems. Also, the ability to set an
|
||||
expiration timestamp relative to the send (rather than read) time is not of
|
||||
obvious value. Therefore the concept of self-destructing messsages was
|
||||
split out into this independent proposal.
|
||||
|
||||
## Proposal
|
||||
|
||||
Users can specify that a message should self-destruct by adding one or more of
|
||||
the following fields to any event's content:
|
||||
|
||||
`m.self_destruct`:
|
||||
the duration in milliseconds after which the participating servers should
|
||||
redact this event on behalf of the sender, after seeing an explicit read
|
||||
receipt delivered for the message from all users in the room. Must be null
|
||||
or an integer in range [0, 2<sup>53</sup>-1]. If absent, or null, this
|
||||
behaviour does not take effect.
|
||||
|
||||
`m.self_destruct_after`:
|
||||
the timestamp in milliseconds since the epoch after which participating
|
||||
servers should redact this event on behalf of the sender. Must be null
|
||||
or an integer in range [0, 2<sup>53</sup>-1]. If absent, or null, this
|
||||
behaviour does not take effect.
|
||||
|
||||
Clients and servers MUST send explicit read receipts per-message for
|
||||
self-destructing messages (rather than for the most recently read message,
|
||||
as is the normal operation), so that messages can be destructed as requested.
|
||||
|
||||
The `m.self_destruct` fields are not preserved over redaction (and
|
||||
self-destructing messages may be redacted to speed up the self-destruct
|
||||
process if desired).
|
||||
|
||||
The `m.self_destruct` fields must be ignored on `m.redaction`events, given it
|
||||
should be impossible to revert a redaction.
|
||||
|
||||
E2E encrypted messages must store the `m.self_destruct` fields outside of the
|
||||
encrypted contents of the message, given the server needs to be able to act on
|
||||
it.
|
||||
|
||||
Senders may edit the `m.self_destruct` fields in order to retrospectively
|
||||
change the intended lifetime of a message. Each new `m.replaces` event should
|
||||
be considered to replace the self-destruction information (if any) on the
|
||||
original, and restart the destruction timer. On destruction, the original
|
||||
event (and all `m.replaces` variants of it) should be redacted.
|
||||
|
||||
## Server-side behaviour
|
||||
|
||||
When a client sends a message with `m.self_destruct` information, the servers
|
||||
participating in a room should start monitoring the room for read receipts for
|
||||
the event in question.
|
||||
|
||||
Once a given server has received a read receipt for this message from a member
|
||||
in the room (other than the sender), then the message's self-destruct timer
|
||||
should be started for that user. Once the timer is complete, the server
|
||||
should redact the event from that member's perspective, and send the user a
|
||||
synthetic `m.redaction` event in the room to the reader's clients on behalf of
|
||||
the sender.
|
||||
|
||||
The synthetic redaction event should contain an `m.synthetic: true` flag on
|
||||
the reaction's content to show the client that it is synthetic and used for
|
||||
implementing self-destruction rather than actually sent from the claimed
|
||||
client.
|
||||
|
||||
For `m.self_destruct_after`, the server should redact the event and send a
|
||||
synthetic redaction once the server's localtime overtakes the timestamp given
|
||||
by `m.self_destruct_after`. The server should only perform the redaction once.
|
||||
|
||||
## Client-side behaviour
|
||||
|
||||
Clients should display self-destructing events in a clearly distinguished
|
||||
manner in the timeline. Details of the lifespan can be shown on demand
|
||||
however, although a visible countdown is recommended.
|
||||
|
||||
Clients should locally remove `m.self_destruct` events as if they have been
|
||||
redacted N milliseconds after first attempting to send the read receipt for the
|
||||
message in question. The synthetic redaction event sent by the local server
|
||||
then acts as a fallback for clients which fail to implement special UI for
|
||||
self-destructing messages.
|
||||
|
||||
Clients should locally remove `m.self_destruct_after` events when the local
|
||||
timestamp exceeds the timestamp indicated in the `m.self_destruct_after`
|
||||
field.
|
||||
|
||||
Clients should warn the sender that self-destruction is based entirely on good
|
||||
faith, and other servers and clients cannot be guaranteed to uphold it.
|
||||
Typical text could be:
|
||||
|
||||
"Warning: recipients may not honour disappearing messages".
|
||||
|
||||
We recommend exposing the feature in UX as "disappearing messages" rather than
|
||||
"self-destructing messages", as self-destruction implies a reliability and
|
||||
permenance that the feature does not in practice provide.
|
||||
|
||||
Other possible user-friendly wording might include:
|
||||
* Ephemeral messages (which feels even less reliably destructive than
|
||||
'disappearing', but may be too obscure a word for a wide audience)
|
||||
* Vanishing messages (which implies they reliably vanish)
|
||||
* Vanishable messages (which is clunky, but more implies that it's an intent
|
||||
rather than a guarantee)
|
||||
* Evanescent messages (which is too obscure, but implies that it's a message
|
||||
which /can/ vanish, rather than that it /will/)
|
||||
* Fleeting messages (which is again quite an obscure word)
|
||||
* Transient messages (too techie)
|
||||
* Temporary messages (could work)
|
||||
* Short-term messages
|
||||
|
||||
## Threat model
|
||||
|
||||
Any proposals around coordinating deletion of data (e.g. this,
|
||||
[MSC1763](https://github.com/matrix-org/matrix-doc/issues/1763),
|
||||
[MSC2278](https://github.com/matrix-org/matrix-doc/issues/2278)) are sensitive
|
||||
because there is of course no way to stop a malicious server or client or user
|
||||
ignoring the deletion and somehow retaining the data. (We consider any attempt
|
||||
at trying to use DRM to do so as futile).
|
||||
|
||||
This MSC is intended to:
|
||||
|
||||
* Give a strong commitment to users on trusted clients and servers that
|
||||
message data will not be persisted on Matrix servers and clients beyond the
|
||||
requested timeframe. This is useful for legal purposes in rooms which span
|
||||
only trusted (e.g. private federated) servers, to enforce data retention
|
||||
behaviour.
|
||||
|
||||
* Give a weak commitment to users on untrusted clients and servers (e.g.
|
||||
arbitary users on the public Matrix network) that message data may not be
|
||||
persisted beyond the requested timeframe. This should be adequate for
|
||||
unimportant disappearing messages (e.g. a casual fleeting message which is so
|
||||
unimportant or of such shortlived relevance that it is not worthy of being put
|
||||
in the timeline). It is **not** adequate for attempting to ensure that
|
||||
sensitive content is deleted after reading for legal or security purposes.
|
||||
|
||||
* Help server admins manage diskspace by letting users dictate retention
|
||||
lifetime per message.
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
We could purge rather than redact destructed messages from the DB, but that
|
||||
would fragment the DAG so we don't do that.
|
||||
|
||||
We could have the sending server send an explicit redaction event on behalf of
|
||||
the sender rather than synthesise a redaction on the various participating
|
||||
servers. However, this would clog up the DAG with a redundant event, and also
|
||||
introduce unreliability if the sending server is unavailable or delayed. It
|
||||
would also result in all users redacting the message the same time. Therefore
|
||||
synthetic per-user redaction events (which are only for backwards
|
||||
compatibility anyway) feel like the lesser evil.
|
||||
|
||||
## Issues
|
||||
|
||||
We should probably ignore missing read receipts from bots when deciding
|
||||
whether to self-destruct. This is blocked on having a good way to identify
|
||||
bots. [MSC1206](https://github.com/matrix-org/matrix-doc/pull/1206) provides
|
||||
one possible way, as does
|
||||
[MSC2199](https://github.com/matrix-org/matrix-doc/pull/2199) (important v.
|
||||
unimportant users in immutable DMs).
|
||||
|
||||
The behaviour for rooms with more than 2 participants ends up being a bit
|
||||
strange. The client (and server) starts the expiry countdown on the message as
|
||||
soon as the participant has read it. This means that someone can look over
|
||||
the shoulder of another user to see the content again. This is probably a
|
||||
feature rather than a bug(?)
|
||||
|
||||
## Security considerations
|
||||
|
||||
There's scope for abuse where users can send obnoxious self-destructing messages
|
||||
into a room.
|
||||
|
||||
One solution for this could be for server implementations to implement a
|
||||
quarantine mode which initially marks redacted events as quarantined for N days
|
||||
before deleting them entirely, allowing server admins to address abuse concerns.
|
||||
This is of course true for redactions in general.
|
||||
|
||||
## Conclusion
|
||||
|
||||
This provides a simple and pragmatic way of automating the process of manually
|
||||
redacting sensitive messages once the recipients have read them.
|
Loading…
Reference in New Issue