From 80f71877a4bfb32ed1de7d35fa5a84dfc211c390 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 14:42:25 +0100 Subject: [PATCH 1/8] Add early draft of Portable Identities document --- proposals/xxxx-portable-identities.md | 307 ++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 proposals/xxxx-portable-identities.md diff --git a/proposals/xxxx-portable-identities.md b/proposals/xxxx-portable-identities.md new file mode 100644 index 00000000000..8d194c0bf2d --- /dev/null +++ b/proposals/xxxx-portable-identities.md @@ -0,0 +1,307 @@ +# MSCXXXX: Portable Identities + +## Background + +This is an evolution of [MSC1228](https://github.com/matrix-org/matrix-doc/pull/1228) +which aims to make it simpler to implement portable identities and decentralised +accounts. + +It is still a work-in-progress—some things that need attention include: + +- How to handle invites, given that you won't know a UDK until after the user has + joined the room; +- How to adequately disconnect UDKs from UPKs as a part of a data removal request + for GDPR compliance; +- Whether UPKs should really be a "one true identity" for a user or whether a user + may actually have multiple UPKs if they want; +- How to handle device list syncing and send-to-device messages; +- The extent to which users should be involved in attesting MXID-to-UPK mappings. + +## Goals + +The goals of this proposal are: + +- To enable account portability by breaking the link between a user identity and a + specific homeserver; +- To allow breaking the link between delegated and permanent user identities at a + later date, e.g. as a part of a data deletion request; +- To allow a user to grant permission to one or more homeservers to act on behalf of + the user in a given room, e.g. allowing them to creating and sign events from a + user; +- To remove the need for servers to have a single static signing key, as they do + today. + +## Proposal + +This proposal includes specifications to: + +- To give a user a single cryptographic User Permanent Key (herein referred to as + a "UPK"), which they will use as part of a cryptographic challenge login; +- To give a server a set of User Delegated Keys (herein referred to as a "UDK"), + which will represent servers acting on behalf of users within rooms; +- To allow users to attest one or more UDKs using their UPK; +- To remove Matrix IDs (MXIDs) and server names from events, similar to MSC1228; +- To allow a user to receive one or more server-provided MXIDs mapped to a UPK. + +### User Permanent Key (UPK) + +The UPK is an ed25519 public key which represents a user entity. The initial +intention is that a user will use this UPK to perform a challenge-response login +to a homeserver and that it will become their "one true identity". + +Central to this design is that the UPKs are user-owned and therefore the private +key portion to each UPK is held by the user, although they could be protected with +a passphrase and backed up to key storage on one or more homeservers if needed. + +The UPK private portion must not be decrypted nor used serverside. + +#### UPK Format + +The UDK is prefixed with a version byte, then URL-safe base64-encoded, and then +prefixed with the `~` sigil. The version byte for ed25519 is `0x01`. + +### User Delegated Key (UDK) + +Homeservers create a new UDK, which is an ed25519 key, on behalf of each user in +each room. These keys are generated and stored by the server when a user joins a +room: + +1. The user requests to join a room; +2. The server generates a UDK and sends the public key to the client; +3. The client signs a UDK attestation using a UPK - this forms the link between + the UDK and the UPK; +4. The server generates the membership event, including the attestation, and sends + it into the room/to federated servers, signed using the new UDK. + +The homeserver should store all active UPK-UDK links. + +#### UDK Format + +The UDK is prefixed with a version byte, then URL-safe base64-encoded, and then +prefixed with the `^` sigil. The version byte for ed25519 is `0x01`. + +### Membership UDK Attestation + +An attestation will include the UDK that is being attested to, and an expiry time. The +attestation will be valid for events up until the expiry time, at which point a new +attestation will be required. + +The completed attestation will take a format similar to this: + +``` +"attestation": { + "content": { + "identity": ~upk_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 + }, + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" + }, + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" + } + } +} +``` + +The attestation contains a `"server_name"` field which contains the name of the server +that manages the UDK. This is necessary as, without this, other servers in the room +will not be able to work out where to route messages for this UDK. + +The attestation `"content"` key will then be canonicalised and signed, once by the UPK +and then once by the homeserver that issued the UDK. + +#### Validity + +The attestation will be valid from the point that it is sent (in effect, from the +`"origin_server_ts"` timestamp) up until the `"expires"` timestamp. + +Since there may be multiple membership state events with renewals over time, event +validity is based on the attestation in the room state at (before) the event. If the attestation has expired in the room state at (before) the event, the attestation is +considered invalid - newer attestations must not be considered. + +#### Authorisation rules + +Events will continue to refer to the membership event as an auth event, with the +main difference being that the referred-to membership event will now contain an +attestation. + +Authorisation rules will be updated to include extra clauses, that events should +only be accepted for a specific UDK as long as there is: + +1. A valid attestation for the UDK in the referred membership event; +2. The event falls inclusive of the `"origin_server_ts"` and the `"expires"` of + the attestation. + +To cover the possibility of an attestation not being renewed, soft-fail rules will +be updated to include extra clauses, that events should be soft-failed unless there +is: + +1. A valid attestation for the UDK in the current room state; +2. The event falls before the `"expires"` timestamp of the attestation. + +This prevents servers from continuing to impersonate the user with new events after +the attestation has expired - necessary as the server owns and maintains the UDK +keypair. + +Some thought needs to be given on how to ban a UPK so that generating new UDKs is not +an effective measure for evading bans. + +### Membership event format + +A membership event including an attestation may look something like this: + +``` +{ + "auth_events": [ ... ], + "prev_events": [ ... ], + "content": { + "avatar_url": "mxc://here/is/neilalexander.png", + "displayname": "neilalexander", + "membership": "join", + "attestation": { + "content": { + "identity": ~UPK_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 + }, + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" + }, + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" + } + } + } + }, + "origin_server_ts": 1589549295296, + "sender": "^udk_that_is_being_attested", + "signatures": { + "^udk_that_is_being_attested": "signature_as_signed_by_udk" + }, + "hashes": { + "sha256": ..., + } + "state_key": "^udk_that_is_being_attested", + "type": "m.room.member", + "unsigned": { + "age": 25, + }, + "event_id": "$eventid", + "room_id": "!roomid" +} +``` + +Note that there is no MXID in the `"sender"` and `"state_key"` fields, nor in the +`"signatures"` field of the event itself - these are now referencing the UDKs. + +A membership event must include an attestation - the `"identity"` key may have been +banned. Requiring an attestation helps us to prevent ban evasion. + +### Timeline event format + +Otherwise, the event format remains unchanged, with only one exception: that the +`"signatures"` contains the signature from the UDK, rather than from the server +itself as today: + +``` +{ + "auth_events": [ ... ], + "prev_events": [ ... ], + "content": { + "body": "Hi!", + "msgtype": "m.text" + }, + "origin_server_ts": 1589549295384, + "sender": "^udk_that_is_being_attested", + "signatures": { + "^udk_that_is_being_attested": "signature_as_signed_by_udk" + }, + "hashes": { + "sha256": ..., + } + "type": "m.room.message", + "unsigned": { + "age": 26, + }, + "event_id": "$eventid", + "room_id": "!roomid" +} +``` + +#### Renewing an attestation + +At any time, the UPK holder can issue new attestations by sending updated membership +state events with a new attestation. This can be done either before or after the +validity of the previous attestation has expired. + +The previous membership event with the previous attestation must appear in the +`auth_events` of the new membership event with the new attestation. + +#### Removing an attestation + +To remove an attestation, the membership event should be replaced with a new +membership event that no longer includes an attestation. + +Assuming there is no need to remove evidence of the attestations ever existing, +then this will be sufficient. The previously attested servers will no longer be able +to send events into the room on behalf of the user. + +#### Redacting an attestation + +To satisfy data deletion requests, or where it may be important to fully remove links +between UDKs and UPKs for legal compliance, it should be possible to redact the +membership events to remove the `"attestation"` section from them. + +This may need to be done recursively, following the `"auth_events"`, to remove all +historical attestations too. + +TODO: Doing this may mean that other servers that try to backfill may not be able to +verify that the events were allowed to be sent? + +As the redaction algorithms already have rules for `m.room.member` events which will +preserve the `"membership"` key, it should be possible to redact any other personally +identifiable information such as the `"attestation"`, the `"display_name"` or the +`"avatar_url"` without issue. + +The UDK signature will remain in the event, but without the attestation, it will not +be possible to link it to a UPK. + +### Matrix ID to UPK mapping + +Public keys as identifiers may enable some portability but they aren't user-friendly +and somewhat difficult to put on a business card. For this, it is necessary to be +able to allow users to maintain MXID mappings much as they have today. + +However, a homeserver returning a UPK for an MXID should ideally imply that the server +actually has some kind of association with the user and that the user is resident, +rather than third-party servers gratuitously providing MXID mappings for users that +they may not otherwise be aware of. + +### User signalling + +For things like invites, direct messages etc, it is not possible to know what the UDK +will be before a homeserver generates one to join the room. Therefore these endpoints +should be updated to use either: + +- A UPK in combination with a previously-known resident server name; +- A MXID, from which a response will contain the UPK and a resident server name. + +In these instances, you are addressing "the user" rather than a UDK. + +### Invites + +TODO. + +### Device list syncing + +TODO. + +### Send-to-device + +TODO. From f71a93f04a9adf6ac555a4a054e6b7749b2bcc44 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 14:43:55 +0100 Subject: [PATCH 2/8] Rename file --- .../{xxxx-portable-identities.md => 2787-portable-identities.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-portable-identities.md => 2787-portable-identities.md} (100%) diff --git a/proposals/xxxx-portable-identities.md b/proposals/2787-portable-identities.md similarity index 100% rename from proposals/xxxx-portable-identities.md rename to proposals/2787-portable-identities.md From eeafacda051714c154cd3a9791d9e246b7323669 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 14:48:20 +0100 Subject: [PATCH 3/8] Update header --- proposals/2787-portable-identities.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index 8d194c0bf2d..cb009bdac7c 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -1,10 +1,10 @@ -# MSCXXXX: Portable Identities +# MSC2787: Portable Identities ## Background This is an evolution of [MSC1228](https://github.com/matrix-org/matrix-doc/pull/1228) which aims to make it simpler to implement portable identities and decentralised -accounts. +accounts. It is still a work-in-progress—some things that need attention include: From d778ee108d0321dbaf318d3d1d5da25781e36d7a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 14:52:33 +0100 Subject: [PATCH 4/8] Multiple attestations in membership event format --- proposals/2787-portable-identities.md | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index cb009bdac7c..b9cdf9293b7 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -89,7 +89,7 @@ attestation will be required. The completed attestation will take a format similar to this: ``` -"attestation": { +"attestations": { "content": { "identity": ~upk_that_is_attesting", "delegate": "^udk_that_is_being_attested", @@ -162,22 +162,24 @@ A membership event including an attestation may look something like this: "avatar_url": "mxc://here/is/neilalexander.png", "displayname": "neilalexander", "membership": "join", - "attestation": { - "content": { - "identity": ~UPK_that_is_attesting", - "delegate": "^udk_that_is_being_attested", - "server_name": "example.com", - "expires": 15895491111111 - }, - "signatures": { - "~upk_that_is_attesting": { - "ed25519": "upk_signature" + "attestations": [ + { + "content": { + "identity": ~UPK_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 }, - "~udk_that_is_being_attested": { - "ed25519": "udk_signature" + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" + }, + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" + } } } - } + ] }, "origin_server_ts": 1589549295296, "sender": "^udk_that_is_being_attested", @@ -256,7 +258,7 @@ to send events into the room on behalf of the user. To satisfy data deletion requests, or where it may be important to fully remove links between UDKs and UPKs for legal compliance, it should be possible to redact the -membership events to remove the `"attestation"` section from them. +membership events to remove the `"attestations"` section from them. This may need to be done recursively, following the `"auth_events"`, to remove all historical attestations too. @@ -266,7 +268,7 @@ verify that the events were allowed to be sent? As the redaction algorithms already have rules for `m.room.member` events which will preserve the `"membership"` key, it should be possible to redact any other personally -identifiable information such as the `"attestation"`, the `"display_name"` or the +identifiable information such as the `"attestations"`, the `"display_name"` or the `"avatar_url"` without issue. The UDK signature will remain in the event, but without the attestation, it will not From 2b7cf618ab336432283237391ba2b3c3d956ebac Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 14:53:30 +0100 Subject: [PATCH 5/8] Multiple attestations in example --- proposals/2787-portable-identities.md | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index b9cdf9293b7..9dc465b0e25 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -89,22 +89,24 @@ attestation will be required. The completed attestation will take a format similar to this: ``` -"attestations": { - "content": { - "identity": ~upk_that_is_attesting", - "delegate": "^udk_that_is_being_attested", - "server_name": "example.com", - "expires": 15895491111111 - }, - "signatures": { - "~upk_that_is_attesting": { - "ed25519": "upk_signature" +"attestations": [ + { + "content": { + "identity": ~upk_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 }, - "~udk_that_is_being_attested": { - "ed25519": "udk_signature" + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" + }, + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" + } } } -} +] ``` The attestation contains a `"server_name"` field which contains the name of the server From 5cc1cb6101f32d7bc844269aac9ffe8c5714d51c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 15:27:44 +0100 Subject: [PATCH 6/8] The sender really should be the UPK --- proposals/2787-portable-identities.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index 9dc465b0e25..8fcca02f60c 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -8,6 +8,8 @@ accounts. It is still a work-in-progress—some things that need attention include: +- How to handle multiple homeservers joining the same room, all with attestations + from the same UPK, and how they synchronise state amongst themselves; - How to handle invites, given that you won't know a UDK until after the user has joined the room; - How to adequately disconnect UDKs from UPKs as a part of a data removal request @@ -167,7 +169,7 @@ A membership event including an attestation may look something like this: "attestations": [ { "content": { - "identity": ~UPK_that_is_attesting", + "identity": ~upk_that_is_attesting", "delegate": "^udk_that_is_being_attested", "server_name": "example.com", "expires": 15895491111111 @@ -184,14 +186,14 @@ A membership event including an attestation may look something like this: ] }, "origin_server_ts": 1589549295296, - "sender": "^udk_that_is_being_attested", + "sender": "^upk_that_is_attesting", "signatures": { - "^udk_that_is_being_attested": "signature_as_signed_by_udk" + "^udk_that_is_being_attested": ... }, "hashes": { "sha256": ..., } - "state_key": "^udk_that_is_being_attested", + "state_key": "^upk_that_is_attesting", "type": "m.room.member", "unsigned": { "age": 25, @@ -202,10 +204,7 @@ A membership event including an attestation may look something like this: ``` Note that there is no MXID in the `"sender"` and `"state_key"` fields, nor in the -`"signatures"` field of the event itself - these are now referencing the UDKs. - -A membership event must include an attestation - the `"identity"` key may have been -banned. Requiring an attestation helps us to prevent ban evasion. +`"signatures"` field of the event itself - these are now referencing the UPKs. ### Timeline event format @@ -222,9 +221,9 @@ itself as today: "msgtype": "m.text" }, "origin_server_ts": 1589549295384, - "sender": "^udk_that_is_being_attested", + "sender": "^upk_that_is_attesting", "signatures": { - "^udk_that_is_being_attested": "signature_as_signed_by_udk" + "^udk_that_is_being_attested": ... }, "hashes": { "sha256": ..., From 7cfca3a6e51dea7104410c373ed7d3749a6f600f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 15:56:27 +0100 Subject: [PATCH 7/8] Tweaks --- proposals/2787-portable-identities.md | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index 8fcca02f60c..6fc9910a86c 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -88,6 +88,10 @@ An attestation will include the UDK that is being attested to, and an expiry tim attestation will be valid for events up until the expiry time, at which point a new attestation will be required. +The attestation `"content"` is built by the client, and then is signed with the UPK +before being sent to the server. The attested server will then add its own signature +using the UDK. + The completed attestation will take a format similar to this: ``` @@ -118,6 +122,15 @@ will not be able to work out where to route messages for this UDK. The attestation `"content"` key will then be canonicalised and signed, once by the UPK and then once by the homeserver that issued the UDK. +Multiple attestations can be placed into a single membership event, each for a separate +UDK and `"server_name"`, allowing multiple servers to participate in the same room on +behalf of a single user. It is required that each of the `"server_names"` in each +attestation is considered when sending federated events, rather than relying on the +domain names from the `"state_key"` field as today. + +There should be only one attestation in `"attestations"` per UDK and `"server_name"` +pair. + #### Validity The attestation will be valid from the point that it is sent (in effect, from the @@ -125,24 +138,27 @@ The attestation will be valid from the point that it is sent (in effect, from th Since there may be multiple membership state events with renewals over time, event validity is based on the attestation in the room state at (before) the event. If the attestation has expired in the room state at (before) the event, the attestation is -considered invalid - newer attestations must not be considered. +considered invalid - newer attestations must not be considered when determining the +validity period. #### Authorisation rules Events will continue to refer to the membership event as an auth event, with the -main difference being that the referred-to membership event will now contain an -attestation. +main difference being that the referred-to membership event will now contain one or +more attestations. Authorisation rules will be updated to include extra clauses, that events should only be accepted for a specific UDK as long as there is: 1. A valid attestation for the UDK in the referred membership event; 2. The event falls inclusive of the `"origin_server_ts"` and the `"expires"` of - the attestation. + the attestation; +3. An `m.room.member` event with an `"attestation"` section must contain a signature + from the UPK. To cover the possibility of an attestation not being renewed, soft-fail rules will -be updated to include extra clauses, that events should be soft-failed unless there -is: +be updated to include extra clauses, that events should be soft-failed when received as +new events unless there is: 1. A valid attestation for the UDK in the current room state; 2. The event falls before the `"expires"` timestamp of the attestation. From e26c97c2bb69dc1f7ca5297abfa57786561505bb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 Sep 2020 16:11:39 +0100 Subject: [PATCH 8/8] UDK as sender again, because otherwise attestations can't be redacted as events will still have those signatures --- proposals/2787-portable-identities.md | 83 ++++++++++++--------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/proposals/2787-portable-identities.md b/proposals/2787-portable-identities.md index 6fc9910a86c..c4f8f667ed0 100644 --- a/proposals/2787-portable-identities.md +++ b/proposals/2787-portable-identities.md @@ -8,8 +8,8 @@ accounts. It is still a work-in-progress—some things that need attention include: -- How to handle multiple homeservers joining the same room, all with attestations - from the same UPK, and how they synchronise state amongst themselves; +- How to handle multiple homeservers joining the same room, since they will have + their own membership events, and clients may wish to disambiguate these; - How to handle invites, given that you won't know a UDK until after the user has joined the room; - How to adequately disconnect UDKs from UPKs as a part of a data removal request @@ -95,24 +95,22 @@ using the UDK. The completed attestation will take a format similar to this: ``` -"attestations": [ - { - "content": { - "identity": ~upk_that_is_attesting", - "delegate": "^udk_that_is_being_attested", - "server_name": "example.com", - "expires": 15895491111111 +"attestation": { + "content": { + "identity": ~upk_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 + }, + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" }, - "signatures": { - "~upk_that_is_attesting": { - "ed25519": "upk_signature" - }, - "~udk_that_is_being_attested": { - "ed25519": "udk_signature" - } + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" } } -] +} ``` The attestation contains a `"server_name"` field which contains the name of the server @@ -122,15 +120,6 @@ will not be able to work out where to route messages for this UDK. The attestation `"content"` key will then be canonicalised and signed, once by the UPK and then once by the homeserver that issued the UDK. -Multiple attestations can be placed into a single membership event, each for a separate -UDK and `"server_name"`, allowing multiple servers to participate in the same room on -behalf of a single user. It is required that each of the `"server_names"` in each -attestation is considered when sending federated events, rather than relying on the -domain names from the `"state_key"` field as today. - -There should be only one attestation in `"attestations"` per UDK and `"server_name"` -pair. - #### Validity The attestation will be valid from the point that it is sent (in effect, from the @@ -182,34 +171,32 @@ A membership event including an attestation may look something like this: "avatar_url": "mxc://here/is/neilalexander.png", "displayname": "neilalexander", "membership": "join", - "attestations": [ - { - "content": { - "identity": ~upk_that_is_attesting", - "delegate": "^udk_that_is_being_attested", - "server_name": "example.com", - "expires": 15895491111111 + "attestation": { + "content": { + "identity": ~upk_that_is_attesting", + "delegate": "^udk_that_is_being_attested", + "server_name": "example.com", + "expires": 15895491111111 + }, + "signatures": { + "~upk_that_is_attesting": { + "ed25519": "upk_signature" }, - "signatures": { - "~upk_that_is_attesting": { - "ed25519": "upk_signature" - }, - "~udk_that_is_being_attested": { - "ed25519": "udk_signature" - } + "~udk_that_is_being_attested": { + "ed25519": "udk_signature" } } - ] + } }, "origin_server_ts": 1589549295296, - "sender": "^upk_that_is_attesting", + "sender": "^udk_that_is_being_attested", "signatures": { "^udk_that_is_being_attested": ... }, "hashes": { "sha256": ..., } - "state_key": "^upk_that_is_attesting", + "state_key": "^udk_that_is_being_attested", "type": "m.room.member", "unsigned": { "age": 25, @@ -222,6 +209,10 @@ A membership event including an attestation may look something like this: Note that there is no MXID in the `"sender"` and `"state_key"` fields, nor in the `"signatures"` field of the event itself - these are now referencing the UPKs. +Multiple servers wanting to join on behalf of the same user should send their own +membership events, each with an attestation as created and signed by the user. +There may be a need for clients to disambiguate users. + ### Timeline event format Otherwise, the event format remains unchanged, with only one exception: that the @@ -237,7 +228,7 @@ itself as today: "msgtype": "m.text" }, "origin_server_ts": 1589549295384, - "sender": "^upk_that_is_attesting", + "sender": "^udk_that_is_being_attested", "signatures": { "^udk_that_is_being_attested": ... }, @@ -275,7 +266,7 @@ to send events into the room on behalf of the user. To satisfy data deletion requests, or where it may be important to fully remove links between UDKs and UPKs for legal compliance, it should be possible to redact the -membership events to remove the `"attestations"` section from them. +membership events to remove the `"attestation"` section from them. This may need to be done recursively, following the `"auth_events"`, to remove all historical attestations too. @@ -285,7 +276,7 @@ verify that the events were allowed to be sent? As the redaction algorithms already have rules for `m.room.member` events which will preserve the `"membership"` key, it should be possible to redact any other personally -identifiable information such as the `"attestations"`, the `"display_name"` or the +identifiable information such as the `"attestation"`, the `"display_name"` or the `"avatar_url"` without issue. The UDK signature will remain in the event, but without the attestation, it will not