Zero-knowledge model
How PulsVault's zero-knowledge design works — which data is encrypted on your device, which the server can read, dual credentials, and why a compromised server cannot recover your secrets.
Zero-knowledge means the server can prove who you are and what you may access, but can never read your secrets: passwords, secret fields, Notes and file attachments are encrypted and decrypted only on your device, and the server never possesses a key that could decrypt them.
It does not mean the server sees nothing. The descriptive parts of a vault item — its name, tags, remarks and the fields that are not marked secret — are stored so the server can read them. The exact line is drawn in What is end-to-end encrypted below.
The core separation: authorization vs. decryption#
PulsVault splits access into two independent concerns handled by different parties:
| Concern | Handled by | Mechanism |
|---|---|---|
| "Is this user allowed to access this vault?" | Server | JWT validation + vault ownership/sharing checks |
| "Can this user actually read the secrets?" | Client | Only the client holds the UMK → DEK chain in memory |
For your secrets, the server behaves as dumb encrypted storage: it authenticates, authorizes, stores and returns opaque encrypted blobs. It never decrypts them, never parses ciphertext, and never receives a raw encryption key. Even a request made with a stolen JWT returns secret fields only as ciphertext that is useless without the vault's DEK.
What is end-to-end encrypted#
Every item type defines which of its fields are secret. A secret field is encrypted on your device with the vault's key before it leaves; every other field is sent and stored as readable text — protected in transit and encrypted at rest on our servers, but readable by PulsVault.
| End-to-end encrypted (PulsVault cannot read) | Readable by PulsVault |
|---|---|
| Passwords, PINs, tokens, private keys, seed phrases, card numbers and security codes, and every other field an item type marks as secret | Item names, tags and remarks |
| The whole content of Notes — titles and bodies | Fields not marked secret — for example usernames, email addresses, website URLs, card-holder names, bank names and IBANs, document names and dates |
| File attachment contents | Vault and folder names and descriptions |
| Your master password, Access Key, Recovery Key and every vault key | That an item exists, its type, which vault it is in, when it changed, and who it is shared with |
Four item types have no secret field at all: Secure note, Medical record, Reward program and Document. Everything typed into them — and into any item's name, tags or remarks — is readable by PulsVault. For text that must stay private, use Notes, which are end-to-end encrypted, or a field marked secret.
This is the same statement our app-store privacy declarations make: passwords and other secret fields are end-to-end encrypted; item names and non-secret fields are encrypted in transit and at rest on our servers, but are readable by us.
What the server stores vs. never sees#
| Server stores (encrypted/hashed) | Server never sees |
|---|---|
| BCrypt hash of the master password | The raw master password (beyond login verification) |
| BCrypt hash of a one-way verifier of the Access Key | The raw Access Key — not even at signup |
| UMK wrapped with the password+Access-Key KEK | The raw User Master Key (UMK) |
| UMK recovery wrap (derived from the Recovery Key), BCrypt hash of a verifier of it | The raw Recovery Key — not even at signup or recovery |
| Per-vault DEKs wrapped with the UMK | Any raw vault DEK |
| Field-level ciphertext envelopes for secret fields | Any plaintext secret field |
| A secure link's encrypted payload | The link key (it lives in the URL #fragment) |
Your browser generates the Access Key and the Recovery Key at signup and shows them exactly once — it is your job to save them in the Emergency Kit. Neither is ever sent to PulsVault: to prove you hold a key, your browser sends a verifier — a one-way value derived from the key and your email address that opens nothing. PulsVault cannot retrieve or regenerate either key.
Two independent credentials#
Every account is protected by two cryptographic factors that are never combined server-side:
- Master Password — authenticates you (gate 1) and contributes the Password-Derived Secret (PDS) used in client-side key derivation.
- Access Key — a ~155-bit-entropy key (
PULS-XXXXXX-…) generated in your browser, required to derive the KEK that unwraps the UMK at vault unlock (gate 2).
Neither factor alone can decrypt anything: the PDS must be combined with the Access Key to derive the KEK, and the Access Key alone cannot authenticate. This is the foundation of the two-gate model.
Consequences of the design#
- Database breach: attacker gets ciphertext of your secrets and BCrypt hashes, no keys — plus the readable parts of your items (names, tags, remarks, non-secret fields).
- Full server compromise: the server has no UMK, KEK, or DEK to steal, so no secret field, Note or attachment can be decrypted.
- Password change: only re-wraps the UMK — no re-encryption of items, because keys and data are decoupled.
- The cost: losing both the master password and the Emergency Kit (Access Key + Recovery Key) makes the account unrecoverable by design. There is no admin backdoor.
Account recovery deliberately requires the Access Key and Recovery Key plus an emailed OTP — an email-only "forgot password" reset is intentionally not supported, because the server could never re-encrypt your secrets for a new password anyway.
Related#
- Encryption architecture — the full key hierarchy
- Security invariants — the guarantees we never break
- Threat model — attacker models and residual risks
- Zero-knowledge in 2 minutes — the short version