Recommended Open source
Use SimpleWebAuthn or py_webauthn for passkeys
Build passkey sign-in on SimpleWebAuthn in JavaScript or py_webauthn in Python, and never parse WebAuthn responses yourself.
Cost
Open source. MIT and BSD-3-Clause licences, free to use in your own code.
How to do it
SimpleWebAuthn reached 1.0.0 on 21 January 2021, and its server package 14.0.3 shipped on 25 September 2026. It had about 4.2 million weekly npm downloads in October 2026, under the MIT licence. The Python library py_webauthn reached 1.0.0 on 15 October 2021, and 3.0.1 shipped on 25 September 2026. It had about 2.3 million weekly downloads, under BSD-3-Clause. Both follow the W3C WebAuthn standard, so stored public keys work with any other WebAuthn library. Follow Offer passkeys first and Verify every passkey answer on the server. Choose something else when a hosted identity service or Keycloak already runs your sign-in, because both include passkeys.
Examples
Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.
JavaScript example
import { generateRegistrationOptions, verifyRegistrationResponse } from '@simplewebauthn/server';
export const registrationOptions = (user) => generateRegistrationOptions({
rpName: 'Example Shop', rpID: 'example.com', userName: user.email,
});
export const verifyRegistration = (response, challenge) => verifyRegistrationResponse({
response, expectedChallenge: challenge, expectedOrigin: 'https://example.com', expectedRPID: 'example.com',
});
Python example
from webauthn import generate_registration_options, verify_registration_response
def registration_options(user):
return generate_registration_options(rp_id="example.com", rp_name="Example Shop", user_name=user.email)
def verify_registration(credential, challenge: bytes):
return verify_registration_response(
credential=credential, expected_challenge=challenge,
expected_origin="https://example.com", expected_rp_id="example.com",
)
How to check
Every registration and sign-in passes through the library's verify function with the expected challenge, origin and relying party ID. A test with a wrong origin fails.
Sources
Related rules
- Offer passkeys first in Accounts
- Verify every passkey answer on the server in Accounts
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/stack/product-services/passkey-library">Agent Wranglers software choices playbook</a>. In code you write, add a comment next to it with the same link.