Security Model
End-to-End Encryption
uunn encrypts message content, document content and titles, vote choices, vote titles, and vote descriptions on your device using the Web Crypto API before they leave your browser. The server only stores ciphertext for these fields.
Note: Coarse metadata that the server needs in order to route requests — union names, usernames, membership lists, and timestamps — remains visible to the server. AI document drafting, when used, sends the prompt content to Google Gemini.
How It Works
Key Exchange — RSA-OAEP (2048-bit)
Each user generates an RSA key pair in their browser. The public key is stored on the server; the private key never leaves your device. When you join a union, the union's shared key is encrypted with your public key so only you can unlock it.
Content Encryption — AES-GCM (256-bit)
Each union has a shared AES-256 key. All messages and documents are encrypted with this key using AES-GCM with a unique 96-bit initialization vector (IV) per message, ensuring that identical messages produce different ciphertexts.
Key Backup — PBKDF2 (100,000 iterations)
Your private key can be backed up in an encrypted vault protected by your password. The password is never sent to the server — a key is derived locally using PBKDF2 with SHA-256 and used to encrypt the vault.
Zero-Knowledge Architecture
uunn is designed so that the server never has access to plaintext content. Even if the database is compromised or subpoenaed, message content remains encrypted and unreadable.
- All encryption and decryption happens client-side in your browser.
- Private keys are stored in session storage and cleared on logout.
- Passwords are hashed with bcrypt before storage — we never see plaintext passwords.
- No tracking cookies, no IP logging. We use Sentry for error monitoring only — it receives anonymized error reports with PII stripped, but no user content.
Threat Model
We design our system assuming that the server could be compromised or subpoenaed. Even in these cases, your message content remains secure.
What we protect against:
- Database leaks or breaches.
- Subpoenas for message content (we don't have it).
- Passive network observers and on-path attackers on networks where you trust the certificate authorities (HSTS enforced, TLS required).
Limitations:
- We cannot protect against a compromised device (e.g., keyloggers, screen capture).
- Managed work devices and company networks. Many employers install a corporate root certificate on managed devices and route traffic through a TLS-inspecting proxy. In that setup, the proxy can intercept and even modify the JavaScript uunn ships to your browser — bypassing client-side encryption entirely. HSTS does not prevent this, because the proxy presents a certificate that chains to a root the device already trusts. Do not use a work device or a company network for organizing. Use a personal phone or laptop on cellular data or a non-work Wi-Fi.
- Metadata (who is in which union, message timestamps) is visible to the server, though not to external observers.
- If you lose your password and your recovery key, your data cannot be recovered.
AI Document Drafting
uunn offers optional AI-powered document drafting and formalization features. When you use these features, the plaintext content you provide is sent to Google's Gemini API for processing. This is the only case where plaintext content leaves your browser. These features are entirely opt-in — if you do not use them, your content remains fully encrypted end-to-end.
Open Source
uunn is open source. You can inspect the cryptographic implementation, verify our claims, and audit the code yourself. We believe transparency is essential to trust.
Best Practices
- Use a strong, unique password.
- Use a pseudonym that doesn't identify you (e.g., "Blue Jay" not "John Smith").
- Do not organize on a work device or a company network — they can defeat the encryption. Use a personal device on cellular data or a non-work Wi-Fi.
- Verify invite codes with your coworkers in person.
- Log out when you're done — this clears your private key from the browser.