Skip to content
Get startedGetting started →

Secret vaults

A secret vault holds one secret (a recovery phrase, a private key, any bytes), encrypted so that only a passkey ceremony can decrypt it. Vaults cover the cases where key material must come from outside the passkey. They are the advanced pattern because the app must store the encrypted vault itself.

Vaults encrypt with AES-256-GCM, a symmetric cipher: one key both encrypts and decrypts. The cipher authenticates what it encrypts, so tampering with the stored bytes makes decryption fail. For each secret, the vault functions derive the encryption key from the passkey’s PRF evaluated against a fresh random 32-byte salt, and store that salt in the vault.

The vault round trip. A secret, a phrase, a key, or any bytes, is encrypted with AES-256-GCM. The encryption key material is the PRF output of a passkey ceremony run against a fresh random salt for this secret. The result is ordinary vault JSON, stored in localStorage, a backend, or a sync service, with the salt stored inside. Unlocking runs the same ceremony with the stored salt, which reproduces the key and recovers the secret. Tampering with the stored bytes makes decryption fail. Secret AES-256-GCM Passkey ceremony PRF output Vault JSON unlock Secret

The main case is migration: an account created elsewhere, with an existing recovery phrase or private key, moves to passkey sign-in by encrypting that secret once. Losing the passkey still loses access through mera, but any surviving copy of the secret restores the account.

Where the vault lives, how it syncs, and how it survives device loss are design decisions the app owns. Losing every copy of both the vault and the secret loses the account.