This is a SHORT document, explaining the security measures in place. It's not the place for AI slop, or legaleeze.
There are two auth flows: one for the admin dashboard, one for devices (Electron app).
A passphrase-based system. The passphrase is set via DASHBOARD_SECRET env var on the server.
- User enters passphrase on login page
- Server compares it to
DASHBOARD_SECRET - If valid, sets an httpOnly cookie (
context_admin) containing the passphrase - Cookie settings: httpOnly, secure in production, sameSite=lax, 1 year expiry
- Subsequent requests check if cookie value matches
DASHBOARD_SECRET
In development, if DASHBOARD_SECRET is unset, auth is bypassed entirely.
Devices authenticate via a shared secret:
- Set
API_WRITE_SECRETenv var on the server - Enter the same secret in the desktop app settings
- Desktop app sends it as
Authorization: Bearer <secret>header - Server rejects requests where the token doesn't match
If API_WRITE_SECRET is unset on the server, device auth is bypassed (for development).
API read is actually more sensitive than write.
Messages and screenshots are encrypted on the desktop before upload. The encryption key never leaves your browser.
- Desktop app encrypts data locally before sending to the server
- Server stores encrypted blobs (it cannot read your data)
- Web dashboard downloads encrypted data and decrypts it locally
- The encryption key is stored in browser
sessionStorage(must not be sent anywhere) - Decryption uses the Web Crypto API (
crypto.subtle) in your browser
The server has no way to decrypt your data. If you lose your encryption key, your data is unrecoverable.
Configure rate limiting in the Vercel dashboard under Firewall → + New Rule.
Recommended rule for API endpoints:
- Name:
api-rate-limit - If: Request Path starts with
/api - Rate Limit: Fixed Window, 300 seconds, 10 requests, Key: IP Address
- Then: Too Many Requests (429)
See docs/firewall-example.png for reference.