removing entropy part as it didn't add anything
All checks were successful
Release to Production / build_and_release (push) Successful in 24s

This commit is contained in:
_ 2025-01-13 00:37:43 +00:00
parent f9be77ec7c
commit e209cea19c

View File

@ -3,21 +3,28 @@
In creating an email flow that maintains PRIVACY and SECURITY whilst also being convenient to use, the following principles were observed: In creating an email flow that maintains PRIVACY and SECURITY whilst also being convenient to use, the following principles were observed:
- Keypair must be generated client-side - Keypair must be generated client-side
- Keypair must be protected by a password - Keypair must be protected by a long and complex password
- There must be protection from keyloggers
- It must be possible to change the password - It must be possible to change the password
- It must remain possible to work offline - It must remain possible to work offline
- Network traffic must not contain identifying metadata - Network traffic must not contain identifying metadata
All of the above is achieved using a high level flow as follows: All of the above is achieved using a high level signup flow as follows:
1. Generate temporary key pair for secure server communication 1. User provides email and complex password
2. Validate email using a 6 digit code 2. These are used to encrypt a locally generated keypair into a backup
3. Provide some server side entropy to client 3. Email address, Public Key and encrypted backup are sent to the server
4. Combine entropy + complex user password to encrypt the final keypair 4. Account is validated
5. Store the encrypted keypair on the server
The password is only used to encrypt the key and is never stored or sent anywhere. Hence, the server cannot decrypt the backup. All key signing / encryption operations happen on client side using [private class properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties). The password is only used to encrypt/decrypt the local backup and is never stored or sent anywhere.
When perforing a login, the flow is:
1. Generate a temporary key pair for secure server communication
2. Validate the email
3. Provide the encrypted keypair for the user to unlock
All key signing / encryption operations happen on client side using [private class properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties).
## SIGNUP FLOW ## SIGNUP FLOW
@ -27,47 +34,44 @@ sequenceDiagram
autoNumber autoNumber
actor U as SIGit User actor U as SIGit User
participant W as SIGit Website participant W as SIGit Website
participant D as DVM participant D as Server
Participant DB as DataBase Participant DB
Note over W,D: All comms over <br> Nostr Relay Note over W,D: All comms encrypted with throwaway <br>(ephemeral) client keys and a <br>.well-known server key
U->>W: Click SIGNUP and enter <br>email address U->>W: Click SIGNUP
Note over W: Ephemeral key generated <br> to communicate with DVM U->>W: Provide Email and Complex Password
W->>D: Request Account Note over W: Validate Email<br>Ensure Complex Password
Note right of W: Event uses PoW and<br> encrypts only EMAIL<br> to dvm@sigit.io pubkey
D -x DB: Verify PoW and check<br> if email exists Note right of U: User is warned that they CANNOT<br>RESET PASSWORD, should USE <br>PASSWORD MANAGER etc
Note over D: If email already exists, <br>send user to LOGIN.<br> Otherwise#58;
D->>DB: Create Temp Session
Note over DB: SESSION entry#58;<br>#128274;session.pubkey="ephemeral pubkey"<br>session.email=lowcase($EMAIL)<br>session.email_code=INT (6 digits)<br>session.created_at=now() Note over W: Nostr Keypair Generated <br> & Encrypted inside a <br> PRIVATE method,<br>with COMPLEX password.<br> Password variable is not <br>stored, sent or printed <br> anywhere. <br>Any sensitive variables <br>are immediately destroyed.
W->>D: Request account activation
Note right of W: Event uses PoW and<br> encrypts PUBKEY, EMAIL,<br> and the encrypted BACKUP<br> to the dvm@sigit.io pubkey<br> using the ephemeral key
Note over D: Verify PoW, <br>event.created_at,<br>event.id
D -x DB: Check if email exists
Note over D: If email already exists, and <br>user.last_seen <> null then <br>send user to LOGIN.<br><br>If email exists and last_seen<br> is null, then DELETE the <br>current entry.<br><br> Otherwise#58;
D->>DB: Create DB entries
Note over DB: USER insert#58;<br>#128274;user.id=uid()<br>user.pubkey=lowcase($PUBKEY)<br>user.email=lowcase($EMAIL)<br>user.last_seen=null<br>user.created_at=now()<br>user.bkp=$BACKUP
Note over DB: SESSION insert#58;<br>#128274;session.pubkey="ephemeral pubkey"<br>session.email_code=INT (6 digits)<br>session.user_id=user.id<br>session.created_at=now()
D->>U: Send session.email_code via email D->>U: Send session.email_code via email
D->>W: Account created D->>W: Account created
Note left of D: Payload is an empty string or<br> an encrypted (and detailed)<br> error message Note left of D: Payload is the user.id and/or<br> an encrypted (and detailed)<br> error message
Note over W: Verify DVM pubkey, <br> event.created_at,<br>event.id
W->>U: Tell user to check email and<br>to open it in the <br> SAME BROWSER SESSION W->>U: Tell user to check email and<br>to open it in the <br> SAME BROWSER SESSION
Note over W: Screen to accept the 6 digits <br> is already displayed<br>(mobile optimised if relevant) Note over W: Screen to accept the 6 digits <br> is already displayed<br>(mobile optimised if relevant)
U->>W: User opens link or enters the code U->>W: User opens link or enters the code
W->>D: Verify Account W->>D: Verify Account
Note right of W: Event uses PoW and <br>encrypts only CODE<br> to DVM pubkey Note right of W: Event uses PoW and <br>encrypts both user_id <br>and email_code<br> to DVM pubkey
D -x DB: Check email_code where <br>session pk=event pk D -x DB: Check email_code where <br>session pk=event pk
D->>DB: If code matches,<br>create User Account D->>DB: If email_code matches, <br>update USER table where<br> session.user_id=user.id
Note over DB: USER entry#58;<br>#128274;user.id=uid()<br>user.email=session.email<br>user.pubkey=""<br>user.activated=false<br>user.created_at=now()<br>user.bkp=""<br>user.entropy=uid()
D->>W: Provide user.entropy
Note left of D: Payload encrypted to ephemeral <br>pubkey. Is either a UID or a <br> detailed error message.
Note over W: Client verifies that <br> DVM response came from <br> DVM pubkey
W->>U: Ask for secure password
Note right of U: This password is what prevents<br>backend from decrypting the nsec
Note right of U: User is warned that they CANNOT<br>RESET PASSWORD, should USE <br>PASSWORD MANAGER etc
U->>W: Enter password (twice)
Note over W: Nostr Keypair Generated <br> & Encrypted inside a <br> PRIVATE METHOD,<br>using password + entropy.<br> Password variable is not <br>stored, sent or printed <br> anywhere. Temporary <br>variables are destroyed.
W->>D: Request account activation Note over DB: USER update#58;<br>user.last_seen=now()
Note right of W: Event uses PoW and<br> encrypts both PUBKEY<br> and the already-<br>encrypted BACKUP<br> to the DVM pubkey
D -x DB: Ensure event pubkey <br> in SESSION table
D->>DB: Update Account
Note over DB: user.activated=true <br>user.pubkey=$pubkey<br>user.bkp=$backup
D->>W: Account activated D->>W: Account activated
Note left of D: Payload is an empty string or<br> an encrypted (and detailed)<br> error message Note left of D: Payload is an empty string or<br> an encrypted (and detailed)<br> error message
Note over W: Verify DVM pubkey, <br> event.created_at,<br>event.id
W->>U: User is automatically logged in W->>U: User is automatically logged in
Note over W: Ephemeral key is destroyed<br>Default relay list applied Note over W: Ephemeral key is destroyed<br>Default relay list is broadcast<br> using the user pubkey
``` ```