About this tool
Review browser-flow configuration for passkey compatibility and fallback UX.
Most passkey rollouts that "do not work" are not broken code — they are a options object that quietly asks for the wrong thing. residentKey left at its default produces a second-factor credential, not a passkey. authenticatorAttachment set to platform blocks the phone-and-QR route. Conditional autofill with a non-empty allowCredentials does nothing at all, silently. Paste the PublicKeyCredentialCreationOptions or PublicKeyCredentialRequestOptions object you pass to navigator.credentials and this checks every member against the WebAuthn Level 3 rules for discoverable credentials, then asks the handful of fallback questions no options object can answer. It runs entirely in the page: no credential is created, nothing is sent anywhere.
Open Passkey Readiness Tester on AltFTool — it loads instantly in your browser.
Enter the "Origin the ceremony runs on", pick the "Ceremony", and for an authentication ceremony set the "Mediation passed to navigator.credentials.get()".
Paste your PublicKeyCredentialCreationOptions or PublicKeyCredentialRequestOptions into "Credential options JSON" (challenge and user.id in base64url), or load the "Registration example" or "Authentication example".
Read the findings on RP ID, challenge length, user handle, algorithms, resident key, user verification, attachment, attestation and extensions, tick the "Fallback and recovery" boxes your sign-in page actually does, then press "Copy review".
The RP ID has to be the origin's host or a parent domain of it, and it cannot be a public suffix. Get it wrong and the browser throws a SecurityError; get it too specific and moving sign-in to another subdomain later orphans every passkey on the account.
The specification says the user handle must not contain personally identifying information, because it is stored unencrypted on the authenticator. Base64url values are decoded and flagged when they turn out to be an email address or a readable username.
Six recovery and UX questions — a non-passkey route in, NotAllowedError handling, availability probing, the autocomplete token, cross-device sign-in, more than one passkey per account — each with the concrete failure it prevents.
It has to be discoverable, which means the authenticator stores the credential itself and can list it without being told the credential ID first. That comes from residentKey: "required" in authenticatorSelection. With "preferred" you may get a non-discoverable credential instead — it still authenticates when you supply allowCredentials, but it cannot do usernameless or autofill sign-in and it will not show up in the user's passkey list.
It restricts the ceremony to an authenticator built into the machine in front of the user. That excludes security keys and, more importantly, excludes the hybrid transport — scanning a QR code to use a passkey that lives on a phone. On a desktop without Windows Hello or Touch ID the user gets nothing at all. Leaving the member unset is the recommended default; WebAuthn Level 3's hints array is the softer way to express a preference.
Neither. It reads the static options object you paste and applies the specification's rules to it. It makes no network request, calls no WebAuthn API and never touches an authenticator, which is why you can safely paste production options into it.
Everything that happens after the browser returns a credential. Your server still has to verify the client data origin and type, the RP ID hash inside authenticatorData, the signature, the UV flag when you required user verification, the BE and BS backup flags if you care whether the passkey is synced, and the signature counter. It also cannot tell whether your challenge is genuinely random and single-use — only how many bytes long it is.