From f57b74b4e5f03e418e293a6551eca44028204655 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 13:28:36 +0000 Subject: [PATCH 01/11] Auth Lock: Soft-failure-be-gone --- .../4104-auth-lock-soft-failure-be-gone.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 proposals/4104-auth-lock-soft-failure-be-gone.md diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md new file mode 100644 index 000000000..41dc504bc --- /dev/null +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -0,0 +1,125 @@ +# MSC4104: Auth Lock: Soft-failure-be-gone! + +This MSC introduces a new authorization event, the auth-lock. +When a server issues an authorization event that supersedes an existing +event, for example by banning a user, the user can can choose to +canonicalise their version of the room history by issuing an auth-lock. +This can be thought of as a thread lock from forum software applied +to a specific portion of the DAG. The auth-lock event not only +specifies the authorization event to lock, but all forward +extremities that reference the locked authorization event. Thus +canonicalising the history of that part of the DAG. + +Any further events that reference an authorization event that has been +*locked* will then be rejected outright in during authorization. + +## Proposal + +### The auth lock event `m.auth_lock` + +#### Properties +- content: + + `locked_event_id`: The event_id of the authorization event to lock. + + `extremities`: A list of extremities that should be shared to other + servers representing the canonicalised version of the room history. + +- state_key: A sha256 of the `locked_event_id` concatenated with the + mxid of the event sender. + +### Changes to auth_rules + +#### Issuing `m.auth_lock` + +If type is `m.auth_lock`: + 1. if `state_key` does not match a sha256 of `locked_event_id` and + `sender`, reject. + +#### Authorizing other events + +Considering the event's `auth_events`: + 1. if the considered auth_event's `event_id` matches a + `locked_event_id` AND the `event_id` of the event is abscent + from any `extremities` field AND the chain of `prev_events` + from any event referenced by any `extremities` field, reject. + +## Potential issues + +### Conflicting auth-lock events + +Imagine that there are two admins in a room, Alice and Bob. +Imagine that there is a malicious user Chelsea. +Alice and Bob both ban chelsea. +Alice sees Chelsea send events B -> A. +Bob sees Chelsea send events C -> B -> A. +Alice and Bob both issue auth_lock events for Chelsea's prior membership. +Alice's `extremities` field includes `B`, but excludes `C`. +Bob's `extremities` field includes `C`. + +The receiving server must combine the `extremities` from both events +such that the canonical history becomes C -> B -> A. + +### Issuing auth-lock to deliberatly encode less or no extremities + +#### Effects on participating servers + +We counteract this issue by requiring that servers maintain all +existing `extremities` and their `prev_events`, regardless of +whether they are missing from the `extremities` field of +an `m.auth_lock` event. + +#### Effects on joining servers + +Joining servers will no longer be able to authorize large parts of the +room's history. + +### Revising auth-lock to deliberatly encode less or no extremities + +We counteract this issue by encoding that only one auth_rule can exist +for the same `state_key` in the room's history. + +### Split history for unprivileged users on unprivileged servers + +Imagine that Alice issues an `m.room.power_levels` event P. +Alice revises this event so that it becomes P'. +Alice issues an auth_lock for P, Lock-P. +Imagine that Alice receives an event B from Bob that references P. +Alice is forced to reject event B. + +### Resolution + +Bob receives Lock-P, and notices that B is abscent from the chain +specified in Lock-P's `extremities`. + +We would need a new MSC for bob to resend B as B' such that servers who +have accepted B would recognise B' to be a duplicate that references +more recent authorization events. + +### Redaction of the lock + +We probably do want the lock to be redactable. +But how can you be sure that you're not opening pandora's box by +allowing hidden malicious events residing on participating servers +to suddenly be incorporated into the DAG? + +### Locking all current auth events + +It would be possible to lock all auth_events and stop any further +developments in the room. + +## Alternatives + +None recognized. + + +## Security considerations + +See potential issues. + + +## Unstable prefix + +None issued. + +## Dependencies + +None. From 7ea5f1e50bf06ef7a2bf8013b7bbd681a4000fad Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 13:51:15 +0000 Subject: [PATCH 02/11] clarity --- proposals/4104-auth-lock-soft-failure-be-gone.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 41dc504bc..574f54576 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -2,7 +2,7 @@ This MSC introduces a new authorization event, the auth-lock. When a server issues an authorization event that supersedes an existing -event, for example by banning a user, the user can can choose to +event, for example by banning a user, the admin can can choose to canonicalise their version of the room history by issuing an auth-lock. This can be thought of as a thread lock from forum software applied to a specific portion of the DAG. The auth-lock event not only @@ -11,7 +11,7 @@ extremities that reference the locked authorization event. Thus canonicalising the history of that part of the DAG. Any further events that reference an authorization event that has been -*locked* will then be rejected outright in during authorization. +*locked* will then be rejected outright during authorization. ## Proposal @@ -58,7 +58,7 @@ Bob's `extremities` field includes `C`. The receiving server must combine the `extremities` from both events such that the canonical history becomes C -> B -> A. -### Issuing auth-lock to deliberatly encode less or no extremities +### Issuing auth-lock to deliberately encode less or no extremities #### Effects on participating servers From f50c5ca9b1ef619ce963087e3fa548dc5f2c705c Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 13:56:22 +0000 Subject: [PATCH 03/11] aspell thanks Andy --- proposals/4104-auth-lock-soft-failure-be-gone.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 574f54576..1ad6e6cc5 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -38,7 +38,7 @@ If type is `m.auth_lock`: Considering the event's `auth_events`: 1. if the considered auth_event's `event_id` matches a - `locked_event_id` AND the `event_id` of the event is abscent + `locked_event_id` AND the `event_id` of the event is absent from any `extremities` field AND the chain of `prev_events` from any event referenced by any `extremities` field, reject. @@ -48,7 +48,7 @@ Considering the event's `auth_events`: Imagine that there are two admins in a room, Alice and Bob. Imagine that there is a malicious user Chelsea. -Alice and Bob both ban chelsea. +Alice and Bob both ban Chelsea. Alice sees Chelsea send events B -> A. Bob sees Chelsea send events C -> B -> A. Alice and Bob both issue auth_lock events for Chelsea's prior membership. @@ -72,7 +72,7 @@ an `m.auth_lock` event. Joining servers will no longer be able to authorize large parts of the room's history. -### Revising auth-lock to deliberatly encode less or no extremities +### Revising auth-lock to deliberately encode less or no extremities We counteract this issue by encoding that only one auth_rule can exist for the same `state_key` in the room's history. @@ -87,7 +87,7 @@ Alice is forced to reject event B. ### Resolution -Bob receives Lock-P, and notices that B is abscent from the chain +Bob receives Lock-P, and notices that B is absent from the chain specified in Lock-P's `extremities`. We would need a new MSC for bob to resend B as B' such that servers who @@ -97,7 +97,7 @@ more recent authorization events. ### Redaction of the lock We probably do want the lock to be redactable. -But how can you be sure that you're not opening pandora's box by +But how can you be sure that you're not opening Pandora's box by allowing hidden malicious events residing on participating servers to suddenly be incorporated into the DAG? From 2b59d33e16a5cd0577825713df5ab498e5189172 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:21:09 +0000 Subject: [PATCH 04/11] Elaborate authorisation rules. We need to say explicitly that all `m.auth_lock` events that have been created that match the `auth_event` are considered. --- proposals/4104-auth-lock-soft-failure-be-gone.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 1ad6e6cc5..9f18ce5c1 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -37,10 +37,17 @@ If type is `m.auth_lock`: #### Authorizing other events Considering the event's `auth_events`: - 1. if the considered auth_event's `event_id` matches a - `locked_event_id` AND the `event_id` of the event is absent - from any `extremities` field AND the chain of `prev_events` - from any event referenced by any `extremities` field, reject. + 1. For each `auth_event` all `m.auth_lock` events with a + `locked_event_id` matching the `event_id` of the `auth_event` + are found from the room's current state. + From each `m.auth_lock` event relevant to one `auth_event`, the + `extremities` fields are combined to form a set of all `extremities` + relevant to the `auth_event`. + If the considered auth_event's `event_id` matches any + `m.auth_lock`'s `locked_event_id` field AND the `event_id` of the + event being authorized is absent from both the `extremities` set + AND the `event_id` of any connected event referenced via each + extremity's `prev_events`, reject. ## Potential issues From 5ebe319a11b1fab328ac7b9332dde79fb7643977 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:22:39 +0000 Subject: [PATCH 05/11] This concern is already covered It's allowed because servers will still retain the history and an admin can easily recanonicalise the state so that joining servers can see the relevant history again. --- proposals/4104-auth-lock-soft-failure-be-gone.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 9f18ce5c1..7cb785221 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -79,11 +79,6 @@ an `m.auth_lock` event. Joining servers will no longer be able to authorize large parts of the room's history. -### Revising auth-lock to deliberately encode less or no extremities - -We counteract this issue by encoding that only one auth_rule can exist -for the same `state_key` in the room's history. - ### Split history for unprivileged users on unprivileged servers Imagine that Alice issues an `m.room.power_levels` event P. From 7340c0635341cd9cc958005535999bb6a9922bbd Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:23:38 +0000 Subject: [PATCH 06/11] layout and formating --- proposals/4104-auth-lock-soft-failure-be-gone.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 7cb785221..9dc81f2e8 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -65,7 +65,7 @@ Bob's `extremities` field includes `C`. The receiving server must combine the `extremities` from both events such that the canonical history becomes C -> B -> A. -### Issuing auth-lock to deliberately encode less or no extremities +### Issuing `m.auth_lock` to deliberately encode less or no extremities #### Effects on participating servers @@ -87,7 +87,7 @@ Alice issues an auth_lock for P, Lock-P. Imagine that Alice receives an event B from Bob that references P. Alice is forced to reject event B. -### Resolution +#### Resolution Bob receives Lock-P, and notices that B is absent from the chain specified in Lock-P's `extremities`. @@ -96,7 +96,7 @@ We would need a new MSC for bob to resend B as B' such that servers who have accepted B would recognise B' to be a duplicate that references more recent authorization events. -### Redaction of the lock +### Redaction of `m.auth_lock` We probably do want the lock to be redactable. But how can you be sure that you're not opening Pandora's box by From cf513b5060156f1e0fec43c4886cff1972da9fdc Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:38:26 +0000 Subject: [PATCH 07/11] Make a shorter introduction --- proposals/4104-auth-lock-soft-failure-be-gone.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 9dc81f2e8..2f1b7d386 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -1,5 +1,10 @@ # MSC4104: Auth Lock: Soft-failure-be-gone! +This proposal aims to make soft failure redundant, by introducing +`m.auth_lock` as a mechanism to stop authorising events that are +crafted to reference previous state. All without disrupting the +history of the room for new users. + This MSC introduces a new authorization event, the auth-lock. When a server issues an authorization event that supersedes an existing event, for example by banning a user, the admin can can choose to @@ -8,7 +13,7 @@ This can be thought of as a thread lock from forum software applied to a specific portion of the DAG. The auth-lock event not only specifies the authorization event to lock, but all forward extremities that reference the locked authorization event. Thus -canonicalising the history of that part of the DAG. +canonicalising the history of that part of the DAG. Any further events that reference an authorization event that has been *locked* will then be rejected outright during authorization. From 763d023983c6048e35101d3b06ed868c8ee26c5e Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:38:43 +0000 Subject: [PATCH 08/11] Elaborate `state_key`. --- proposals/4104-auth-lock-soft-failure-be-gone.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 2f1b7d386..e0549c119 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -23,13 +23,16 @@ Any further events that reference an authorization event that has been ### The auth lock event `m.auth_lock` #### Properties -- content: +- `content`: + `locked_event_id`: The event_id of the authorization event to lock. + `extremities`: A list of extremities that should be shared to other servers representing the canonicalised version of the room history. -- state_key: A sha256 of the `locked_event_id` concatenated with the - mxid of the event sender. +- `state_key`: A sha256 of the `locked_event_id` concatenated with the + mxid of the event sender. We do this so that different room admins + can optionally specify their own versions of the `extremities` + that will combine to form a complete set to be considered during + authorization. This also keeps `extremities` conflict free. ### Changes to auth_rules From 383c426c0a39a24ba6550474924fca700a2cd769 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 15:49:09 +0000 Subject: [PATCH 09/11] duplicate can. --- proposals/4104-auth-lock-soft-failure-be-gone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index e0549c119..c301309a1 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -7,7 +7,7 @@ history of the room for new users. This MSC introduces a new authorization event, the auth-lock. When a server issues an authorization event that supersedes an existing -event, for example by banning a user, the admin can can choose to +event, for example by banning a user, the admin can choose to canonicalise their version of the room history by issuing an auth-lock. This can be thought of as a thread lock from forum software applied to a specific portion of the DAG. The auth-lock event not only From f6444a0ed7203eaa4af543f81859cde0417f524e Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 19:20:46 +0000 Subject: [PATCH 10/11] Clarify redaction and eager locking --- proposals/4104-auth-lock-soft-failure-be-gone.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index c301309a1..9f6eea85b 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -5,7 +5,7 @@ This proposal aims to make soft failure redundant, by introducing crafted to reference previous state. All without disrupting the history of the room for new users. -This MSC introduces a new authorization event, the auth-lock. +This MSC introduces a new authorization event, the `m.auth_lock` event. When a server issues an authorization event that supersedes an existing event, for example by banning a user, the admin can choose to canonicalise their version of the room history by issuing an auth-lock. @@ -22,11 +22,24 @@ Any further events that reference an authorization event that has been ### The auth lock event `m.auth_lock` +The `m.auth_lock` event can be issued in scenarios where room admins +or their tooling detect or anticipate events referring to previous +authorization events. This should only be done eagerly when there +is reasonable risk. For example, it would be inappropriate to +issue an `m.auth_lock` event after banning a spammer that +resided on `matrix.org` as it is unlikely for matrix.org +to attempt to maliciously reference old authorization events. +By delaying the application of `m.auth_lock`, room administrators +reduce the risk of divergence. This is something that currently +occurs frequently with [soft failure](https://github.com/element-hq/synapse/issues/9329). + #### Properties - `content`: + `locked_event_id`: The event_id of the authorization event to lock. + This is protected from redaction. + `extremities`: A list of extremities that should be shared to other servers representing the canonicalised version of the room history. + This is protected from redaction. - `state_key`: A sha256 of the `locked_event_id` concatenated with the mxid of the event sender. We do this so that different room admins From e15517ee53981e94d8e4a4195d11fd50206c4f7c Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 19 Feb 2024 19:21:18 +0000 Subject: [PATCH 11/11] Rewrite issues. --- .../4104-auth-lock-soft-failure-be-gone.md | 98 +++++++++++++++---- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/proposals/4104-auth-lock-soft-failure-be-gone.md b/proposals/4104-auth-lock-soft-failure-be-gone.md index 9f6eea85b..87d9b46eb 100644 --- a/proposals/4104-auth-lock-soft-failure-be-gone.md +++ b/proposals/4104-auth-lock-soft-failure-be-gone.md @@ -72,7 +72,7 @@ Considering the event's `auth_events`: ## Potential issues -### Conflicting auth-lock events +### Multiple auth-lock events Imagine that there are two admins in a room, Alice and Bob. Imagine that there is a malicious user Chelsea. @@ -83,46 +83,102 @@ Alice and Bob both issue auth_lock events for Chelsea's prior membership. Alice's `extremities` field includes `B`, but excludes `C`. Bob's `extremities` field includes `C`. +#### Solution + The receiving server must combine the `extremities` from both events such that the canonical history becomes C -> B -> A. +This is already explicitly written within the authorization rules +in this MSC. + +### Diverging `extremities` + +Imagine Bob's server receives an `m.auth_lock` event and Bob's server +has authorized events referencing the `locked_event_id` that are not +present within any relevant `m.auth_lock`'s `extremities`. +Bob's server must decide what to do with the events it has already +authorized. + +This is a problem that occurs in the following scenarios: + +#### Scenario A: Alice deliberately encodes less `extremities` than Bob has +Alice issues an `m.auth_lock` to deliberately encode less or no +extremities, in an attempt permanently to diverge Bob's DAG. +Joining user David would then also not be able to see a large portion +of the history that Bob can, because it wouldn't be authorized in +David's DAG when David backfills. + +#### Scenario B: Alice issues a lock quickly after changing an auth event + +Imagine that Alice issues an `m.room.power_levels` event P. +Alice revises this event so that it becomes P'. +Alice issues an auth_lock for P, Lock-P. +Imagine that Alice receives an event B from Bob that references P. +Alice and every other server with Lock-P is forced to reject event B. + +#### Scenario C: Bob's events are mixed with Chelsea's + +Chelsea has sent `X -> A` to Alice, but `Y -> A` to Bob. +Bob has then appended `B -> Y -> A` and in turn Chelsea +has appended `Z -> B -> Y -> A` and sent `Z` to Bob. -### Issuing `m.auth_lock` to deliberately encode less or no extremities +Alice has banned Chelsea and locked Chelsea's prior membership. +Only now has Bob received this `m.auth_lock` event, and it only +contains the extremity `X`. + +Alice can get `B` if Bob sends it to her, +but new joiner David will probably be unable to by backfilling `B`, +at least if David's server doesn't have special code to account +for the connected events being rejected. #### Effects on participating servers -We counteract this issue by requiring that servers maintain all -existing `extremities` and their `prev_events`, regardless of -whether they are missing from the `extremities` field of -an `m.auth_lock` event. +Servers are required to maintain all their existing `extremities` +and their `prev_events`, regardless of whether they are missing from +the `extremities` field of any `m.auth_lock` event. + +These servers should still incorporate these diverged `extremities` +into `prev_events` so that they can be discovered and repaired later. #### Effects on joining servers Joining servers will no longer be able to authorize large parts of the room's history. -### Split history for unprivileged users on unprivileged servers +#### Solution A: Dedicated API for showing diverged events to room admins -Imagine that Alice issues an `m.room.power_levels` event P. -Alice revises this event so that it becomes P'. -Alice issues an auth_lock for P, Lock-P. -Imagine that Alice receives an event B from Bob that references P. -Alice is forced to reject event B. +A room administrator could be made aware of all the extremities that +are diverged. This can be done because a server can detect when +authorized events contain references to unauthorized events +within `prev_events` of authorized events in the DAG. -#### Resolution +A room administrator can then preview the effects of incorporating +diverged extremities and make a decision to do so via the +`extremities` field of `m.auth_lock`. -Bob receives Lock-P, and notices that B is absent from the chain -specified in Lock-P's `extremities`. +#### Solution B: Room administrators on other servers issue their own `m.auth_lock` + +Room admins residing on different servers with diverged extremities +can issue their own `m.auth_lock` event to include diverged extremities. +When this event is received by other servers, the diverged extremities +can be authorized and the DAG will converge again. + +#### Solution C: Unprivileged users propose changes to the `extremities` of `m.auth_lock` + +Participants in the room can propose changes to the `extremities` +contained within `m.auth_lock` via a dedicated event. Room administrators +can then review the effects and merge them. + +#### Solution D: Recrafting PDUs + +Take scenario B. Bob receives Lock-P, and notices that B is absent +from the chain specified in Lock-P's `extremities`. We would need a new MSC for bob to resend B as B' such that servers who have accepted B would recognise B' to be a duplicate that references more recent authorization events. -### Redaction of `m.auth_lock` - -We probably do want the lock to be redactable. -But how can you be sure that you're not opening Pandora's box by -allowing hidden malicious events residing on participating servers -to suddenly be incorporated into the DAG? +This would allow Alice to see `B` in Scenario C. But it wouldn't +allow Alice to redact `Z` or `Y`, which Bob my find harmful. ### Locking all current auth events