Zero-access encryption by design
Your synced profile data is encrypted on your device before it ever reaches a server, so the server stores only encrypted blobs it can never read. Calendar app connections are a documented plaintext exception, scoped to your Calendar inbox and read-only subscriptions.
How encryption works
Graspee uses a client-side key hierarchy. Your password and a random salt are run through PBKDF2 with 200,000 iterations to derive a Key Encryption Key (KEK). The KEK encrypts a randomly generated Data Encryption Key (DEK). The DEK encrypts all your data using AES-GCM-256. Your password never leaves the browser.
What zero-access means
The server never sees your plaintext data, your password, or your encryption keys. Even with full database access, the server operator cannot read your notes, tasks, transactions, or other synced content. If you enable sync, the server relays encrypted blobs between your devices but cannot decrypt them. Calendar app connections are a documented exception: read-only subscription feeds are plaintext artifacts that external calendar apps must be able to read, and Quick Add events sent to your Calendar inbox are stored in plaintext while pending so the unlocked browser can import them. After import, ignore, expiry, or tombstone the staged plaintext is scrubbed.
Session security
Your DEK is encrypted under a temporary Session Wrapper Key stored in sessionStorage. It survives page refreshes but is cleared when you close the browser. Sessions use HttpOnly cookies with SameSite and Secure flags. CSRF protection is enforced via origin checking. Rate limiting protects authentication endpoints.
Sync encryption
Cloud sync uses Yjs CRDT documents encrypted client-side. The WebSocket transport carries only encrypted payloads. State vectors and updates are validated server-side for size but never decrypted. Compaction uses optimistic locking to prevent data loss.
Bank connection security
Provider credentials such as Plaid access tokens or Flinks login IDs are stored in your encrypted local shard, never in the server database. The server acts as a pass-through: it relays provider API calls and may hold sync payloads briefly in memory, but stores no durable provider data. HMAC ownership proofs bind tokens to your account statelessly. A separate connection link ledger holds non-reversible HMAC fingerprints of provider connection IDs to enforce per-user link allowance limits. Flinks is only available where the operator has enabled it.
Calendar app connections exception
Calendar app connections are an intentional, limited plaintext exception to zero-access. Read-only subscription artifacts are plaintext because external calendar apps must be able to read .ics, and Quick Add events from your calendar app are stored in plaintext in your Calendar inbox while pending so the unlocked browser can import them. The server keeps that staged inbox plaintext while pending and the published read-only subscription artifacts; for credentials and bearer tokens, only hashes are kept on the server, and the live subscription token is held in encrypted local storage on the unlocked browser. Pending events expire after 7 days, and staged plaintext is scrubbed after browser import, ignore, expiry, or tombstone. If a subscription URL leaks, rotate it from Settings to invalidate every existing subscriber.