Discoverable credentials
On the Registration page, the server always knew who it was registering a credential for — the demo account already existed. A discoverable credential (also called a resident key, since the credential resides on the authenticator rather than the server) flips that: the authenticator stores enough about the account that the browser can list it in a sign-in prompt before the server says anything about who's signing in.
That's what makes usernameless login possible — no text field, no "who are you" round trip. The visitor picks a passkey, and the assertion that comes back contains the credential ID. The server looks up which account that credential belongs to from the ID alone.
1. Register with a resident key required
Same registration ceremony as before, but this time
authenticatorSelection.residentKey is set to "required"
instead of the default "preferred" — the browser will refuse to
complete registration if the authenticator can't store one.
2. Sign in without typing a username
The request below sends an empty allowCredentials list — the server
isn't naming a credential, because it doesn't know who's asking yet.
const result = await verifyAuthenticationResponse({
response,
expectedChallenge: challenge.challenge,
expectedOrigin: rp.expectedOrigin,
expectedRPID: rp.expectedRPID,
credential: {
id: credItem.credentialId,
publicKey: isoBase64URL.toBuffer(credItem.publicKey),
counter: credItem.counter,
transports: credItem.transports as AuthenticatorTransportFuture[],
},
});
// Before that verification runs, the server resolves the credential ID from the assertion back to an account: