|
| 1 | +--- |
| 2 | +title: Message redaction |
| 3 | +layout: spec |
| 4 | +work-in-progress: true |
| 5 | +copyrights: |
| 6 | + - |
| 7 | + name: "James Wheare" |
| 8 | + |
| 9 | + period: "2020" |
| 10 | + - |
| 11 | + name: "Val Lorentz" |
| 12 | + |
| 13 | + period: "2023" |
| 14 | +--- |
| 15 | + |
| 16 | +## Notes for implementing work-in-progress version |
| 17 | + |
| 18 | +This is a work-in-progress specification. |
| 19 | + |
| 20 | +Software implementing this work-in-progress specification MUST NOT use the |
| 21 | +unprefixed `message-redaction` capability name. |
| 22 | +Instead, implementations SHOULD use the `draft/message-redaction` capability |
| 23 | +name to be interoperable with other software implementing a compatible |
| 24 | +work-in-progress version. |
| 25 | + |
| 26 | +The final version of the specification will use an unprefixed capability name. |
| 27 | + |
| 28 | +## Introduction |
| 29 | + |
| 30 | +This specification enables messages to be deleted. |
| 31 | +Use cases include retracting accidentally sent messages, moderation, |
| 32 | +and removing a [`+draft/react` client tag][], amongst others. |
| 33 | +These are cosmetic use cases and do not provide any operational security |
| 34 | +guarantees. |
| 35 | + |
| 36 | +## Architecture |
| 37 | + |
| 38 | +### Dependencies |
| 39 | + |
| 40 | +Clients wishing to use this capability MUST negotiate the [`message-tags`][] |
| 41 | +capability with the server. |
| 42 | +Clients SHOULD negotiate the [`echo-message`][] capability in order to receive |
| 43 | +message IDs for their own messages, so they can be redacted. |
| 44 | + |
| 45 | + |
| 46 | +### Capability |
| 47 | + |
| 48 | +This specification adds the `draft/message-redaction` capability. |
| 49 | +Clients MUST ignore this capability's value, if any. |
| 50 | + |
| 51 | +Implementations that negotiate this capability indicate that they are |
| 52 | +capable of handling the command described below. |
| 53 | + |
| 54 | + |
| 55 | +### Command |
| 56 | + |
| 57 | +To redact a message, a client MUST negotiate the `draft/message-redaction` |
| 58 | +capability and send a `REDACT` command to a target nickname or channel. |
| 59 | +The command is defined as follows: |
| 60 | + |
| 61 | + REDACT <target> <msgid> [<reason>] |
| 62 | + |
| 63 | +Where `<msgid>` is the id of the message to be redacted, which MUST be a |
| 64 | +`PRIVMSG`, `NOTICE`, or `TAGMSG`. |
| 65 | + |
| 66 | +An optional `<reason>` MAY be provided. As the last parameter, it MAY contain spaces. |
| 67 | +If the client is authorised to delete the message, the server: |
| 68 | + |
| 69 | +* SHOULD forward this `REDACT`, with an appropriate prefix, to the target |
| 70 | + recipients that have negotiated the `draft/message-redaction` capability, in the |
| 71 | + same way as PRIVMSG messages. |
| 72 | +* MUST not forward this `REDACT` to target recipients that have not negotiated |
| 73 | + this capability (see "Fallback" below) |
| 74 | + |
| 75 | +### Chat history |
| 76 | + |
| 77 | +After a message is redacted, [`chathistory`][] responses SHOULD either: |
| 78 | + |
| 79 | +* exclude it entirely |
| 80 | +* replace its content and/or tags with a placeholder and |
| 81 | + add the `REDACT` message to the response (not counting toward message limits) |
| 82 | + after the redacted message |
| 83 | +* add the `REDACT` message to the response (not counting toward message limits) |
| 84 | + after the redacted message |
| 85 | + |
| 86 | +### Errors |
| 87 | + |
| 88 | +This specification defines `FAIL` messages using the [standard replies][] |
| 89 | +framework for notifying clients of errors with message editing and deletion. |
| 90 | +The following codes are defined, with sample plain text descriptions. |
| 91 | + |
| 92 | +* `FAIL REDACT INVALID_TARGET <target> :You cannot delete messages from <target>` |
| 93 | +* `FAIL REDACT REDACT_FORBIDDEN <target> <target-msgid> :You are not authorised to delete this message` |
| 94 | +* `FAIL REDACT REDACT_WINDOW_EXPIRED <target> <target-msgid> <window> :You can no longer edit this message` |
| 95 | +* `FAIL REDACT UNKNOWN_MSGID <target> <target-msgid> :This message does not exist or is too old` |
| 96 | + |
| 97 | +## Client implementation considerations |
| 98 | + |
| 99 | +It is strongly RECOMMENDED that clients provide visible redaction history to users. |
| 100 | +This helps ensure accountability, and mitigates abuse through malicious or |
| 101 | +surreptitious redaction. This could be done via a tool tip, or a separate log. |
| 102 | +Redacted messages MAY be hidden entirely from the primary message log, |
| 103 | +but a deletion log SHOULD be made available. |
| 104 | + |
| 105 | +For the purposes of user interface, clients MAY assume that their own messages |
| 106 | +are redactable. |
| 107 | +However, this will not always be the case, and there could be other messages |
| 108 | +that they have permission to act on. |
| 109 | +Pending a mechanism for discovering redaction permissions, clients SHOULD |
| 110 | +allow users to attempt to delete any message via some mechanism. |
| 111 | + |
| 112 | +Clients SHOULD NOT provide a default reason if users do not provide one. |
| 113 | + |
| 114 | +When a `REDACT` command's `msgid` parameter references a known message not in |
| 115 | +the `target`'s history, clients MUST ignore it. |
| 116 | +This allows servers to safely relay `REDACT` commands targeting messages which they |
| 117 | +did not keep in their history. |
| 118 | + |
| 119 | +## Server implementation considerations |
| 120 | + |
| 121 | +This section is non-normative. |
| 122 | + |
| 123 | +A key motivation for specifying this capability as a server tag, rather than |
| 124 | +a client-only message tag, is to enable more granular redaction permissions. |
| 125 | +Clients might be able to determine which messages are their own, but other |
| 126 | +use cases would not be feasible without server validation. |
| 127 | + |
| 128 | +Such use cases might include: |
| 129 | + |
| 130 | +* Allowing channel moderators or server admins to delete unwelcome messages from others |
| 131 | +* Specifying a cut-off time after which message edits are no longer allowed |
| 132 | + |
| 133 | +If a message is redacted while a client is not present in a channel, servers may send the `REDACT` command in a `chathistory` batch when it re-joins the channel. |
| 134 | + |
| 135 | +If servers use predictable or guessable `msgid`s, they should consider whether errors |
| 136 | +returned on `REDACT` may leak a message's existence to users who did not receive it |
| 137 | +(in a channel they are/were not in or in private messages). |
| 138 | + |
| 139 | +### Message validation |
| 140 | + |
| 141 | +To implement validation, servers require a mechanism for determining the permissions of |
| 142 | +a particular edit or delete action. |
| 143 | +The user requesting the action would need to be compared against properties of |
| 144 | +the message, given only the message ID and target. |
| 145 | + |
| 146 | +Servers with message history storage could look up the message properties from the ID, |
| 147 | +but this might not be possible or desirable in all cases. |
| 148 | +Another mechanism could involve encoding any required properties within the message ID |
| 149 | +itself, e.g. the account ID, timestamp, etc. Servers might choose to encrypt this |
| 150 | +information if it isn't usually public facing. Any information encoded in a message ID |
| 151 | +is still opaque and not intended to be parsed by clients. |
| 152 | + |
| 153 | +### Fallback |
| 154 | + |
| 155 | +Server implementations might choose to inform clients that haven't negotiated |
| 156 | +the capability that a deletion has taken place. |
| 157 | +The fallback method used (if any) is left up to server implementations, but |
| 158 | +could take the form of a standard NOTICE or PRIVMSG with information about the |
| 159 | +action. |
| 160 | +It might be preferable to use relative time descriptions if referring to |
| 161 | +messages in the past, for example: |
| 162 | + |
| 163 | + :irc.example.com NOTICE #channel :nickname redacted a message from othernick from 5 seconds ago: spam |
| 164 | + |
| 165 | +Implementations might also choose not to send a fallback, if this behaviour |
| 166 | +is considered too noisy for users. |
| 167 | + |
| 168 | +## Security considerations |
| 169 | + |
| 170 | +The ability to delete messages does not offer any information or operational |
| 171 | +security guarantees. |
| 172 | +Once a message has been sent, assume that it will remain visible to any |
| 173 | +recipients or servers, whether or not it is subsequently redacted. |
| 174 | +Above all else, clients that do not support this specification will not see |
| 175 | +any changes to the original message. |
| 176 | + |
| 177 | +## Examples |
| 178 | + |
| 179 | +Deleting a PRIVMSG: |
| 180 | + |
| 181 | + C: PRIVMSG #channel :an example |
| 182 | + S: @msgid=123 :nick!u@h PRIVMSG #channel :an example |
| 183 | + C: REDACT #channel 123 :bad example |
| 184 | + S: :nick!u@h REDACT #channel 123 :bad example |
| 185 | + |
| 186 | +Deleting a TAGMSG: |
| 187 | + |
| 188 | + C: @draft/react=🤞TAGMSG #channel |
| 189 | + S: @msgid=123;draft/react=🤞TAGMSG #channel |
| 190 | + C: REDACT #channel 123 |
| 191 | + S: :nick@u@h REDACT #channel 123 |
| 192 | + |
| 193 | +Deleting someone else's PRIVMSG: |
| 194 | + |
| 195 | + C1: PRIVMSG #channel :join my network for cold hard chats |
| 196 | + S: @msgid=123 :nick!u@h PRIVMSG #channel :join my network for cold hard chats |
| 197 | + C2: REDACT #channel 123 spam |
| 198 | + S: :chanop!u@h REDACT #channel 123 spam |
| 199 | + |
| 200 | + |
| 201 | +[`echo-message`]: ../extensions/echo-message.html |
| 202 | +[`+draft/react` client tag]: ../client-tags/react.html |
| 203 | +[standard replies]: ../extensions/standard-replies.html |
| 204 | +[`message-tags`]: ../extensions/message-tags.html |
| 205 | +[`msgid`]: ../extensions/message-ids.html |
| 206 | +[`chathistory`]: ../extensions/chathistory.html |
0 commit comments