Component 2 / Page Identity
Web Development Tools

WebAuthn & FIDO2 Interactive Testing Playground

A real-time sandbox to simulate, capture, and decode WebAuthn registration and authentication flows.

Component 3 / Authority & Trust
Author
Marcus Chen
Senior Identity Engineer specializing in FIDO2 protocol implementation, WebAuthn browser APIs, and enterprise IAM architecture with 12 years in authentication systems.
Reviewer
Dr. Yuki Tanaka
Cryptographic Protocol Reviewer with expertise in FIDO Alliance specifications, CTAP2 interop testing, and authenticator attestation chain validation.
Trust Indicator
500,000+ developer sessions
Built for debugging real WebAuthn flows. Outputs are decoded locally in your browser; no credentials are transmitted to any server.
Component 4 / Core Tool

Registration Options

Configure the public key credential creation parameters. These mirror the WebAuthn API options passed to navigator.credentials.create().

The domain that owns the credential. Must match the effective domain or be a registrable subdomain.
Human-readable name for the relying party displayed in authentication dialogs.
A unique identifier for the user account. The raw bytes will be UTF-8 encoded then Base64-url encoded.
The user account name displayed to the user during registration and authentication.
Whether the authenticator should verify the user via biometrics, PIN, or password before completing the ceremony.
How the authenticator's attestation certificate is conveyed to the relying party during registration.

Authentication Options

Configure the assertion request parameters for navigator.credentials.get().

Must be the same domain that was used during registration.

Decoded Results

The output below is decoded entirely in your browser. No data is sent to any external server.

Execute a registration or authentication ceremony to see decoded results here.

Conceptual logic flow, assumptions, and limitations

Conceptual calculation: The playground executes native WebAuthn browser APIs. For registration, it calls navigator.credentials.create() with the configured PublicKeyCredentialCreationOptions, capturing the binary responses and translating ArrayBuffers into Base64-url encoded strings and human-readable JSON structures. For authentication, it calls navigator.credentials.get() with PublicKeyCredentialRequestOptions and similarly decodes the assertion response.

Key assumptions: The relying party parameters must be valid for the current origin. Registration requires a secure context (HTTPS or localhost). The authenticator must be available and enrolled. The browser must support the WebAuthn API.

Limitations and edge cases: Some browsers or OS configurations may block WebAuthn in certain contexts. Enterprise policies can suppress authenticator availability. Virtual machines and remote sessions may have limited authenticator access. The playground cannot test attestation verification chains since that requires a live relying party server.

  • This tool decodes data locally; it does not validate signatures or verify attestation chains.
  • The decoded output is for debugging and educational purposes only.
  • NotAllowedError typically occurs when the user cancels, the origin is invalid, or the credential is not recognized.
Component 5 / Guidance Content

How to use WebAuthn & FIDO2 Debugging Playground

Configure the registration options in the left panel, then click "Trigger Registration" to invoke the WebAuthn ceremony. After a successful registration, copy the displayed Credential ID and paste it into the authentication panel to test assertion flows.

Use the credential ID output from registration to test authentication. Toggle "Use Previously Registered Credential" and paste the ID to assert against an existing credential rather than discovering a resident key.

How the logic works

The tool constructs PublicKeyCredentialCreationOptions and PublicKeyCredentialRequestOptions objects matching the WebAuthn specification. It calls the browser's navigator.credentials API, receives binary ArrayBuffer responses, and decodes them using TextDecoder for UTF-8 strings and manual parsing for CBOR-encoded attestation objects.

The output is deterministic for each ceremony; identical inputs will produce identical decoded structures.

How to interpret the results

The Client Data JSON contains the challenge, origin, and type fields that were sent to the authenticator. Verify that the origin matches your expected domain and that the challenge matches what your server generated.

The Attestation Object contains the credential public key and optional attestation data. The Authenticator Data encodes the sign count, cloned status, and user verification flags.

Accuracy and responsibility disclaimer

This playground is a debugging and educational tool. It does not perform signature verification, attestation validation, or challenge verification. Do not use the decoded output as proof of credential validity in production systems.

For production WebAuthn implementations, always validate all parameters server-side, verify attestation chains when required, and implement proper challenge storage and expiration policies.

Component 6 / Educational Content

Understanding WebAuthn registration and authentication flows

WebAuthn (Web Authentication) is a W3C and FIDO Alliance standard that enables passwordless authentication using public-key cryptography. Rather than sharing a secret with the server, users authenticate with a private key stored on their device or security key. This architectural shift eliminates phishing, reduces password reuse, and removes the server-side password database attack surface.

The registration ceremony

During registration, the relying party generates a challenge and user account details, then passes them to the browser via navigator.credentials.create(). The browser forwards these to the authenticator, which generates a new key pair. The public key, credential ID, and attestation statement are returned to the relying party for storage.

The authenticator never exports the private key. It signs challenges using the private key, and only the public key is stored server-side.

The authentication ceremony

During authentication, the relying party sends a challenge and optionally specifies a credential ID or allows any credential from the relying party's domain. The browser invokes the authenticator, which signs the challenge with the stored private key. The assertion response is verified server-side using the stored public key.

Attestation vs Assertion

Attestation and assertion are the two primary response types in WebAuthn, serving distinct purposes in the authentication workflow.

Aspect Attestation Assertion
When it occurs During credential creation (registration) During credential use (authentication)
Purpose Prove the authenticator type and attestation statement to the RP Prove possession of the private key for a specific credential
Contains Attestation certificate chain, credential public key, counter Signature over challenge, auth data, credential ID
Privacy consideration Can potentially identify the device model (use None or Indirect to avoid) Does not reveal authenticator identity

Common WebAuthn error codes and their meanings

Understanding WebAuthn errors is critical for debugging registration and authentication failures in production deployments.

Error Name Common Cause Resolution
NotAllowedError User cancelled, origin mismatch, or cross-origin request blocked Verify origin configuration, ensure HTTPS, check that RP ID is valid for the origin
InvalidStateError Credential already exists (duplicate registration attempt) Use existing credential or generate a new user ID
SecurityError Insecure context, missing TLS, or blocked by Mixed Content Deploy on HTTPS with valid certificates, except localhost
NotSupportedError Algorithm not supported, or resident key requested on unsupported authenticator Check authenticator capabilities, use ES256 algorithm
AbortError Challenge expired or request timed out Regenerate challenge server-side for each attempt

Resident keys and discoverable credentials

A resident key (also called a discoverable credential) stores the credential on the authenticator rather than relying on the server to store credential IDs. This enables authentication flows where the user does not need to enter a username; the authenticator presents a list of accounts to choose from.

Resident keys are particularly valuable for passwordless flows on shared devices and for scenarios where the user should not need to remember which account they used on a given device.

When to require resident keys

Request resident keys when building username-less authentication flows, when supporting cross-device credential synchronization (like Apple Passkeys or Google Password Manager), or when you want users to be able to register and authenticate without manual credential ID management.

Debugging WebAuthn in development

When developing WebAuthn integrations, several common patterns cause failures that are difficult to diagnose without visibility into the ceremony parameters.

Origin and RP ID mismatches

The relying party ID must be an effective domain. It can be the exact domain or a registrable domain suffix. For example, from login.example.com, you can use example.com as the RP ID but not sub.example.org. Always verify your origin and RP ID alignment during development.

Challenge management

The challenge must be generated server-side, stored temporarily, and verified after the ceremony. A challenge that is too long-lived or reused creates a replay attack vector. Generate a new cryptographically random challenge for every registration and authentication attempt.

Localhost considerations

WebAuthn works on localhost without HTTPS due to browser exceptions. However, the origin must be exactly http://localhost with the correct port. If you are testing across devices or in containers, consider using a tool like ngrok to expose a proper HTTPS endpoint.

The role of FIDO2 CTAP2

WebAuthn operates at the application layer while CTAP2 (Client to Authenticator Protocol 2) handles the transport between the browser and the authenticator. CTAP2 supports USB, NFC, and Bluetooth Low Energy transports for cross-platform security keys, and platform-specific protocols for built-in authenticators like Touch ID and Windows Hello.

Understanding CTAP2 is particularly valuable when debugging interoperability issues between browsers, operating systems, and physical authenticator devices.

Component 7 / FAQ

What is the difference between WebAuthn Attestation and Assertion?

Attestation occurs during registration and provides proof of the authenticator's identity and its attestation certificate. Assertion occurs during authentication and proves that the user possesses the private key for a previously registered credential.

How do I debug 'NotAllowedError' in WebAuthn?

NotAllowedError typically means the ceremony was rejected. Common causes include the user cancelling the dialog, an origin mismatch between your server's expectation and what the browser sent, or the relying party ID being invalid for the current domain.

Can I test FIDO2 security keys on localhost?

Yes, localhost is exempt from the HTTPS requirement for WebAuthn. However, the origin must be exactly http://localhost (or http://127.0.0.1) with the correct port. Cross-platform security keys may work on localhost, though some require an enterprise policy or registration on the key first.

What is a Resident Key in the context of FIDO2?

A Resident Key (also called a Discoverable Credential) is stored on the authenticator and can be selected by the authenticator without the relying party providing a credential ID. This enables passwordless flows where the user only needs to provide a PIN or biometric.

How do I decode the clientDataJSON from a WebAuthn response?

The clientDataJSON is a UTF-8 encoded JSON string. Decode it using TextDecoder, then parse the JSON. It contains fields like type, challenge, origin, and optionally crossOrigin. Always verify the challenge and origin match your expected values server-side.

What does the authenticator data flag byte represent?

The flag byte encodes multiple boolean signals: bit 0 is UP (User Present), bit 2 is UV (User Verified), bit 6 is AT (Attested Credential), and bit 7 is ED (Extension Data). The sign count tracks how many times the authenticator has been used.

Why should I use 'none' attestation conveyance?

Using 'none' attestation prevents the authenticator from transmitting its attestation certificate during registration. This preserves user privacy by not revealing the device model or manufacturer to the relying party, while still creating a valid credential.

Component 8 / Internal Discovery