Typelets implements a zero-knowledge encryption architecture where all note encryption and decryption happens exclusively in your browser. We cannot read your notes - even if we wanted to. This document details our security implementation for transparency and verification.
- All encryption/decryption occurs in the browser using the Web Crypto API
- Notes are encrypted before leaving your device
- The server never receives unencrypted data
- Even database administrators cannot read your notes
- We store only encrypted data
- Encryption keys are derived from user-specific secrets
- No master keys exist that could decrypt all user data
- Password reset means permanent data loss (by design)
Algorithm: AES-256-GCM
Key Derivation: PBKDF2-SHA256
Iterations: 250,000
Key Length: 256 bits
IV Length: 96 bits (12 bytes)
Salt Length: 128 bits (16 bytes)
On first login, users must set up a master password:
-
Master Password Setup (Required)
- User creates a strong password on first use
- Required at the start of every session
- Portable across all devices with same password
- Zero-knowledge: we cannot recover forgotten passwords
- Encrypts all notes with user-specific derivation
-
Master Password Encryption Flow
Input: masterPassword ↓ User-specific salt: "typelets-salt-{userId}-v1" ↓ PBKDF2 (250,000 iterations) ↓ AES-256-GCM Key (session only) ↓ Per-note encryption with unique salts
- Mandatory setup: Cannot access app without setting master password
- Session protection: Master password required each session
- No backdoors: Lost passwords = permanently lost data
- Test verification: Encryption verified before committing
- Memory cleanup: Keys cleared on logout/session end
Each note has unique encryption parameters:
{
encryptedTitle: "base64...", // AES-256-GCM encrypted
encryptedContent: "base64...", // AES-256-GCM encrypted
iv: "base64...", // Unique 96-bit IV
salt: "base64..." // Unique 128-bit salt
}
Why per-note salts?
- Prevents rainbow table attacks
- Ensures identical content produces different ciphertext
- Limits damage if a single key is compromised
- Makes cryptanalysis significantly harder
graph LR
A[Plain Text] --> B[Browser Encryption]
B --> C[Encrypted Data + IV + Salt]
C --> D[API Transport]
D --> E[Database Storage]
E --> F[API Retrieval]
F --> G[Browser Decryption]
G --> H[Plain Text Display]
style B fill:#90EE90
style G fill:#90EE90
style C fill:#FFB6C1
style E fill:#FFB6C1
- Decryption cache with TTL: 15-minute expiry
- Automatic cache cleanup: Every 5 minutes
- Size-limited cache: Prevents memory exhaustion
- User-scoped cleanup: On logout/switch
- HTTPS required: Web Crypto API only works over secure connections
- Modern browser needed: Chrome 37+, Firefox 34+, Safari 11+
- No plugins required: Native browser APIs only
- Clerk Authentication: Industry-standard OAuth/JWT
- Token-based API access: No passwords stored
- Automatic token refresh: Seamless security updates
Attack Vector | Protection Method |
---|---|
Server breach | Encrypted data only - no readable content |
Man-in-the-middle | HTTPS + encrypted payload |
Rainbow tables | Per-note salts (128-bit) |
Brute force | 250,000 PBKDF2 iterations |
Key reuse | Unique IV per encryption |
Memory dumps | Cache TTL + cleanup |
XSS attacks | CSP headers + input sanitization |
SQL injection | Parameterized queries + ORM |
We cannot protect against:
- Compromised user device (keyloggers, malware)
- Physical access to unlocked browser
- Weak master passwords (if used)
- Browser vulnerabilities
- Users who lose their encryption keys
- Account Creation: Sign up via Clerk authentication
- Master Password Setup (Required):
- Create a strong master password
- This becomes your encryption key
- Cannot be recovered if forgotten
- Confirmation: Encryption tested and verified
- Start Using: Create your first encrypted note
Login → Enter Master Password → Access Notes → Auto-lock on Session End
- 🔐 Locked: Master password required to access notes
- 🔓 Unlocked: Active session with decryption key in memory
- ⏰ Session End: Keys cleared, re-authentication required
- 🚪 Logout: All encryption keys purged from memory
- Open browser DevTools → Network tab
- Create/edit a note
- Inspect the API request payload
- Verify
title
andcontent
show as[ENCRYPTED]
- Verify presence of
encryptedTitle
,encryptedContent
,iv
,salt
-- Even with database access, you see only:
SELECT title, content FROM notes;
-- Returns: [ENCRYPTED], [ENCRYPTED]
SELECT encryptedTitle FROM notes;
-- Returns: Base64 encrypted data (unreadable)
- Use a strong master password: 16+ characters with mixed types
- Never share your password: Even we cannot recover it
- Regular backups: Export important notes periodically
- Use HTTPS only: Never access via HTTP
- Unique password: Don't reuse from other services
- Master Password: Required every session for security
- Zero-Knowledge: We never see your password or unencrypted data
- No recovery options: Lost password = lost data (by design)
- Export regularly: Your data, your responsibility
- NIST Approved: AES-256-GCM (FIPS 197)
- OWASP Compliant: Following encryption best practices
- PBKDF2 iterations: Exceeds OWASP 2023 recommendation (210,000)
- Web Crypto API: W3C standard implementation
- SubtleCrypto: Hardware acceleration when available
- Secure Context: HTTPS-only operation
No. Notes are encrypted in your browser before transmission. We only store encrypted data that we cannot decrypt.
Your data becomes permanently inaccessible. This is intentional - true security means even we cannot recover your data.
We do! The "ends" are your browser sessions. Each note is encrypted client-side (one end) and decrypted client-side (other end).
Yes. Attackers would only obtain encrypted data without the means to decrypt it. Your keys never leave your browser.
Absolutely! Our code is open source. Use browser DevTools to inspect network requests and see the encrypted payloads.
Security vs Performance balance. This provides ~0.5 seconds of computation on modern devices while exceeding OWASP recommendations.
AES-256 is quantum-resistant with effective 128-bit security against Grover's algorithm. We'll migrate to post-quantum algorithms when standardized.
Found a vulnerability? Please report it responsibly:
Email: [email protected]
PGP Key: [Available on request]
Response Time: Within 48 hours
We appreciate security researchers and will acknowledge your contribution (with permission).
For security-related questions:
- Documentation: https://typelets.com/security
- GitHub Issues: https://github.com/typelets/typelets-app/issues
- Email: [email protected]
Remember: True security means even we cannot access your data. Your privacy is not a feature - it's our foundation.