Security Whitepaper
This document explains the technical mechanisms behind Dim Notes' encryption and security model. It is written for users who want to verify our claims rather than take them on faith. Last updated: April 2026.
Dim Notes uses a client-server architecture where encryption and decryption happen exclusively in your browser or app — never on our servers. The server stores only ciphertext it cannot read.
The data flow for a note looks like this:
The Content Encryption Key (CEK) lives only on your device while your session is unlocked. It is never sent to our servers in raw form. The server stores a copy of your CEK that has itself been encrypted with a key derived from your PIN — so even that stored copy is opaque to us.
All encryption runs in the browser using the built-in window.crypto.subtle (Web Crypto API). We do not use any third-party crypto library. The algorithm is AES-256-GCM.
crypto.getRandomValues() for every encrypt call. IVs are never reused.File attachments are encrypted with the same AES-256-GCM scheme as notes, using the same per-account CEK, before being uploaded to cloud storage. The server stores the ciphertext bytes and an IV; it cannot read the file content.
Dim Notes uses a two-key system: a Content Encryption Key (CEK) that encrypts your data, and a Key Encryption Key (KEK) that protects the CEK.
CEK — Content Encryption Key
A 256-bit random AES key generated once when you first set up encryption. This key encrypts all your notes and attachments. It is stored on our server only in wrapped (encrypted) form. We never see the raw CEK.
KEK — Key Encryption Key
Derived from your PIN on your device using PBKDF2-SHA-256 with 100,000 iterations and a 256-bit random salt. The KEK wraps the CEK before sending it to the server. The KEK itself never leaves your device and is never stored anywhere.
When you enter your PIN to unlock, your device derives the KEK locally, uses it to unwrap the CEK from the server, and holds the CEK in memory for the duration of your unlock session. When the session expires or you lock manually, the CEK is discarded from memory.
Dim Notes has two separate authentication layers that operate independently.
Layer 1 — Account Login (Clerk)
Standard account authentication. Supports email + password, Google OAuth, Apple OAuth, and Microsoft OAuth. This layer controls who can access your account. Clerk manages session tokens via httpOnly cookies. Dim Notes never handles your OAuth provider credentials.
Layer 2 — Note Unlock (Encryption Gate)
A second gate that controls access to note content. Being logged in is not enough — you must also pass the unlock step before your notes are decrypted. This layer is independent of Layer 1; even if your account session is valid, a locked Dim Notes session hides all note content.
Unlock methods (you choose one at signup):
Auto-lock: Your session automatically locks after a configurable period of inactivity (5 minutes, 15 minutes, 30 minutes, 1 hour, or Never). The default is 15 minutes. After the initial unlock, re-locking always requires your PIN or biometrics — not a new TOTP or email code — to avoid constant interruptions.
The unlock session is tracked as an HS256 JWT stored in an httpOnly, SameSite=Strict cookie. The cookie is inaccessible to JavaScript running on the page, which prevents XSS from stealing the unlock session.
When you enable encryption, Dim Notes generates 10 single-use recovery codes in the format XXXX-XXXX-XXXX. These are the only way to recover your encrypted notes if you lose access to your PIN and your primary unlock method.
"Zero-knowledge" means we designed the system so that our servers cannot read your note content, even if compelled to by law enforcement, even if our database is breached.
We cannot read
We can see
Folder and tag names are encrypted using the same AES-256-GCM scheme as note content. They are decrypted client-side after you unlock your notes. While locked, folder and tag names are not visible — even on your own device.
We believe honesty about limitations is more useful than pretending they don't exist.
lib/crypto.ts uses standard Web Crypto API calls that can be independently verified by inspecting the JavaScript bundle in your browser's DevTools. We plan to open-source the repository after launch stabilizes.A threat model is a statement of what a security system does and does not protect against. Being specific about this is more useful than vague assurances.
Protected against
Not protected against
Questions about our security model? security@dimnotes.com
This document is updated when the security implementation changes. Effective April 2026.
We use analytics to improve Dim Notes. Your notes are never included.