Avok has no seed phrase because the passkey is the wallet. The private key is derived from the
passkey on demand and wiped after each use.
The derivation
Two steps produce the key:
- PRF. During the WebAuthn ceremony, Avok evaluates the authenticator’s
PRF extension with a fixed salt,
passkey-access-vault/prf-salt/v0. The authenticator returns a secret that only a matching
credential can reproduce. WebAuthn scopes that evaluation to the pair (credential, rpId).
- HKDF. Avok runs the PRF output through HKDF-SHA256 to produce a 256-bit key
K, using
salt passkey-access-vault/hkdf-salt/v0 and info passkey-access-vault/wallet-key/v0.
K is the root. The EVM key is derived from K directly; the Solana ed25519 seed is derived
from K with its own info string, passkey-access-vault/solana-key/v0. No mnemonic is ever
created, so the entropy stays in bytes that Avok can zero.
rpId is the key’s scope
rpId does not enter the HKDF math. It enters as the WebAuthn scope of the PRF: only an origin
that matches the rpId can obtain the PRF output, and therefore only that origin can reconstruct
K. This has one practical consequence you must respect:
Changing the rpId changes the wallet. Every user gets a different address. Pin the rpId
explicitly and never infer it from a hostname. The SDK refuses to start without it.
The key is never at rest
Key K is derived inside a sandbox for exactly one signing gesture, then wiped (along with the
PRF output) in a finally block. There is no key in storage, in memory between gestures, or in
any backend. A device’s lasting access is exactly its passkey plus its encrypted access slot
on chain. See Access keys and the vault.