Zero Accessby Railmandocs

How it works

Sessions, step-up, and vault unlock as three independent layers.

How it works

Three proofs, three jobs. Products that merge them give attackers a free upgrade.

These are independent authorization and key-state layers, not three parallel product paths. Elevate can run alone; Vault uses the passkey composition; Chat extends the unlocked Vault identity.

The three layers

L0
Session

Better Auth cookie or bearer. Proves identity only.

  • Enough to list your wrap slots
  • Not enough to decrypt sealed data
  • Not enough for privileged account actions
L1
Elevate / sudo

Fresh passkey, TOTP, or password proof. Short TTL on the session.

  • Billing change, delete account, admin panel
  • Never puts a MEK in memory
L2
Vault unlock

Client unwraps the MEK with PRF, vault password, or recovery phrase.

  • MEK stays in tab memory
  • Does not grant sudo routes
LayerProvesDoes not prove
L0 SessionThis browser is signed inUser can decrypt data; user re-proved recently
L1 ElevateUser just re-provedMEK is available
L2 Vault unlockMEK is in this tabUser may hit admin APIs

Keep the paths separate

Elevate must not call vault unlock. Vault unlock must not mint elevate claims. Same human, different control planes.

L0 — Session

Normal Better Auth login (password, passkey login, OAuth, magic link). After login, loginFactors() can stamp a signed login factor on the session so later gates know how the session started.

L1 — Elevate

The user re-proves. The server stores an HMAC-signed claim on the session row (bound to the live session token). Default window is about five minutes, sliding when the product refreshes the claim.

Methods: password, TOTP, passkey. Passkey is optional — you can ship elevate with password and TOTP only.

Try it without a vault: Elevate demo.

L2 — Vault unlock

The client loads wrap slots from the blind store, then unwraps locally:

  • Passkey PRF — preferred daily path when the authenticator supports it
  • Vault password — PBKDF2 wrap
  • Recovery phrase — reset only (product policy), not daily unlock

The server only ever stored wrapped copies of the MEK.

The documented Vault product composition always includes the hardened passkey guard, even when a user chooses a vault password for a particular daily unlock.

A day in the life

  1. Sign in → L0.
  2. Open encrypted notes → load wraps → PRF or password → L2.
  3. Delete account → product asks for step-up → L1 → delete route runs.
  4. Lose the passkey → recovery phrase resets access → re-enroll daily methods.

Steps 2 and 3 never share a code path.

What the server stores

On the serverNever on the server
Wrapped MEK slotsRaw MEK
Association metadataMnemonic / recovery words
Account-recovery public materialPRF output / vault password
Sealed E2E envelopes (chat)Plaintext messages

On this page