productJuly 10, 2026·3 min read

How the WarpDesk Shared Vault Works Behind the Scenes

The vault is the surface most WarpDesk users spend the most time in, so it's worth explaining exactly what happens under the hood — without going full engineering deep-dive.

Anatomy of a vault entry

Every entry has: a service (from our internal catalog, which is where the logo comes from), a username or email, a password, an optional TOTP secret, an owner (the member who created it), and a family (the container it belongs to). Everything else — favorite status, notes, custom category — is metadata.

Where the data lives

Vault rows live in a managed Postgres database. Each row has a `family_id` column, and every SELECT/INSERT/UPDATE/DELETE goes through Row-Level Security policies that filter on `family_id = <current user's family>`. That's not application-level filtering — it's enforced by the database itself. If application code ever tried to fetch the wrong family's rows, the database would simply return zero rows.

What happens when you click "reveal"

You'd expect the reveal button to fire a network request. It does — but only for the raw password field, and only after re-checking your session. The service logo and username are already in the DOM. The password is fetched on demand and dropped into the field, then cleared from memory when you close the dialog.

The TOTP path

TOTP secrets are stored the same way as passwords, plus a "type" tag. When a card renders, we run the TOTP algorithm client-side to produce the current 6-digit code and a countdown ring. The secret never leaves the vault; only the derived code appears in the UI.

Ownership without gatekeeping

Every entry has an owner, but "owner" is a light concept. It's who created the entry and who gets attributed in the activity log. It does *not* mean the owner is the only one who can edit — any family member with the right role can update or delete. This matters because in real households the person who signed up for Netflix is rarely the person who ends up managing it.

The service catalog

We keep a curated catalog of ~230 popular services. When you add an entry, the service picker searches that catalog and attaches the right logo (via Logo.dev). If your service isn't in the catalog, you can add a custom entry — you just won't get a pre-baked logo.

Search and category filtering

The vault supports substring search across service, username, and category. Categories are inferred from the service (streaming, finance, utilities, etc.) but you can override them per entry. The search is client-side after the initial fetch, so it's snappy even with hundreds of entries.

Favorites, activity, and audit

Marking an entry as a favorite bubbles it to the top. Every mutation writes an activity log row that any family member can read — who added, edited, or deleted what, and when. That log is the single source of truth for "wait, who changed the Hulu password?"

What we don't do

We don't currently support attached files, secure notes as a separate object type, or hardware key registration on the vault side (only for account login). Those are on the list but haven't shipped.

Deletion semantics

Deleting an entry is a hard delete — the row is gone. There's no trash. That's deliberate; a shared vault with a "recently deleted" bucket is a vector for a departing family member to peek at things they shouldn't. If you accidentally delete an entry, you'll need to re-add it.

The threat model, honestly

The vault protects against: another family reading your data, an ex-member reading anything after you revoke them, and an application bug leaking rows across families (RLS blocks that too). It does not currently protect against: an attacker who fully compromises our infrastructure and can read the raw database, because we don't ship client-side zero-knowledge encryption yet. That's the trade-off that lets us ship features like TOTP preview and inbox search without a bespoke crypto path. We plan to close that gap in a future release.