Security Whitepaper

How Dim Notes Protects Your Data

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: May 2026 · v1.0

1. Architecture Overview

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:

Your device (browser / desktop app)
├─ Note body typed → AES-256-GCM encrypt (CEK, random IV)
├─ Note title typed → AES-256-GCM encrypt (CEK, random IV)
│ [only ciphertext leaves the device]
└─ POST /api/notes ─────────────────────────────────────────▶ Neon DB
stores: encrypted_body
encrypted_title
body_iv, title_iv
timestamps, metadata
Your device (reading notes)
├─ GET /api/notes ◀─── server returns ciphertext ──────────── Neon DB
└─ AES-256-GCM decrypt (CEK) → plaintext rendered in editor

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.

2. Encryption Implementation

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.

  • Algorithm: AES-256-GCM (256-bit key, authenticated encryption with additional data). GCM provides both confidentiality and integrity — a tampered ciphertext will fail to decrypt rather than produce garbage output.
  • IV (Initialization Vector): 96-bit (12 bytes), generated fresh from crypto.getRandomValues() for every encrypt call. IVs are never reused.
  • What is encrypted: Note title, note body, and file attachments. These fields leave your device only as ciphertext.
  • What is not encrypted: Color labels, timestamps, and whether a note is pinned or archived. See Section 6 for the full breakdown.

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.

3. Key Derivation & Storage

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 Argon2id with m=65,536 (64 MiB), t=3, p=1 and a 256-bit random salt. Argon2id is the OWASP-recommended algorithm for password-based key derivation — its memory-hard design makes offline brute-force attacks using GPUs or ASICs significantly more expensive than PBKDF2 or bcrypt. 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.

The PBKDF2 salt is unique per account and stored on our server alongside the wrapped CEK. The salt is not a secret — its purpose is to make pre-computation attacks (rainbow tables) infeasible, which it achieves regardless of whether the attacker has the salt.

4. Authentication Layers

Dim Notes has two separate authentication layers that operate independently.

Layer 1 — Account Login

Standard account authentication. Supports email + password, Google OAuth, and Microsoft OAuth. This layer controls who can access your account. Session tokens are managed 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):

  • TOTP: Time-based one-time password via Google Authenticator or any compatible app. First unlock per session only.
  • Email OTP: Email verified once during setup; all subsequent unlocks use your PIN.
  • PIN: 4–6 digit PIN set by you. Required alongside TOTP/Email OTP to derive the encryption key. Always available as a fallback.

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.

Your PIN is the root secret for key derivation. TOTP verifies your identity on the first unlock per session, but your PIN is also required alongside it because the KEK is derived from the PIN. Email OTP users verify their email once during setup; all unlocks then use PIN directly.

5. Recovery Codes

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.

  • Each code independently encrypts a backup copy of your CEK using Argon2id-derived keys (same parameters as the PIN: m=65,536, t=3, p=1) with unique salts. The 10 backups are stored on our server.
  • Using a code decrypts its CEK backup and immediately marks the code as consumed. It cannot be reused.
  • We store a scrypt hash of each code for verification. We cannot reverse the hash to recover the original code.
  • Recovery codes are presented to you once at setup. If you lose them without saving copies, they are gone.
  • You can regenerate your recovery codes at any time. Regeneration creates a new set of 10 codes and invalidates all previous ones.
  • We cannot reset your PIN, restore your recovery codes, or recover your encryption key. This is intentional — it means a server breach cannot compromise your data.
If you lose your PIN and all 10 recovery codes, your encrypted notes are permanently unrecoverable. Not by you, not by us. Save your recovery codes somewhere safe — a password manager, printed paper, or offline storage. This is the trade-off of true end-to-end encryption.

6. Zero-Knowledge Architecture

"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

  • Note titles
  • Note body content
  • File attachment contents
  • Folder names
  • Tag names
  • Your raw PIN or recovery codes
  • Your encryption key (CEK)

We can see

  • Your account email
  • Note count and storage usage
  • Timestamps (created/updated)
  • Color labels
  • Whether notes are pinned or archived

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.

When law enforcement presents a valid court order, the only data we can produce is what is in the "We can see" column above. Note content is inaccessible to us and cannot be handed over regardless of legal process.

7. What We Don't Do

  • No AI processing of your notes. Your note content never touches a language model or any AI service.
  • No analytics on note content. Usage analytics (PostHog) track app-level events like "note created" — never what is inside a note.
  • No advertising, no ad networks, no tracking pixels.
  • No selling data. We are a subscription product. Our revenue comes from you, not from your data.
  • No third-party access to note content. Our infrastructure vendors (Neon, Cloudflare, Hetzner) receive only the encrypted ciphertext stored on their hardware — the same blobs we cannot read.

8. Known Limitations

We believe honesty about limitations is more useful than pretending they don't exist.

  • Metadata is visible. Note count, storage usage, timestamps, color labels, and whether notes are pinned or archived are stored in plaintext. This reveals usage patterns even without access to content.
  • Not open source (currently). Dim Notes is built and maintained by a solo developer. The codebase is not yet public. The encryption implementation in 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.
  • PIN strength matters. The security of your encryption depends on the strength of your PIN. A 4-digit PIN has 10,000 possible values. Argon2id (m=65,536 MiB, t=3) makes brute-force slow, but a longer PIN or using a random one is stronger. We recommend at least 6 digits.
  • Biometrics are mobile-only. Biometric unlock (fingerprint / Face ID) is available on the mobile app only. It does not change the underlying cryptography — it is a convenience gate that uses a stored PIN to derive the KEK. The PIN still underpins the encryption.

9. Threat Model

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

  • Server breach / database dump: Attackers who steal our database get ciphertext they cannot decrypt without your PIN.
  • Insider access: Dim Notes staff, contractors, or infrastructure providers cannot read note content. The server never holds the raw CEK.
  • Legal requests for note content: A court order served on Dim Notes or our infrastructure providers cannot produce plaintext note content — we do not have it.
  • Network interception: All client-server communication uses TLS. Even without E2E encryption, this would protect data in transit. With E2E, intercepted requests contain only ciphertext.
  • Cross-site scripting stealing note content: Note content is decrypted only when the unlock session is active. Even if an XSS attack runs on the page, it cannot access the unlock JWT (httpOnly cookie) and the CEK is held in memory only.

Not protected against

  • Compromised device: If an attacker has physical or remote access to your unlocked device, they can read your notes — the same way they could read anything else on your screen. Device security is outside the scope of Dim Notes.
  • Keyloggers: A keylogger on your device captures your PIN before it reaches the crypto layer. Dim Notes cannot detect or prevent this.
  • User error: Sharing your PIN, losing all recovery codes, or being socially engineered into providing credentials. We cannot protect against voluntary disclosure.
  • Malicious browser extensions: A malicious extension with broad page access could read DOM content or intercept decrypted text. Use a trusted browser environment.
  • Account takeover: If an attacker gains access to your Layer 1 account (email + password), they can initiate an unlock attempt. They still need your PIN, but account security is the first line of defense.

10. Account & Data Deletion

You can permanently delete your Dim Notes account and all associated data at any time. No data is retained after deletion.

Deletion removes the following immediately and irreversibly:

  • All notes, note versions, and drafts
  • All folders and tags
  • All file attachments (deleted from cloud storage)
  • Your unlock settings, PIN hash, TOTP secret, and recovery codes
  • Your active subscription (cancelled immediately with Paddle)
  • Your account credentials and session data

Verification before deletion: To prevent unauthorised deletion, you must verify ownership of your account email with a one-time code before the deletion is processed. The code expires after 10 minutes.

Deletion process

  1. 1.Go to Settings → Account → Delete account, or visit dimnotes.com/delete-account
  2. 2.Type DELETE (all caps) to confirm intent
  3. 3.A 6-digit verification code is sent to your account email
  4. 4.Enter the code to authorise the deletion
  5. 5.All data is permanently removed and a confirmation email is sent
Deletion is permanent. Your encrypted notes cannot be recovered after deletion — not by you, not by us. If you have important notes, export them first from within the app before deleting your account.

To delete your account: dimnotes.com/delete-account

Questions about our security model? [email protected]

This document is updated when the security implementation changes. v1.0 — May 2026.

We use analytics to improve Dim Notes. Your notes are never included.