Skip to content

Commit 2a503b3

Browse files
committed
add proposal for identity and key agreement for spaces
1 parent 5cbd532 commit 2a503b3

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

docs/identity.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Identity
2+
3+
## Goals
4+
5+
- Allow all sorts of wallet providers or wallets integrations
6+
- Avoid passwords for encryptions keys
7+
8+
## Proposal A: Wallet to sign locally stored keys
9+
10+
### Sign up
11+
12+
- [UI] Click sign up
13+
- During signup a key pair is generated that is stored locally
14+
- [UI] Sign with your wallet
15+
- The key pair is signed by the wallet and uploaded to the relay server
16+
- [UI] Modal shown with recovery phrase
17+
- The key pair is encrypted with a backup key (recovery phrase) and stored in the relay server
18+
19+
### Sign in with another browser/device
20+
21+
- [UI] Click sign in
22+
- A new key pair is generated and stored locally
23+
- [UI] Sign with your wallet
24+
- The key pair needs to be signed by the wallet and uploaded to the relay server
25+
26+
### Account recovery
27+
28+
- [UI] Click recover account
29+
- The user can enter the recovery key
30+
- [UI] Enter recovery phrase in a form
31+
- The key pair is fetched from the server, decrypted and stored locally
32+
33+
### Device management
34+
35+
- [UI] See a list of devices
36+
- From the server you can fetch a list of devices that are signed by the wallet
37+
- [UI] Click on revoke device and sign with your wallet
38+
- You can revoke a device by signing with the wallet that the device should be revoked
39+
40+
### Remarks
41+
42+
If we go down that route we probably still want some form of user keypair that can be unlocked with these device keys. The reason here is that every browser sign in would be a new device and this would mean you need if I would want to send you the key to a workspace I would need to encrypt it possibly for hundreds of devices instead of one. In addition it's quite privacy concern because you basically can track logins from other users.
43+
Key rotation of the user-key pair is relatively easy since this can be done with signing with the wallet.
44+
45+
One open question for me is if the current user public key should be stored on chain or if it's fine to trust the server to be honest. Due the wallet the server can never inject their own public key, but it could withhold the information of a removed device. Maybe that's up an option and up to the developer using the SDK?
46+
47+
This is the most wallet oriented approach, but feels unnecessary complex in the Web3 context. For non-web3 context this makes a lot of sense and is something I thinking a lot about here: https://github.com/serenity-kit/identity
48+
49+
## Proposal B: Wallet and additionally Passkey
50+
51+
### Sign up
52+
53+
- [UI] Click the sign up button and need to log in with a passkey
54+
- A passkey keypair is created
55+
- [UI] Sign with your wallet
56+
- The public key of your passkey is signed with your wallet (this actually could be completely optional and is only relevant in the Web3 context).
57+
58+
### Sign in with another browser/device
59+
60+
- [UI] Click sign in and use your passkey
61+
62+
### Remarks
63+
64+
I think the easiest would be to require a passkey that is synced by the user and a user can have only one active passkey per application. Otherwise you run into the same complexity with device and user keys as in proposal A.
65+
66+
Same as in Proposal A we need to decide if the public key of the passkey should be stored on chain or if it's fine to trust the server to be honest. Or could be up to the developer using the SDK.
67+
68+
Not sure how solid it is, but the Passkey part has been built before:
69+
70+
- https://github.com/mylofi/webauthn-local-client
71+
- https://github.com/mylofi/local-data-lock (not sure if it's 100% secure, but the future PRF extension of Passkeys will be - we could use this method temporarily)
72+
73+
## Proposal C: Metamask Snaps
74+
75+
While not feasible at the moment, Metamask Snaps could be a great way to handle identity. The user would use the Wallet to sign in an be done.
76+
77+
### Sign up
78+
79+
- [UI] Click sign up
80+
- Key pair is generated
81+
- [UI] Sign with your wallet
82+
- The keypair is stored encrypted in the Wallet
83+
84+
### Sign in with another browser/device
85+
86+
- [UI] Click sign in
87+
- [UI] Sign with your wallet
88+
- The keypair is decrypted in the Wallet
89+
90+
### Remarks
91+
92+
This is the most user friendly approach, but would require lock-in to Metamask.
93+
94+
Optionally a recovery key could be created, but probably better to leave it up to the user to manage the wallet properly. Depending on how Snaps work the encrypted key might have to be backed up by the user.

docs/key-agreement-for-spaces.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Key Agreement for Spaces
2+
3+
It's easy to create an initial key with a group of people and then share it. Once it leaked or if someone is removed from the group it's best practice to rotate the key.
4+
5+
## Proposal A: MLS
6+
7+
MLS is a relatively new standard that has been designed over years and is not used in dozens of projects (Cisco, Discord https://discord.com/blog/meet-dave-e2ee-for-audio-video). It's a protocol that is designed to be secure and scalable. It's a bit more complex than the other options but it's very secure and can even be post-quantum secure when picking the right algorithms.
8+
9+
Downside is that it requires a system to order the events of when a new device/user got added to a group. Usually this is done by a server. We could do so as well. Alternatively we could implement this in a blockchain.
10+
11+
One other downside is that there is no out of the Box JavaScript version:
12+
13+
- OpenMLS builds to WASM, but has no JS bindings:
14+
- https://github.com/openmls/openmls
15+
- https://github.com/openmls/openmls/issues/487
16+
- AWS implementation has wasm support, but didn't see JS bindings: https://github.com/awslabs/mls-rs
17+
18+
Implementations: https://github.com/mlswg/mls-implementations/blob/main/implementation_list.md
19+
Spec: https://datatracker.ietf.org/doc/rfc9420/
20+
21+
## Proposal B: Implement DCGKA
22+
23+
DCGKA is fully decentralized key agreement algorithm: https://eprint.iacr.org/2020/1281. Currently multiple teams implementing it, but so far no one has every deployed it.
24+
25+
It was developed by Martin Kleppmann, Matthew Weidner and others
26+
27+
## Proposal C: Implement a custom solution
28+
29+
This can be relatively simple:
30+
31+
- Create a new key
32+
- Encrypt the key for ever user public key that should have access
33+
- Store all of them on the server
34+
35+
This would require a central server again to trust telling everyone that a key rotation happened and ideally block syncs that happened with an old key. We also could use a blockchain to store the information that a new key rotation took place. That would be more secure since the server can't betray the users.
36+
37+
This is what I did in Serenity since OpenMLS was far away from being standardized when I started. Instead of a blockchain I used a signature chain to ensure the integrity over time.

0 commit comments

Comments
 (0)