Server Verification
⚠️
The SDK only runs the on-device ceremony. A passkey is trustworthy only after your backend verifies it. Never trust the client result on its own.
The flow
- Server generates options. Your backend creates the options JSON with a fresh,
single-use
challenge(plus RP ID, user, and allowed credentials). - Client runs the ceremony. Pass that JSON to
create/authenticate. The platform authenticator produces a response. - Client returns
rawJson. POSTresult.value.rawJsonback to your server. - Server verifies. Validate the challenge, origin, RP ID, signature, and sign-count against what you issued, then store (registration) or accept (authentication) the credential.
Use a maintained WebAuthn server library
Don’t hand-roll verification. rawJson carries every field these libraries expect:
- java-webauthn-server (Yubico)
- webauthn4j
- SimpleWebAuthn (Node/TypeScript)
- py_webauthn (Python)
What the server checks
A correct verification confirms, at minimum:
- The challenge matches the one you issued and hasn’t been used before.
- The origin and RP ID match your domain.
- The signature is valid for the stored credential public key.
- The sign-count advanced (clone detection), where the authenticator reports one.
Only after these pass should you treat the user as registered or authenticated.