From 1cafc1657fbf75bc9265c34c64b00cdfba3cbaa8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 27 May 2025 15:48:37 -0600 Subject: [PATCH 01/14] MSC: Redact on ban --- proposals/4293-redact-on-ban.md | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 proposals/4293-redact-on-ban.md diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md new file mode 100644 index 00000000000..b0f2876d509 --- /dev/null +++ b/proposals/4293-redact-on-ban.md @@ -0,0 +1,103 @@ +# MSC4293: Redact on ban + +[MSC2244 (accepted)](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/2244-mass-redactions.md)-style +mass redactions are incredibly helpful for cleaning up large volumes of spam, but still require sending +a dedicated event to clean up the spam. In a typical case, a user will get kicked/banned from a room +and the moderators will further redact some or all of their messages. Mass redactions have more use +cases, but the specific case of "redact everything upon ban" is something which may be easily backported +to existing room versions. + +This proposal suggests adding a new flag to membership events to indicate to clients and servers that +all of that user's events should be redacted in addition to being kicked or banned. The flag isn't +protected from redaction itself, so may have some consistency issues, but overall should still provide +relatively high amounts of protection to rooms. + +This proposal is exploratory and subject to change. Implementations may validate the idea through +early feature support, but MUST expect that things will change (or become completely rejected). + +## Proposal + +A new flag is added to [`m.room.member`](https://spec.matrix.org/v1.14/client-server-api/#mroommember) +events where the target user is kicked or banned (**TODO**: Allow on self-leaves too?): `redact_events`. +This flag is a boolean and, when `true`, causes servers (and clients) to redact all of the user's events +as though they received an [`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction), +including adding [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) to +`unsigned` where applicable. + +**Note**: This also means that if the user was kicked/banned with a `reason`, that event is automatically +compatible with the redaction `reason` field and shows up accordingly. + +This redaction behaviour continues until the membership event itself is redacted (thus removing the +field) or another membership event removes the field. For example, if the user is unbanned, the moderator +MAY NOT choose to carry the `redact_events` flag to that kick (unban) event. Or, when the user rejoins +after a kick, the flag is implicitly dropped. + +Other membership states with the flag no-op, such as joins. + +Moderation bots and similar MAY still wish to issue (mass) redactions upon kick/ban to protect users +on servers or clients which don't have this feature. + +Example ban: + +```jsonc +{ + // Irrelevant fields excluded + "type": "m.room.member", + "state_key": "@spam:example.org", + "sender": "@mod:example.org", + "content": { + "membership": "ban", + "reason": "flooding", // this is copied to `redacted_because`, leading to clients showing it + "redact_events": true + } +} +``` + +The new field is proxied through to the event by the [`/kick`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidkick) +and [`/ban`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidban) +sugar APIs, like `reason` is. + +## Potential issues + +It's a little annoying that the flag is redacted when the membership event is redacted, however it's +extremely rare for a moderator/admin to redact a kick or ban event. We can fix this in a room version +trivially if it proves to be an issue. + +Clients may miss the membership event if they are using lazy loading, though servers should already +be tracking which membership events the client has received and needs to render events in the timeline. +This should mean that those clients will still receive the event. + +Servers which miss the event will eventually receive or retrieve it, just like they would with any +other event. + +## Alternatives + +Mass redactions are the cited major alternative, where a single event can target approximately 1500 +other events in the room. New rooms can benefit from that functionality, especially for cases not +covered by this proposal, while existing rooms can be given an option to protect their users with +relative ease. + +## Security considerations + +As the room moderator/administrator would already send redactions, and may still for full protection, +it's not deemed any more risk than today. This may change if self-leaves are permitted to also carry +the field. + +There may also be implementation or reliability bugs which inhibit the "stop redacting now" point +from working as intended. Server implementations in particular should ensure that an event received +after a membership event which asks for redaction is *really* affected by that redaction. ie: whether +it's just a late delivery, or if there's a join waiting for state res to make a determination. + + +## Unstable prefix + +While this proposal is not considered stable, implementations should use `org.matrix.msc4293.redact_events` +instead of `redact_events`. + +## Dependencies + +This MSC has no direct dependencies. + +## Credits + +Credit goes to Erik of the Spec Core Team for the suggestion to look into this. From b9391a028b3ba199a20c52a0b262f18650430a8f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 10 Jun 2025 17:18:56 -0600 Subject: [PATCH 02/14] Add some clarity --- proposals/4293-redact-on-ban.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index b0f2876d509..f5d8941761d 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -22,17 +22,27 @@ events where the target user is kicked or banned (**TODO**: Allow on self-leaves This flag is a boolean and, when `true`, causes servers (and clients) to redact all of the user's events as though they received an [`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction), including adding [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) to -`unsigned` where applicable. +`unsigned` where applicable. An `m.room.redaction` event is not actually sent, however. **Note**: This also means that if the user was kicked/banned with a `reason`, that event is automatically compatible with the redaction `reason` field and shows up accordingly. -This redaction behaviour continues until the membership event itself is redacted (thus removing the -field) or another membership event removes the field. For example, if the user is unbanned, the moderator -MAY NOT choose to carry the `redact_events` flag to that kick (unban) event. Or, when the user rejoins -after a kick, the flag is implicitly dropped. +Similar to regular redactions, if the sender of the membership event can't actually redact the target's +events, the redaction doesn't apply. This means having a power level higher than or equal to `redacts` +*and* `events["m.room.redaction"]` (if set). Normally, `m.room.redaction` events could be rejected +due to the power levels - that rejection behaviour doesn't apply with the `redact_events` field. +Instead, the target's events are simply not redacted. -Other membership states with the flag no-op, such as joins. +If the sender is allowed to redact, the redaction behaviour continues until the membership event itself +is redacted (thus removing the field) or another membership event removes the field. For example, if +the user is unbanned, the moderator MAY NOT choose to carry the `redact_events` flag to that kick +(unban) event. Or, when the user rejoins after a kick, the flag is implicitly dropped. + +Events which are delivered after the ban are likely [soft failed](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) +and are still redacted if the current membership event in the room has a valid `redact_events` +field. + +Other membership states with the flag no-op, such as joins, knocks, and invites. Moderation bots and similar MAY still wish to issue (mass) redactions upon kick/ban to protect users on servers or clients which don't have this feature. @@ -60,8 +70,13 @@ sugar APIs, like `reason` is. ## Potential issues It's a little annoying that the flag is redacted when the membership event is redacted, however it's -extremely rare for a moderator/admin to redact a kick or ban event. We can fix this in a room version -trivially if it proves to be an issue. +extremely rare for a moderator/admin to redact a kick or ban event. This can be fixed in a future +room version, like what is proposed by [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). + +Though extremely rare, if an existing server in the room didn't apply the redactions *and* a sender's +ban was redacted, a new server to the room may backfill through that existing server and see unredacted +events without knowing it's supposed to redact them due to the ban having lost the `redact_events` +field. This is fixed for future room versions by implementing something like [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). Clients may miss the membership event if they are using lazy loading, though servers should already be tracking which membership events the client has received and needs to render events in the timeline. @@ -88,7 +103,6 @@ from working as intended. Server implementations in particular should ensure tha after a membership event which asks for redaction is *really* affected by that redaction. ie: whether it's just a late delivery, or if there's a join waiting for state res to make a determination. - ## Unstable prefix While this proposal is not considered stable, implementations should use `org.matrix.msc4293.redact_events` From 6d92bbaa5b024c869b25fdf8355ed92bc85b36c3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 20 Jun 2025 17:55:04 -0600 Subject: [PATCH 03/14] Add more considerations --- proposals/4293-redact-on-ban.md | 53 ++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index f5d8941761d..384e2973fa3 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -12,26 +12,23 @@ all of that user's events should be redacted in addition to being kicked or bann protected from redaction itself, so may have some consistency issues, but overall should still provide relatively high amounts of protection to rooms. -This proposal is exploratory and subject to change. Implementations may validate the idea through -early feature support, but MUST expect that things will change (or become completely rejected). - ## Proposal A new flag is added to [`m.room.member`](https://spec.matrix.org/v1.14/client-server-api/#mroommember) -events where the target user is kicked or banned (**TODO**: Allow on self-leaves too?): `redact_events`. -This flag is a boolean and, when `true`, causes servers (and clients) to redact all of the user's events -as though they received an [`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction), -including adding [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) to -`unsigned` where applicable. An `m.room.redaction` event is not actually sent, however. +events where the target user is kicked or banned: `redact_events`. This flag is a boolean and, when +`true`, causes servers (and clients) to redact all of the user's events as though they received an +[`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction), including +adding [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) to `unsigned` +where applicable. An `m.room.redaction` event is not actually sent, however. **Note**: This also means that if the user was kicked/banned with a `reason`, that event is automatically compatible with the redaction `reason` field and shows up accordingly. Similar to regular redactions, if the sender of the membership event can't actually redact the target's events, the redaction doesn't apply. This means having a power level higher than or equal to `redacts` -*and* `events["m.room.redaction"]` (if set). Normally, `m.room.redaction` events could be rejected -due to the power levels - that rejection behaviour doesn't apply with the `redact_events` field. -Instead, the target's events are simply not redacted. +*and* `events["m.room.redaction"]` (if set). We maintain the `events` check despite not actually sending +events of that type to keep the same expectations within rooms. If the sender doesn't have permission +to redact an event normally, no redaction is applied. If the sender is allowed to redact, the redaction behaviour continues until the membership event itself is redacted (thus removing the field) or another membership event removes the field. For example, if @@ -67,6 +64,28 @@ The new field is proxied through to the event by the [`/kick`](https://spec.matr and [`/ban`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidban) sugar APIs, like `reason` is. +## Fallback behaviour + +Servers which don't support this feature may be served redacted events over federation when attempting +to fill gaps or backfill. This is considered expected behaviour. + +Clients which don't support this feature may see events remain unredacted until they clear their local +cache. Upon clearing or invalidating their cache, they will either receive redacted events if their +server supports the feature or unredacted events otherwise. + +To (primarily) help protect users on unsupported *clients*, implementations SHOULD continue to try +sending individual redaction events in addition to the redact-on-ban flag. They MAY cease to do so +once they are comfortable with the level of adoption for this proposal. Servers in particular SHOULD +assist clients and send individual redaction events on their behalf, meaning clients SHOULD wait a +little bit before trying to issue redactions themselves. For example, a client may ban a user, wait +a minute, then start sending redactions if it hasn't seen an `m.room.redaction` event targeting some +of the banned user's events. Servers MAY deduplicate redactions to lower federation load, as they +always could. + +**Note**: It is possible due to implementation and real-world constraints that not all individual +redactions will "make it" over federation to another server. This is why mass redaction approaches +are preferred, as they are significantly more reliable. + ## Potential issues It's a little annoying that the flag is redacted when the membership event is redacted, however it's @@ -85,6 +104,11 @@ This should mean that those clients will still receive the event. Servers which miss the event will eventually receive or retrieve it, just like they would with any other event. +Moderation bots/clients which attempt to reduce the amount of duplicate work they do may need to +inspect `redacted_because` instead of checking for its presence to determine which kind of redaction +was applied to a given event. This is especially true if the moderation bot/client is providing the +fallback support described above. + ## Alternatives Mass redactions are the cited major alternative, where a single event can target approximately 1500 @@ -92,6 +116,13 @@ other events in the room. New rooms can benefit from that functionality, especia covered by this proposal, while existing rooms can be given an option to protect their users with relative ease. +## Future considerations + +It may be desirable to place this behaviour on self-leaves too, allowing for faster removal of one's +own messages/events. This proposal doesn't suggest adding this functionality here to maintain narrow +scope on T&S functionality. A future proposal may introduce this, or rely on regular mass redactions +instead. + ## Security considerations As the room moderator/administrator would already send redactions, and may still for full protection, From 687db4ccfc6e2dae07a7f34b6d9f76e2ec756f0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 26 Jun 2025 13:45:04 -0600 Subject: [PATCH 04/14] Misc clarifications --- proposals/4293-redact-on-ban.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index 384e2973fa3..b9093f126e3 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -31,9 +31,13 @@ events of that type to keep the same expectations within rooms. If the sender do to redact an event normally, no redaction is applied. If the sender is allowed to redact, the redaction behaviour continues until the membership event itself -is redacted (thus removing the field) or another membership event removes the field. For example, if -the user is unbanned, the moderator MAY NOT choose to carry the `redact_events` flag to that kick -(unban) event. Or, when the user rejoins after a kick, the flag is implicitly dropped. +is redacted (thus removing the field), another membership event removes the field, or the flag is set +to `false`. Events already redacted up to that point remain redacted after the flag changes to a falsey +value. For example, if the user is unbanned, the moderator MAY NOT choose to carry the `redact_events` +flag to that kick (unban) event. Or, when the user rejoins after a kick, the flag is implicitly dropped. + +In essence, the `redact_events` flag applies to all events which topologically come before the falsey +value. Events which are delivered after the ban are likely [soft failed](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) and are still redacted if the current membership event in the room has a valid `redact_events` @@ -109,6 +113,21 @@ inspect `redacted_because` instead of checking for its presence to determine whi was applied to a given event. This is especially true if the moderation bot/client is providing the fallback support described above. +If a user is banned using `redact_events: true`, unbanned, rejoins, sends more events, and is banned +again using `redact_events: true`, the user's events between bans will be subsequently redacted. The +events redacted by the first ban may also be re-redacted by servers/clients depending on implementation. +This is considered expected behaviour, and implementations can internally track which events they've +already auto-redacted to avoid duplicate work. + +With respect to the fallback behaviour, a client might not know if a server is applying fallback +redactions and may not wish to wait an arbitrary amount of time to see if it does. One solution would +be to have the server expose a [capability](https://spec.matrix.org/v1.15/client-server-api/#capabilities-negotiation), +however such a flag would be longer lived than the fallback behaviour itself (hopefully). Instead, +clients which don't implement watchdog functionality SHOULD send redactions anyway, even if it +duplicates the server's fallback efforts. Further, as already mentioned above, server MAY deduplicate +redactions to lower their federation load, though this is closer to a SHOULD considering clients are +already sending their own redaction events (like in the case of Mjolnir). + ## Alternatives Mass redactions are the cited major alternative, where a single event can target approximately 1500 From aabe7518cc96cd14fbf68dda7de12ab5077e993f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Jul 2025 15:40:12 -0600 Subject: [PATCH 05/14] Update proposals/4293-redact-on-ban.md Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/4293-redact-on-ban.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index b9093f126e3..eb25667e566 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -25,7 +25,7 @@ where applicable. An `m.room.redaction` event is not actually sent, however. compatible with the redaction `reason` field and shows up accordingly. Similar to regular redactions, if the sender of the membership event can't actually redact the target's -events, the redaction doesn't apply. This means having a power level higher than or equal to `redacts` +events, the redaction doesn't apply. This means having a power level higher than or equal to `redact` *and* `events["m.room.redaction"]` (if set). We maintain the `events` check despite not actually sending events of that type to keep the same expectations within rooms. If the sender doesn't have permission to redact an event normally, no redaction is applied. From b06afd7d6d3f54a1939d907b4afdd8c2668627f1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 22:16:22 -0600 Subject: [PATCH 06/14] Rewrite intro & problem statement --- proposals/4293-redact-on-ban.md | 73 ++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index eb25667e566..df9ea2eb995 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -1,16 +1,67 @@ -# MSC4293: Redact on ban +# MSC4293: Redact on kick/ban [MSC2244 (accepted)](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/2244-mass-redactions.md)-style -mass redactions are incredibly helpful for cleaning up large volumes of spam, but still require sending -a dedicated event to clean up the spam. In a typical case, a user will get kicked/banned from a room -and the moderators will further redact some or all of their messages. Mass redactions have more use -cases, but the specific case of "redact everything upon ban" is something which may be easily backported -to existing room versions. - -This proposal suggests adding a new flag to membership events to indicate to clients and servers that -all of that user's events should be redacted in addition to being kicked or banned. The flag isn't -protected from redaction itself, so may have some consistency issues, but overall should still provide -relatively high amounts of protection to rooms. +mass redactions are incredibly helpful for cleaning up large volumes of spam, especially because they +reduce the total number of events a server needs to process in order to clean up a room. However, they +have a few issues: + +1. To populate the target events, the sender needs to know which event IDs to target. Events may be + [soft failed](https://spec.matrix.org/v1.15/server-server-api/#soft-failure) by the moderator's + local homeserver, which may prevent the sender's client from seeing them. Further, there may be + timeline gaps which limit the sender's visibility on the events to target. + + This may be fixed by adding a "sugar API" like `/room/:roomId/redact/:userId` which causes the + server to calculate event ID targets and send out one or more mass redactions, though this would + only be effective if the server had all of the user's events at the time of the call. If an event + came in late for any reason, the sent redactions might not target it, allowing the likely spam + through to the room. + + Proposals such as [MSC4194](https://github.com/matrix-org/matrix-doc/pull/4194) explore this + solution. + +2. Dedicated events must still be sent in order to perform the redaction, many of which might not be + small if there's lots of events being targeted. This can impact bandwidth and data storage, though + not as badly as trying to redact large volumes of spam without mass redactions. + +3. MSC2244 mass redactions are breaking for clients which perform redaction locally due to changing + the type of `redacts` on `m.room.redaction` events from a string (single event ID) to an array. + This is in part mitigated by MSC2244 through a new room version, though clients are currently + unable to opt out of incompatible room versions. + + It's also possible to mitigate this concern by using a new event type for mass redactions instead. + This alternative is explored in **TODO: Future MSC here**. + +4. Due to changes in event authorization, MSC2244 requires a new room version in order to function. + This limits the feature to new rooms or those which upgrade to a new enough version. Theoretically, + it's possible to allow mass redactions in existing room versions anyway, though the redactions may + get rejected due to the very authorization rules MSC2244 changes. This may cause senders to target + a small number of events per mass redaction to avoid the possibility of spam being left visible + due to a single event target not being present on the receiving homeserver. + +To work around these issues, this proposal suggests adding a new flag to membership events to indicate +to clients and servers that all of that user's events should be redacted in addition to being kicked +or banned. There are still drawbacks for existing room versions with this approach, namely that the +new flag isn't protected from redaction itself and may cause problems, but it does allow moderators +to take an action they were going to anyway: ban & redact everything the user ever sent, without +needing to wait for a new room version to roll out. + +By applying the flag to a user ID instead of an event ID (or set of event IDs), the consumer's local +view is considered instead of the sender's: a redaction for "all of `@alice:example.org`'s events" +when applied by a client removes all events visible to that client. Similarly, that redaction applied +by a server to their local database will redact whatever events the server has already seen, or will +see in the future. + +Though this MSC isn't breaking for clients in the same way that MSC2244 is, clients (and to a degree, +servers) may not support the MSC right away. This means that senders may still have to send "fallback +redactions" to ensure the room is cleaned up, though those senders can begin to treat those redactions +as best effort (currently, moderation bots in particular work incredibly hard to ensure they get *every* +event redacted, but can run into delivery, reliability, and completeness issues with 1:1 redactions). + +It's also important to note that this proposal intends to compliment mass redactions and coexist in +whatever room version mass redactions land in. This proposal has narrow scope and is fairly blunt as +a measure, which may not be desirable in all situations. For example, only a user's last dozen or so +messages may be worth redacting rather than the hundreds they sent prior to the ones which got them +banned. This proposal does not support such a use case, but mass redactions do. ## Proposal From 244082afac23617e0857df2728e60ef1e4263945 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 22:59:48 -0600 Subject: [PATCH 07/14] Clarify proposal body and adjust the fallback recommendation --- proposals/4293-redact-on-ban.md | 173 ++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 63 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index df9ea2eb995..d1c81967a92 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -66,44 +66,80 @@ banned. This proposal does not support such a use case, but mass redactions do. ## Proposal A new flag is added to [`m.room.member`](https://spec.matrix.org/v1.14/client-server-api/#mroommember) -events where the target user is kicked or banned: `redact_events`. This flag is a boolean and, when -`true`, causes servers (and clients) to redact all of the user's events as though they received an -[`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction), including -adding [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) to `unsigned` -where applicable. An `m.room.redaction` event is not actually sent, however. - -**Note**: This also means that if the user was kicked/banned with a `reason`, that event is automatically -compatible with the redaction `reason` field and shows up accordingly. - -Similar to regular redactions, if the sender of the membership event can't actually redact the target's -events, the redaction doesn't apply. This means having a power level higher than or equal to `redact` -*and* `events["m.room.redaction"]` (if set). We maintain the `events` check despite not actually sending -events of that type to keep the same expectations within rooms. If the sender doesn't have permission -to redact an event normally, no redaction is applied. - -If the sender is allowed to redact, the redaction behaviour continues until the membership event itself -is redacted (thus removing the field), another membership event removes the field, or the flag is set -to `false`. Events already redacted up to that point remain redacted after the flag changes to a falsey -value. For example, if the user is unbanned, the moderator MAY NOT choose to carry the `redact_events` -flag to that kick (unban) event. Or, when the user rejoins after a kick, the flag is implicitly dropped. - -In essence, the `redact_events` flag applies to all events which topologically come before the falsey -value. - -Events which are delivered after the ban are likely [soft failed](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) -and are still redacted if the current membership event in the room has a valid `redact_events` -field. - -Other membership states with the flag no-op, such as joins, knocks, and invites. - -Moderation bots and similar MAY still wish to issue (mass) redactions upon kick/ban to protect users -on servers or clients which don't have this feature. +events where the target user is kicked or banned: `redact_events`. This flag is a boolean and has two +effects when `true`: + +1. Clients apply the redaction algorithm to events sent by that user which are cached locally, up to + the point of the user's previous membership event. No [`m.room.redaction`](https://spec.matrix.org/v1.14/client-server-api/#mroomredaction) + events are sent by the client, but the user's events are redacted as though there was such an event. + +2. Servers perform the same function as clients, also not actually sending any `m.room.redaction` + events. Instead, the user's events are redacted locally by the server. When serving events redacted + in this way, the [`redacted_because`](https://spec.matrix.org/v1.14/client-server-api/#redactions) + field is populated using the membership event, like so: + + ```jsonc + { + // irrelevant fields not shown + + "type": "m.room.message", + "sender": "@banned:example.org", + "content": {}, // because the event is redacted, `content` is empty + "unsigned": { + "redacted_because": { + // irrelevant fields also not shown here + + "type": "m.room.member", + "sender": "@moderator:example.org", + "state_key": "@banned:example.org", + "content": { + "membership": "ban", + "reason": "spam", + "redact_events": true + } + } + } + } + ``` + + Note that because `m.room.redaction` supports a `reason` field in the same place as `m.room.member`, + clients which look up that reason by going `event["unsigned"]["content"]["reason"]` will still get + a renderable, human-readable, string for their UI regardless of how the event was actually redacted. + +When `redact_events` is `false`, it acts as though it was not specified: no redactions are applied, +exactly like how bans work prior to this proposal. + +Prior to applying the effects of redaction above, clients and servers MUST ensure that the sender of +the kick or ban has power level to redact the target user's events. This means having a power level +higher than or equal to `redact` *and* `events["m.room.redaction"]` (if set). We maintain the `events` +check despite not actually sending events of that type to keep the same expectations within rooms. If +the sender doesn't have permission to redact an event normally, no the `redact_events` flag is ignored +(and therefore no redaction effect is applied). + +Events which are delivered after the kick or ban are likely [soft failed](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) +and are still redacted by servers if the user's *current* membership event has `redact_events: true`. + +The `redact_events` flag has no effect when present on any other membership state, such as joins, +knocks, invites, and voluntary leaves (non-kicks). + +**Note**: Due to this proposal being enabled in existing room versions, the `redact_events` flag may +become redacted when a user's `m.room.member` event is redacted too. When this happens, the redactions +already applied up to that point are *not* undone, though clients/servers which purge the events and +re-fetch them might receive unredacted copies if they originate from a server which didn't apply this +proposal's effects. Future proposals like [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298) +protect the flag from redaction, avoiding the awkward state where events might be redacted for no +discernable reason after the membership event itself is redacted. + +`redact_events` is also added to the [`/kick`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidkick) +and [`/ban`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidban) +endpoints and is proxied to the resulting event just like `reason` is. It is optional on these endpoints. -Example ban: +An example ban event is: ```jsonc { // Irrelevant fields excluded + "type": "m.room.member", "state_key": "@spam:example.org", "sender": "@mod:example.org", @@ -115,9 +151,26 @@ Example ban: } ``` -The new field is proxied through to the event by the [`/kick`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidkick) -and [`/ban`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidban) -sugar APIs, like `reason` is. +An example sccenario would be: + +1. Alice joins the room. +2. Alice sends events A, B, and C. +3. Alice leaves the room. +4. For whatever reason, Alice rejoins the room. +5. Alice sends events D, E, and F. +6. Bob bans Alice with `redact_events: true`. +7. Clients and servers apply redactions to events D, E, and F, but *not* A, B, or C. No actual + `m.room.redaction` events are sent in this example. +8. Alice's event F arrive's late to Bob's server. +9. Bob's server soft fails F because it fails current auth state (Alice is banned), and redacts it + because `redact_events: true` is set on Alice's ban. There are still no actual `m.room.redaction` + events sent here. + +Events A, B, and C are not redacted because Alice's leave event at step 3 has an implied `redact_events: false`. + +Moderation bots and similar MAY still wish to issue (mass) redactions upon kick/ban to protect users +on servers or clients which don't have this feature. + ## Fallback behaviour @@ -126,20 +179,21 @@ to fill gaps or backfill. This is considered expected behaviour. Clients which don't support this feature may see events remain unredacted until they clear their local cache. Upon clearing or invalidating their cache, they will either receive redacted events if their -server supports the feature or unredacted events otherwise. - -To (primarily) help protect users on unsupported *clients*, implementations SHOULD continue to try -sending individual redaction events in addition to the redact-on-ban flag. They MAY cease to do so -once they are comfortable with the level of adoption for this proposal. Servers in particular SHOULD -assist clients and send individual redaction events on their behalf, meaning clients SHOULD wait a -little bit before trying to issue redactions themselves. For example, a client may ban a user, wait -a minute, then start sending redactions if it hasn't seen an `m.room.redaction` event targeting some -of the banned user's events. Servers MAY deduplicate redactions to lower federation load, as they -always could. - -**Note**: It is possible due to implementation and real-world constraints that not all individual -redactions will "make it" over federation to another server. This is why mass redaction approaches -are preferred, as they are significantly more reliable. +server supports the feature, or unredacted events otherwise. This is also considered expected behaviour. + +Though this proposal makes it clear that `m.room.redaction` events aren't actually sent, senders of +kicks/bans MAY still send actual redactions in addition to `redact_events: true` to ensure that older +clients and servers have the best possible chance of redacting the event. These redactions SHOULD be +considered "best effort" by the sender as they may encounter delivery issues, especially when using +1:1 redactions instead of mass redactions. "Best effort" might mean using endpoints like +[MSC4194](https://github.com/matrix-org/matrix-spec-proposals/pull/4194)'s batch redaction, or using +the less reliable `/messages` endpoint to locate target event IDs to redact. Senders SHOULD note that +this fallback behaviour will only target events they can see (or be made to see via MSC4194) and might +not be the same events that a receiving client or server sees. + +Senders are encouraged to evaluate when they can cease sending fallback redactions like those described +above to minimize the event traffic involved in a ban. For moderation bots this may mean waiting for +sufficiently high *client* implementations existing in their communities. ## Potential issues @@ -160,7 +214,7 @@ Servers which miss the event will eventually receive or retrieve it, just like t other event. Moderation bots/clients which attempt to reduce the amount of duplicate work they do may need to -inspect `redacted_because` instead of checking for its presence to determine which kind of redaction +inspect `redacted_because`'s `type` instead of checking for its presence to determine which kind of redaction was applied to a given event. This is especially true if the moderation bot/client is providing the fallback support described above. @@ -170,21 +224,14 @@ events redacted by the first ban may also be re-redacted by servers/clients depe This is considered expected behaviour, and implementations can internally track which events they've already auto-redacted to avoid duplicate work. -With respect to the fallback behaviour, a client might not know if a server is applying fallback -redactions and may not wish to wait an arbitrary amount of time to see if it does. One solution would -be to have the server expose a [capability](https://spec.matrix.org/v1.15/client-server-api/#capabilities-negotiation), -however such a flag would be longer lived than the fallback behaviour itself (hopefully). Instead, -clients which don't implement watchdog functionality SHOULD send redactions anyway, even if it -duplicates the server's fallback efforts. Further, as already mentioned above, server MAY deduplicate -redactions to lower their federation load, though this is closer to a SHOULD considering clients are -already sending their own redaction events (like in the case of Mjolnir). +With respect to the fallback behaviour, it's not great that implementations, and in particular +moderation bots, need to maintain their "find all events sent by this user and redact them" behaviour. +[MSC4194](https://github.com/matrix-org/matrix-spec-proposals/pull/4194) should help with this, though +has the limitations discussed throughout this MSC when applied to this proposal's use case. ## Alternatives -Mass redactions are the cited major alternative, where a single event can target approximately 1500 -other events in the room. New rooms can benefit from that functionality, especially for cases not -covered by this proposal, while existing rooms can be given an option to protect their users with -relative ease. +Alternatives are discussed inline on this proposal and in the introduction. ## Future considerations From a78f536bb944163dacd29bff5eec6fae4feba4e3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 23:01:32 -0600 Subject: [PATCH 08/14] Clarify early that self-leaves aren't allowed --- proposals/4293-redact-on-ban.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index d1c81967a92..b386b7083fa 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -66,7 +66,8 @@ banned. This proposal does not support such a use case, but mass redactions do. ## Proposal A new flag is added to [`m.room.member`](https://spec.matrix.org/v1.14/client-server-api/#mroommember) -events where the target user is kicked or banned: `redact_events`. This flag is a boolean and has two +events where the target user is kicked or banned: `redact_events`. Discussed later, this new flag has +no effect when applied to self-leaves or other membership states. This flag is a boolean and has two effects when `true`: 1. Clients apply the redaction algorithm to events sent by that user which are cached locally, up to From d9413f5acfb5bf3945dceae18bf66b3ab24cf1b2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 23:04:49 -0600 Subject: [PATCH 09/14] typo --- proposals/4293-redact-on-ban.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index b386b7083fa..e1394936b1a 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -129,7 +129,7 @@ already applied up to that point are *not* undone, though clients/servers which re-fetch them might receive unredacted copies if they originate from a server which didn't apply this proposal's effects. Future proposals like [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298) protect the flag from redaction, avoiding the awkward state where events might be redacted for no -discernable reason after the membership event itself is redacted. +discernible reason after the membership event itself is redacted. `redact_events` is also added to the [`/kick`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidkick) and [`/ban`](https://spec.matrix.org/v1.14/client-server-api/#post_matrixclientv3roomsroomidban) From 0946c5cc2c049e610bbd024f6c3fa1b62445df07 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 23:33:44 -0600 Subject: [PATCH 10/14] cite MSC4343 --- proposals/4293-redact-on-ban.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index e1394936b1a..86a42d53d2e 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -29,7 +29,7 @@ have a few issues: unable to opt out of incompatible room versions. It's also possible to mitigate this concern by using a new event type for mass redactions instead. - This alternative is explored in **TODO: Future MSC here**. + This alternative is explored in [MSC4343](https://github.com/matrix-org/matrix-spec-proposals/pull/4343). 4. Due to changes in event authorization, MSC2244 requires a new room version in order to function. This limits the feature to new rooms or those which upgrade to a new enough version. Theoretically, From ebc60f113220447f2ea1f030f520c68cc48158ad Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Sep 2025 09:25:19 -0600 Subject: [PATCH 11/14] format potential issues --- proposals/4293-redact-on-ban.md | 62 ++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index 86a42d53d2e..5ca4e11e998 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -198,37 +198,37 @@ sufficiently high *client* implementations existing in their communities. ## Potential issues -It's a little annoying that the flag is redacted when the membership event is redacted, however it's -extremely rare for a moderator/admin to redact a kick or ban event. This can be fixed in a future -room version, like what is proposed by [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). - -Though extremely rare, if an existing server in the room didn't apply the redactions *and* a sender's -ban was redacted, a new server to the room may backfill through that existing server and see unredacted -events without knowing it's supposed to redact them due to the ban having lost the `redact_events` -field. This is fixed for future room versions by implementing something like [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). - -Clients may miss the membership event if they are using lazy loading, though servers should already -be tracking which membership events the client has received and needs to render events in the timeline. -This should mean that those clients will still receive the event. - -Servers which miss the event will eventually receive or retrieve it, just like they would with any -other event. - -Moderation bots/clients which attempt to reduce the amount of duplicate work they do may need to -inspect `redacted_because`'s `type` instead of checking for its presence to determine which kind of redaction -was applied to a given event. This is especially true if the moderation bot/client is providing the -fallback support described above. - -If a user is banned using `redact_events: true`, unbanned, rejoins, sends more events, and is banned -again using `redact_events: true`, the user's events between bans will be subsequently redacted. The -events redacted by the first ban may also be re-redacted by servers/clients depending on implementation. -This is considered expected behaviour, and implementations can internally track which events they've -already auto-redacted to avoid duplicate work. - -With respect to the fallback behaviour, it's not great that implementations, and in particular -moderation bots, need to maintain their "find all events sent by this user and redact them" behaviour. -[MSC4194](https://github.com/matrix-org/matrix-spec-proposals/pull/4194) should help with this, though -has the limitations discussed throughout this MSC when applied to this proposal's use case. +1. It's a little annoying that the flag is redacted when the membership event is redacted, however it's + extremely rare for a moderator/admin to redact a kick or ban event. This can be fixed in a future + room version, like what is proposed by [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). + +2. Though extremely rare, if an existing server in the room didn't apply the redactions *and* a sender's + ban was redacted, a new server to the room may backfill through that existing server and see unredacted + events without knowing it's supposed to redact them due to the ban having lost the `redact_events` + field. This is fixed for future room versions by implementing something like [MSC4298](https://github.com/matrix-org/matrix-spec-proposals/pull/4298). + +3. Clients may miss the membership event if they are using lazy loading, though servers should already + be tracking which membership events the client has received and needs to render events in the timeline. + This should mean that those clients will still receive the event. + + Servers which miss the event will eventually receive or retrieve it, just like they would with any + other event. + +4. Moderation bots/clients which attempt to reduce the amount of duplicate work they do may need to + inspect `redacted_because`'s `type` instead of checking for its presence to determine which kind of redaction + was applied to a given event. This is especially true if the moderation bot/client is providing the + fallback support described above. + +5. If a user is banned using `redact_events: true`, unbanned, rejoins, sends more events, and is banned + again using `redact_events: true`, the user's events between bans will be subsequently redacted. The + events redacted by the first ban may also be re-redacted by servers/clients depending on implementation. + This is considered expected behaviour, and implementations can internally track which events they've + already auto-redacted to avoid duplicate work. + +6. With respect to the fallback behaviour, it's not great that implementations, and in particular + moderation bots, need to maintain their "find all events sent by this user and redact them" behaviour. + [MSC4194](https://github.com/matrix-org/matrix-spec-proposals/pull/4194) should help with this, though + has the limitations discussed throughout this MSC when applied to this proposal's use case. ## Alternatives From 209cad309df660521fa161135e9261ef8ade7a65 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Sep 2025 09:49:47 -0600 Subject: [PATCH 12/14] Cover more issues --- proposals/4293-redact-on-ban.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index 5ca4e11e998..a01a4d4e3ff 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -230,6 +230,23 @@ sufficiently high *client* implementations existing in their communities. [MSC4194](https://github.com/matrix-org/matrix-spec-proposals/pull/4194) should help with this, though has the limitations discussed throughout this MSC when applied to this proposal's use case. +7. If a user is banned without the flag then banned again with the flag, their events sent before the + first ban won't be redacted. This is already the case with moderation bots which support autoredaction + when certain ban reasons are used: if there's a typo/problem with the reason, the bot's operator + may need to issue more commands/requests to reach the intended result. + + Clients and moderation bots are encouraged to implement UX which reduces the chances of this sort + of thing happening. Moderation teams are also encouraged to develop operating procedures which + limit the opportunity for accidentally encountering this case. + +8. A spammer may attempt to work around this MSC's effects by joining and leaving the room during + their spam. This has relatively high cost (the impact of spam is lesser when they aren't joined + to the room, and re-joining will hit a more restrictive rate limit on most servers). + + Moderation bots and similar community safety tools are encouraged to add restrictions to the number + of join+leave cycles a user may perform in a short window. This will further reduce the effectiveness + of such an attack. Issue 7 above also applies here. + ## Alternatives Alternatives are discussed inline on this proposal and in the introduction. From 616b4a8fdecb6b3cf86300dfc029337a58d4384a Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:30:28 +0100 Subject: [PATCH 13/14] typos --- proposals/4293-redact-on-ban.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index a01a4d4e3ff..1fda8856835 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -114,7 +114,7 @@ Prior to applying the effects of redaction above, clients and servers MUST ensur the kick or ban has power level to redact the target user's events. This means having a power level higher than or equal to `redact` *and* `events["m.room.redaction"]` (if set). We maintain the `events` check despite not actually sending events of that type to keep the same expectations within rooms. If -the sender doesn't have permission to redact an event normally, no the `redact_events` flag is ignored +the sender doesn't have permission to redact an event normally, the `redact_events` flag is ignored (and therefore no redaction effect is applied). Events which are delivered after the kick or ban are likely [soft failed](https://spec.matrix.org/v1.14/server-server-api/#soft-failure) @@ -152,7 +152,7 @@ An example ban event is: } ``` -An example sccenario would be: +An example scenario would be: 1. Alice joins the room. 2. Alice sends events A, B, and C. From 3910458d06ce968dfbdae3d171b75140a6cff20e Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 12 Nov 2025 17:19:48 +0000 Subject: [PATCH 14/14] typo Co-authored-by: Hubert Chathi --- proposals/4293-redact-on-ban.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4293-redact-on-ban.md b/proposals/4293-redact-on-ban.md index 1fda8856835..4190b7b1f4b 100644 --- a/proposals/4293-redact-on-ban.md +++ b/proposals/4293-redact-on-ban.md @@ -57,7 +57,7 @@ redactions" to ensure the room is cleaned up, though those senders can begin to as best effort (currently, moderation bots in particular work incredibly hard to ensure they get *every* event redacted, but can run into delivery, reliability, and completeness issues with 1:1 redactions). -It's also important to note that this proposal intends to compliment mass redactions and coexist in +It's also important to note that this proposal intends to complement mass redactions and coexist in whatever room version mass redactions land in. This proposal has narrow scope and is fairly blunt as a measure, which may not be desirable in all situations. For example, only a user's last dozen or so messages may be worth redacting rather than the hundreds they sent prior to the ones which got them