Entorno de pruebas de llaves de acceso online
Registra una llave de acceso con tu teléfono, tu portátil o tu llave de seguridad e inicia sesión con ella. La relying party se ejecuta en esta página y muestra cada paso que realiza un servidor; no se envía nada a ninguna parte.
100 % local: todo se ejecuta en tu navegador y nada se envía a ningún servidor
Este navegador
Configuración de la relying party
Credenciales registradas aquí
Aún no hay ninguna credencial: registra una primero.
Reproducir una ceremonia de la especificación
Ejecuta la relying party con los vectores de prueba de la especificación WebAuthn —registros e inicios de sesión generados con formatos de atestación reales— sin un autenticador.
Fuente: W3C Web Authentication Level 3, sección 16, Vectores de prueba (origen https://example.org, RP ID example.org), con su CA de atestación. Comprobado el 2026-10-20.
A relying party in your browser tab
A passkey is a WebAuthn credential: a key pair created by an authenticator — the secure hardware of your phone or laptop, a password manager, a USB security key — for exactly one website, its relying party. The private key never leaves the authenticator; the site stores only the public key and later checks signatures made with it. Because every signature covers the origin the browser actually talked to, a passkey cannot be phished.
Normally the relying party is a server. In this sandbox it is the page itself: it plays the server's role with the same code a server would run — options generation and the verification procedures of WebAuthn Level 3 §7.1 and §7.2 — so you can watch both sides of a ceremony with your own authenticator. The RP ID is this site's host name, which is why the passkeys you create here appear in your password manager as passkeys for this site.
Registration, step by step
Pressing Register a passkey generates PublicKeyCredentialCreationOptions exactly as a server would send them in JSON: the relying party, a user with a random 32-byte handle (never anything that identifies the person, §14.6.1), a fresh 32-byte challenge, the algorithms you allow, the credentials already registered in excludeCredentials, and your choices for residentKey, userVerification, attestation, attachment and hints. The browser turns them into the binary form with PublicKeyCredential.parseCreationOptionsFromJSON (the sandbox converts them itself where the browser lacks it), calls navigator.credentials.create(), and the response comes back through credential.toJSON(). Then the sandbox verifies, in the specification's order:
- clientDataJSON —
typeiswebauthn.create, the challenge is the one just issued, the origin is this page's origin, andcrossOriginandtopOriginare as expected; - authenticator data —
rpIdHashis SHA-256 of the RP ID; the flags: user present (UP), user verified (UV), backup eligible (BE) and backed up (BS), which tell a synced passkey from a device-bound one; - the credential — its ID, length and uniqueness, its COSE public key and algorithm against the ones offered, and the
credPropsextension that says whether it is discoverable; - the attestation statement —
none,packed,tpm,android-key,android-safetynet,fido-u2f,appleorcompound, each verified as §8 prescribes, and, if you paste roots from the FIDO Metadata Service, the certificate chain behind it.
If everything passes, the sandbox stores the credential record a server would keep — ID, public key, algorithm, signature counter, flags, transports, AAGUID — and shows it.
Sign-in, step by step
Sign in with a passkey sends PublicKeyCredentialRequestOptions with a new challenge — with an empty allow list, so that the authenticator offers the passkeys it holds for this site (discoverable sign-in, the passkey way), or with the credentials registered here. The assertion is checked against the stored record: the credential and its user handle, the client data (webauthn.get), the RP ID hash and flags, a backup-eligibility flag that must not change, the signature over authenticatorData ‖ SHA-256(clientDataJSON) with the stored public key, and the signature counter, which must increase unless the authenticator does not keep one (synced passkeys report 0). The updated record is shown and kept.
When a ceremony fails in the browser, the sandbox explains the DOMException: NotAllowedError for a cancelled or timed-out prompt or no matching credential, InvalidStateError when the authenticator already holds a credential in excludeCredentials, SecurityError for an RP ID the origin may not use.
Without an authenticator at hand, Replay a specification ceremony runs the same verification on the test vectors of WebAuthn Level 3 §16 — registrations with no attestation and with packed, TPM, Android Key, Apple and FIDO U2F attestation, each followed by a sign-in. To decode a response captured elsewhere, use the WebAuthn inspector; for the server side in your own stack, read Passkeys for developers: WebAuthn without the guesswork.