# Authentication Flows ## Overview Self implements a cryptographic challenge-response authentication system that eliminates the need for passwords while providing strong security guarantees. The system supports both new user registration and existing user authentication flows. ## Registration Flow ### Step-by-Step Process ```mermaid sequenceDiagram participant U as User participant C as Client (Browser) participant S as Server participant E as Email System Note over U,E: Phase 1: Email Verification U->>C: Enter name and email C->>S: POST /api/send-verification S->>E: Generate verification link S->>C: Verification sent response S-->>U: Display verification link (dev mode) Note over U,E: Phase 2: Email Confirmation U->>S: Click verification link S->>S: Mark email as verified S->>C: SSE notification (verified) C->>C: Update UI to show verified status Note over U,E: Phase 3: Key Generation U->>C: Click "Generate Keys" C->>C: Generate secp256k1 key pair C->>C: Display private key for backup U->>C: Copy private key (mandatory) U->>C: Enter encryption password C->>C: Encrypt private key with AES-256-GCM C->>C: Store encrypted key in localStorage Note over U,E: Phase 4: Key Confirmation U->>C: Paste private key for confirmation C->>C: Verify pasted key matches generated key U->>C: Confirm registration C->>S: POST /api/register {email, name, public_key} S->>S: Verify email is confirmed S->>S: Store user record S->>C: Registration success response C->>C: Complete registration flow ``` ### Registration Data Flow 1. **Email Collection** ```rust struct EmailVerificationRequest { email: String, } ``` 2. **Verification Status** ```rust struct VerificationStatus { email: String, verified: bool, verification_token: String, } ``` 3. **Key Generation** (Client-side) ```rust let keypair = generate_keypair()?; let encrypted_key = encrypt_private_key(&keypair.private_key, &password)?; ``` 4. **Registration Completion** ```rust struct RegistrationRequest { email: String, name: String, public_key: String, } ``` ### Security Measures - **Email Verification**: Prevents unauthorized registrations - **Key Backup Confirmation**: Ensures user has saved private key - **Client-side Encryption**: Private key never transmitted unencrypted - **Secure Random Generation**: Cryptographically secure key generation - **Password Validation**: Minimum 8 character password requirement ## Login Flow ### Step-by-Step Process ```mermaid sequenceDiagram participant U as User participant C as Client (Browser) participant S as Server participant V as Vault System Note over U,V: Phase 1: Identity Input U->>C: Enter public key or select identity C->>C: Validate public key format Note over U,V: Phase 2: Challenge Generation C->>S: Request authentication challenge S->>S: Generate random challenge S->>C: Return challenge + session info Note over U,V: Phase 3: Key Decryption U->>C: Enter password C->>V: Retrieve encrypted private key V->>C: Return encrypted key data C->>C: Decrypt private key with password Note over U,V: Phase 4: Challenge Response C->>C: Sign challenge with private key C->>S: POST /oauth/token {signature, public_key, challenge} S->>S: Verify signature against public key S->>S: Generate JWT token S->>C: Return access token Note over U,V: Phase 5: Session Establishment C->>C: Store JWT token C->>S: GET /oauth/userinfo (with Bearer token) S->>C: Return user profile C->>C: Complete login flow ``` ### OAuth 2.0 Token Request The login process follows OAuth 2.0 client credentials flow with cryptographic assertions: ```rust struct LoginRequest { grant_type: String, // "client_credentials" client_assertion_type: String, // "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" client_assertion: String, // Signed JWT containing challenge response public_key: String, // User's public key (client identifier) challenge: String, // Server-provided challenge scope: String, // Requested permissions } ``` ### JWT Token Structure ```rust struct Claims { sub: String, // Subject (public key) iss: String, // Issuer ("self-sovereign-identity") aud: String, // Audience ("identity-server") exp: usize, // Expiration time (1 hour) iat: usize, // Issued at time scope: String, // Granted scopes } ``` ### Challenge-Response Mechanism 1. **Challenge Generation** ```rust let challenge = Uuid::new_v4().to_string(); ``` 2. **Signature Creation** (Client-side) ```rust let signature = keypair.sign(&challenge)?; ``` 3. **Signature Verification** (Server-side) ```rust fn verify_signature(public_key: &str, challenge: &str, signature: &str) -> bool { // Verify signature matches challenge using public key } ``` ## Vault-Based Authentication ### Multi-Key Management The vault system allows users to store multiple encrypted keys and authenticate with any of them: ```mermaid sequenceDiagram participant U as User participant C as Client participant V as Vault Manager participant S as Server U->>C: Select identity from vault C->>V: List available identities V->>C: Return identity list U->>C: Choose identity and enter password C->>V: Decrypt selected identity key V->>C: Return decrypted private key C->>S: Authenticate with selected identity S->>C: Return session for selected identity ``` ### Vault Data Structure ```rust struct VaultEntry { id: String, name: String, email: String, public_key: String, encrypted_private_key: EncryptedPrivateKey, created_at: String, } struct EncryptedPrivateKey { encrypted_data: String, // Base64 encoded ciphertext nonce: String, // Base64 encoded nonce salt: String, // Base64 encoded salt } ``` ## Session Management ### JWT Token Lifecycle 1. **Token Issuance** - Generated after successful authentication - Contains user's public key as subject - 1-hour expiration time - Signed with server secret 2. **Token Usage** - Included in Authorization header as Bearer token - Required for accessing protected endpoints - Validated on each request 3. **Token Refresh** - Currently requires re-authentication - Future: Refresh token mechanism ### Session Storage ```javascript // Client-side session storage localStorage.setItem('jwt_token', access_token); localStorage.setItem('current_identity', public_key); localStorage.setItem('session_expires', expiration_time); ``` ## Error Handling ### Registration Errors - **Email Not Verified**: User must complete email verification - **Invalid Email Format**: Client-side validation prevents submission - **Key Generation Failed**: Retry with new random seed - **Encryption Failed**: Check password strength and retry - **Server Unavailable**: Retry with exponential backoff ### Authentication Errors - **Invalid Public Key**: Key format validation and user feedback - **Wrong Password**: Decryption failure, prompt for correct password - **Signature Verification Failed**: Invalid key or challenge tampering - **Token Expired**: Automatic re-authentication flow - **User Not Found**: Public key not registered, redirect to registration ### Error Response Format ```rust struct ErrorResponse { error: String, // OAuth 2.0 error code error_description: String, // Human-readable description error_uri: Option, // Optional documentation link } ``` ## Security Considerations ### Attack Mitigation 1. **Replay Attacks**: Challenges are single-use and time-limited 2. **Man-in-the-Middle**: HTTPS encryption for all communications 3. **Key Theft**: Private keys encrypted with user passwords 4. **Brute Force**: Rate limiting on authentication attempts 5. **Session Hijacking**: JWT tokens with short expiration times ### Privacy Protection - **No Password Storage**: Server never sees user passwords - **Minimal Data Collection**: Only email and public key stored - **Local Key Storage**: Private keys never leave user's device - **Anonymous Usage**: Public keys don't reveal personal information ### Compliance Considerations - **GDPR**: Users control their own data, right to deletion - **OAuth 2.0**: Standard token-based authentication - **OpenID Connect**: Compatible user info endpoint - **WebAuthn**: Future integration for hardware token support