From d0ada28c39f3403d084899d424a8f8d67a570026 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Dec 2025 18:07:17 -0500 Subject: [PATCH 1/3] document recovery and backup_disabled account data --- spec/backup_disabled.md | 45 +++++++++++++++++++++++++++++++++++++++ spec/recovery.md | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 spec/backup_disabled.md create mode 100644 spec/recovery.md diff --git a/spec/backup_disabled.md b/spec/backup_disabled.md new file mode 100644 index 0000000..c7cab14 --- /dev/null +++ b/spec/backup_disabled.md @@ -0,0 +1,45 @@ +# m.org.matrix.custom.backup_disabled: Recording whether key backup is enabled or disabled + +## Problem + +We allow users to disable key backup, and if a user does so, we do not want to +continue to nag them. This information needs to be synced between clients so +that users are not nagged is several places after having disabled backup. + +## Proposal + +We introduce a new account data event, `m.org.matrix.custom.backup_disabled`, +which is an object with a boolean property, `disabled`. If the user has chosen +to not enable key backup (for example, by disabling key backup, or by dismissing +a toast prompting them to enable recovery), `disabled` is set to `true`. If the +user has chosen to enable key backup, `disabled` is set to `false`. If +`disabled` is set to `true` but key backup is set up, the client should ignore +the value of `disabled`. + +If there is no `m.org.matrix.custom.backup_disabled` event, this indicates that +the user has not make any decision yet about key backup. In this case, if +backup is not yet set up, we prompt the user to enable backup. + +## MSC + +This is an older version of +[MSC4287](https://github.com/matrix-org/matrix-spec-proposals/pull/4287), and [we +should eventually migrate to the system described there](https://github.com/element-hq/element-meta/issues/2745). + +The main difference between this proposal and the MSC is that the MSC uses an +`enabled` property with the values having the reverse meaning of the `disabled` +property used in this proposal. + +## Security considerations + +A malicious actor could set the value of `disabled` to `true` for a new user, in +which case they would not be prompted to enable key backup. However, this will +not allow the attacker to gain any information, nor will it prevent the user +from enabling key backup. It only prevents the user from being prompted to +enable key backup. + +## Implementations + +* `element-web` implemented this in February 2025: + * https://github.com/element-hq/element-web/pull/29290 +TODO: record when Element X implemented this diff --git a/spec/recovery.md b/spec/recovery.md new file mode 100644 index 0000000..480934a --- /dev/null +++ b/spec/recovery.md @@ -0,0 +1,47 @@ +# io.element.recovery: Recording whether recovery is enabled or disabled + +## Problem + +We allow users to disable recovery (secret storage), and if a user does so, we +do not want to continue to nag them. This information needs to be synced +between clients so that users are not nagged in different places after having +disabled recovery. + +## Proposal + +We introduce a new account data event, `io.element.recovery`, which is an object +with a boolean property, `enabled`. If the user has chosen to not enable +recovery (for example, by disabling recovery, or by dismissing a toast prompting +them to enable recovery), `enabled` is set to `false`. If the user has chosen +to enable recovery, `enabled` is set to `true`. If `enabled` is set to `false` +but recovery is set up, the client should ignore the value of `enabled`. + +If there is no `io.element.recovery` event, this indicates that the user has not +make any decision yet about recovery. In this case, if recovery is not yet set +up (but key backup is enabled), we prompt the user to enable recovery. + +Note that we will only enable recovery if key backup is enabled. This means +that the value of this account data event is affected by the value of +[`m.org.matrix.custom.backup_disabled`](backup_disabled.md) account data event. +In particular, if `m.org.matrix.custom.backup_disabled` has `"disabled": true`, +then we ignore this account data, since we will not prompt the user to enable +recovery. However, if a user enables key backup +(`m.org.matrix.custom.backup_disabled` set to `{"disabled": false}`), they may +disable or enable recovery. + +## MSC + +None + +## Security considerations + +A malicious actor could set the value of `enabled` to `false` for a new user, in +which case they would not be prompted to enable recovery. However, this will +not allow the attacker to gain any information, nor will it prevent the user +from enabling recovery. It only prevents the user from being prompted to enable +recovery. + +## Implementations + +* `element-web` implemented this in June 2025 + * https://github.com/element-hq/element-web/pull/30075 From d701154d330d7ac3d65ee01b7334f4e911e1ebe6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 12 Dec 2025 15:35:38 -0500 Subject: [PATCH 2/3] add note about Rust implementation --- spec/backup_disabled.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/backup_disabled.md b/spec/backup_disabled.md index c7cab14..0c06a3d 100644 --- a/spec/backup_disabled.md +++ b/spec/backup_disabled.md @@ -42,4 +42,5 @@ enable key backup. * `element-web` implemented this in February 2025: * https://github.com/element-hq/element-web/pull/29290 -TODO: record when Element X implemented this +* `matrix-rust-sdk` implemented this in November 2023: + * https://github.com/matrix-org/matrix-rust-sdk/pull/2842 From b6b651f04fbe83ad1fe2a000de69c2fc00582192 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 19 Jan 2026 17:10:26 -0500 Subject: [PATCH 3/3] simplify documentation, and add summary --- spec/backup_disabled.md | 27 ++++++++------------------- spec/index.md | 12 ++++++++++++ spec/recovery.md | 38 +++++++++++--------------------------- 3 files changed, 31 insertions(+), 46 deletions(-) create mode 100644 spec/index.md diff --git a/spec/backup_disabled.md b/spec/backup_disabled.md index 0c06a3d..d96936f 100644 --- a/spec/backup_disabled.md +++ b/spec/backup_disabled.md @@ -1,17 +1,13 @@ # m.org.matrix.custom.backup_disabled: Recording whether key backup is enabled or disabled -## Problem - -We allow users to disable key backup, and if a user does so, we do not want to -continue to nag them. This information needs to be synced between clients so -that users are not nagged is several places after having disabled backup. - -## Proposal - -We introduce a new account data event, `m.org.matrix.custom.backup_disabled`, -which is an object with a boolean property, `disabled`. If the user has chosen -to not enable key backup (for example, by disabling key backup, or by dismissing -a toast prompting them to enable recovery), `disabled` is set to `true`. If the +The `m.org.matrix.custom.backup_disabled` account data event records whether the +user has disabled key backup, so that this information is synchronised between +their devices. Its main purpose is to avoid continuously nagging the user on +multiple devices if they have already chosen to disable key backup. + +It is an object with a boolean property, `disabled`. If the user has chosen to +not enable key backup (for example, by disabling key backup, or by dismissing a +toast prompting them to enable recovery), `disabled` is set to `true`. If the user has chosen to enable key backup, `disabled` is set to `false`. If `disabled` is set to `true` but key backup is set up, the client should ignore the value of `disabled`. @@ -30,13 +26,6 @@ The main difference between this proposal and the MSC is that the MSC uses an `enabled` property with the values having the reverse meaning of the `disabled` property used in this proposal. -## Security considerations - -A malicious actor could set the value of `disabled` to `true` for a new user, in -which case they would not be prompted to enable key backup. However, this will -not allow the attacker to gain any information, nor will it prevent the user -from enabling key backup. It only prevents the user from being prompted to -enable key backup. ## Implementations diff --git a/spec/index.md b/spec/index.md new file mode 100644 index 0000000..9d30c36 --- /dev/null +++ b/spec/index.md @@ -0,0 +1,12 @@ +Element uses the following non-standard event types: + +# Account-data events + +- [io.element.functional_members](functional_members.md): Marking room members + as unimportant functional members +- [io.element.matrix_client_information.](matrix_client_information.md): + Storing additional client information per device +- [m.org.matrix.custom.backup_disabled](backup_disabled.md): Recording whether + key backup is enabled or disabled +- [io.element.recovery](recovery.md): Recording whether recovery is enabled or + disabled diff --git a/spec/recovery.md b/spec/recovery.md index 480934a..c3bbc7c 100644 --- a/spec/recovery.md +++ b/spec/recovery.md @@ -1,20 +1,16 @@ # io.element.recovery: Recording whether recovery is enabled or disabled -## Problem - -We allow users to disable recovery (secret storage), and if a user does so, we -do not want to continue to nag them. This information needs to be synced -between clients so that users are not nagged in different places after having -disabled recovery. - -## Proposal - -We introduce a new account data event, `io.element.recovery`, which is an object -with a boolean property, `enabled`. If the user has chosen to not enable -recovery (for example, by disabling recovery, or by dismissing a toast prompting -them to enable recovery), `enabled` is set to `false`. If the user has chosen -to enable recovery, `enabled` is set to `true`. If `enabled` is set to `false` -but recovery is set up, the client should ignore the value of `enabled`. +The `io.element.recovery` account data event indicates whether the user has +enabled or disabled recovery (secret storage), so that this information is +synchronised between devices. Its main purpose is to avoid continuously nagging +the user on multiple devices if they have already chosen to disable recovery. + +It is an object with a boolean property, `enabled`. If the user has chosen to +not enable recovery (for example, by disabling recovery, or by dismissing a +toast prompting them to enable recovery), `enabled` is set to `false`. If the +user has chosen to enable recovery, `enabled` is set to `true`. If `enabled` is +set to `false` but recovery is set up, the client should ignore the value of +`enabled`. If there is no `io.element.recovery` event, this indicates that the user has not make any decision yet about recovery. In this case, if recovery is not yet set @@ -29,18 +25,6 @@ recovery. However, if a user enables key backup (`m.org.matrix.custom.backup_disabled` set to `{"disabled": false}`), they may disable or enable recovery. -## MSC - -None - -## Security considerations - -A malicious actor could set the value of `enabled` to `false` for a new user, in -which case they would not be prompted to enable recovery. However, this will -not allow the attacker to gain any information, nor will it prevent the user -from enabling recovery. It only prevents the user from being prompted to enable -recovery. - ## Implementations * `element-web` implemented this in June 2025