Add SelfFreezoneClient wrapper for Self components

- Created SelfFreezoneClient in Self components
- Wraps SDK FreezoneScriptClient for Self-specific operations
- Implements send_verification_email method
- Uses Rhai script template for email verification
- Includes template variable substitution
- Added serde-wasm-bindgen dependency

Usage:
  let client = SelfFreezoneClient::builder()
      .supervisor_url("http://localhost:8080")
      .secret("my-secret")
      .build()?;

  client.send_verification_email(
      "user@example.com",
      "123456",
      "https://verify.com/abc"
  ).await?;
This commit is contained in:
Timur Gordon
2025-11-03 16:16:18 +01:00
parent be061409af
commit f970f3fb58
33 changed files with 8947 additions and 449 deletions

View File

@@ -0,0 +1,299 @@
# 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<String>, // 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