Back to blog

Privacy-First Productivity App: Local-First, Encrypted Sync, Zero Data Selling

Your study chaos, mood data, and focus patterns belong to YOU. Locked In is local-first by default — data never leaves your device unless you explicitly choose encrypted sync. No analytics on content, no AI training, no third-party sharing.

Most productivity apps: Your data = their asset. Stored on their servers. Analyzed. Sold. Subpoenable. Used to train AI.

Locked In: Your data = your data. Stays in your browser. Never leaves unless YOU sign in. Encrypted if it does. Zero exceptions.


The privacy spectrum

App TypeData LocationWho AccessesYour Control
Cloud-first (Notion, Todoist, Motion)Their serversEmployees, partners, law enforcementDelete account = hope they delete
Hybrid (Obsidian Sync, some planners)Local + optional cloudYou + cloud providerMore control, but cloud default
Locked InYour browser (localStorage)Only youYou own the keys. Cloud = opt-in only.

What "local-first" means in practice

Default: Zero network calls for YOUR content

Open lockedn.in → Loads from cache → Works 100% offline
Type chaos → AI API call (prompt only) → Plan returns
Save plan → localStorage.setItem('lockedin-v2', ...)
Mood check-in → localStorage
Timer session → localStorage
Streak → localStorage
**Zero bytes of personal content leave your device.**

Optional sync: You decide, you control

  1. You click "Sign in" (Google or email) — not before
  2. Encryption happens BEFORE leaving device (AES-256-GCM)
  3. Pepper key fetched from /api/security/pepper — requires YOUR valid Supabase JWT
  4. Supabase RLS — auth.uid()::text = user_id on every table, anon role = ALL GRANTS REVOKED
  5. Sign out → local data stays, cloud data untouched
  6. Clear all → wipes both instantly

What the AI sees (minimal, aggregated, never raw)

Each planning request sends:

{
  "mode": "study",
  "effort": "mid",
  "history": [...last 10 messages...],
  "userContext": {
    "streak": 14,
    "totalFocusMinutes": 1240,
    "blockCompletionRate": 87,
    "avgMood": 3.8,
    "avgEnergy": 4.1,
    "moodDirection": "improving",
    "preferredModes": ["study", "chill"],
    "totalPlansMade": 42,
    "alreadyPlannedToday": false
  }
}

Never sent: Raw mood history, exact timestamps, specific plan content, personal identifiers, referral codes, exact streak dates.

Only aggregated stats. The AI knows how you're doing, not what you did.


Encryption details (for the technical)

Algorithm: AES-256-GCM via Web Crypto API Key derivation: PBKDF2 (100,000 iterations) with:

  • User ID (salt)
  • JWT-gated pepper (fetched per-session from /api/security/pepper) Format: enc:v1:<ciphertext> Pepper rotation: Per-session, never stored

Result: Even Supabase cannot decrypt your data. Only your browser + your JWT can.


Supabase RLS: Database-level enforcement

Every table has 4 policies (SELECT/INSERT/UPDATE/DELETE):

auth.uid()::text = user_id

anon role: ALL GRANTS REVOKED — zero anonymous access possible.

PKCE auth flow — no implicit flow token leakage in URLs.


What we DON'T do (ever)

PracticeLocked In
Sell data to third parties❌ Never
Train AI on your content❌ Never (only aggregated stats)
Share with advertisers❌ Never
Analytics on your content❌ Never (Vercel Analytics = page views only)
Employee access to your journals❌ Impossible (client-side encryption)
Government backdoor❌ Impossible (we can't decrypt)
"Legitimate interest" processing❌ Never

Verification you can do yourself

  1. Open lockedn.in in incognito
  2. "Start free" → "Continue as guest"
  3. Type something deeply personal
  4. Get plan → complete it → check streak
  5. DevTools → Network tab → Filter: "supabase" → Zero requests
  6. DevTools → Application → LocalStorage → lockedin-v2 → See your data, encrypted or plain
  7. Close tab → reopen → data persists
  8. Sign in → Now Supabase requests appear (encrypted payloads only)

Local-first isn't marketing. It's verifiable architecture.


The "but convenience" counter-argument

"Cloud sync is convenient!"

Locked In gives you both:

  1. Guest mode — full features, local-only, zero friction
  2. Sign in — encrypted sync, same features, you choose when
  3. Sign out → back to guest, local data intact

No "create account to continue" walls. No "premium for sync." You own the data flow.


Try true privacy (30 seconds)

  1. lockedn.in → "Start free" → "Continue as guest"
  2. Type your actual chaos (grades, anxiety, burnout, ADHD)
  3. Get plan → complete it → mood check-in → streak
  4. DevTools → Network → supabase → Empty
  5. That's it. Your chaos. Your device. Your choice.

Locked In: The only productivity app where privacy isn't a feature — it's the architecture. Free, local-first, encrypted-if-synced. Try it here — no account required.

— Locked In

More posts