How your data is actually stored

This page describes exactly which database columns are encrypted and which aren't, and with what methods. Not a marketing summary — the real data structure.

Legacy entries (vault_entries table)

📄 Stored in plaintext

Technical metadata only: the row id, timestamps and the wrapped keys themselves. What does remain visible is that an entry was encrypted for a particular heir's account (the entry_beneficiary_keys table): that link is exactly how an heir finds their own key when the time comes, and encrypting it would make the access itself impossible. Your heirs' names and email addresses also stay readable, because we have to be able to notify those people.

🔒 Stored encrypted

An entry's title, category, beneficiary assignment and actual content (credentials, notes, wallet information, etc.) are assembled client-side into a single JSON object and encrypted with AES-256-GCM before any of it reaches our servers. We only ever store the ciphertext. Anyone reading our database therefore sees neither what kinds of assets you hold nor who is meant to inherit what.

Key management

Every entry gets its own randomly generated Data Encryption Key (DEK). That DEK is independently "wrapped" (encrypted) twice: once with a key derived from your Vault Password, once with a key derived from your Recovery Password. Both wraps are stored — so either password can independently decrypt the content, for example during inheritance or a password reset.

Key derivation
PBKDF2-SHA256, 1,000,000 iterations
Encryption
AES-GCM, 256-bit

Attached files (vault_entry_files table)

File uploads (Premium) use the same DEK as their entry — this means beneficiary/recovery access to files works through the exact same mechanism as text content, with no extra code.

📄 Stored in plaintext

File size, timestamps, and a randomly generated storage path. The storage path contains neither the original filename nor the file extension.

🔒 Stored encrypted

The file bytes themselves are encrypted before upload — the storage bucket only ever holds ciphertext, tagged with a generic content type so the file type isn't leaked via HTTP headers either. Filename and mime type are stored separately as a small encrypted JSON object.

Who can access what

Server-side access control (Row Level Security) ensures every user can only access their own rows — independent of encryption. These two protection layers are independent of each other: even a flaw in access control would only expose ciphertext, never a plaintext password or plaintext content, since the server never receives your Master or Recovery Password.