01 · Introduction
Secret passkeys, minus the metadata.
A secret passkey is a keypair that lives in your device's secure hardware and only signs for one website. That much is private. This page covers what you hand over around the key.
What a secret passkey is
Secret passkeys are discoverable FIDO2 credentials, created and used through the WebAuthn browser API. The private key is generated inside a platform authenticator (Secure Enclave, TPM, Titan) or a roaming one (a security key such as a YubiKey), and it is never exported. Your website receives only a public key, and later only signatures.
Platform secret passkeys sync end-to-end encrypted through iCloud Keychain or Google Password Manager. Security keys don't sync at all. For a wallet, that choice is visible on-chain: see what authenticatorData reveals.
Creating one, privately
Most tutorials fill user with an email and request direct attestation. Both leak. Here is the call this site makes:
const credential = await navigator.credentials.create({
publicKey: {
challenge: crypto.getRandomValues(new Uint8Array(32)),
rp: { name: "UseSecret" },
user: {
id: crypto.getRandomValues(new Uint8Array(16)), // never an email or DB id
name: "anon-7f3a", // shown in OS UI + synced
displayName: "anon-7f3a",
},
pubKeyCredParams: [{ type: "public-key", alg: -7 }], // ES256 / P-256 only
authenticatorSelection: { residentKey: "preferred", userVerification: "required" },
attestation: "none", // don't ask for device certs
timeout: 60000,
},
});
// The public key is only handed to you here, as a DER SubjectPublicKeyInfo.
const spki = credential.response.getPublicKey();Paste it into your browser's DevTools console on any HTTPS page (or localhost, which also counts as a secure context), and the secret passkey will be bound to that page's domain.
Defaults worth changing
| Option | Common | Private |
|---|---|---|
| user.id | email / account id | 16 random bytes |
| user.name | email address | throwaway handle |
| attestation | "direct" | "none" |
| pubKeyCredParams | [-7, -257, …] | [-7] (P-256 only) |
| userVerification | "preferred" | "required" |
Why P-256 matters for Solana
Solana's native signatures are ed25519, and secret passkeys use P-256 (also called secp256r1). No mainstream authenticator signs with ed25519, so a secret passkey can't be a regular Solana keypair.
The bridge is the secp256r1 signature-verification precompile (SIMD-0075). A transaction includes an instruction carrying a public key, a signature and a message; the runtime verifies it; and a program can then authorize a vault on the secret passkey's behalf. Try it with your own secret passkey →