What are passkeys?
Passkeys are phishing-resistant credentials based on WebAuthn/FIDO2. Users register a public key with a relying party; later authentications prove possession of the private key held by the authenticator (device, security key, or synced passkey provider).
Utilxo can act as a local RP sandbox or as a diagnostic client against your production FIDO server (/attestation/options|result, /assertion/options|result). When the server's rp.id differs from utilxo.com, Related Origin Requests (ROR) via /.well-known/webauthn are required.
How to use this tool
- Use Built-in Mock for local enroll/verify, or open Configure FIDO to point at a 3rd-party Base URL with bearer token and endpoint overrides.
- If your server wraps payloads in a custom envelope, open Configure FIDO → Payload and edit the request templates and response paths for each ceremony.
- Run Register Passkey / Authenticate and watch the Ceremony Terminal for options, browser responses, and result posts.
- Open the ROR tab to fetch https://{rpId}/.well-known/webauthn and confirm https://utilxo.com is allowlisted.
Frequently asked questions
Where are credentials stored?
Built-in sandbox credential metadata is kept in sessionStorage on your device. External FIDO server credentials remain on that server — Utilxo only relays ceremony payloads.
Why does WebAuthn need a server?
Challenge generation and cryptographic verification of authenticator responses require an RP/FIDO backend. Utilxo provides a built-in helper API, or you can drive your own FIDO endpoints directly from the browser.
What is Related Origin Requests (ROR)?
ROR lets credentials for a primary RP ID also work on related origins listed in /.well-known/webauthn (HTTPS, application/json, exact path, origins array). The ROR inspector validates that document for you.
My FIDO server expects a custom request shape — how do I match it?
Open Configure FIDO → Payload. Each ceremony has an Options request template and a Result request template: plain JSON describing the exact body to send. A placeholder used as an entire JSON value keeps its type, so "{{request}}" injects the whole generated request object rather than a string. For example {"rpId":"{{rpId}}","serverPublicKeyCredentialCreationOptionsRequest":"{{request}}"} produces a nested envelope with rpId as a sibling.
Which template variables can I use?
Options: {{request}}, {{username}}, {{displayName}}, {{userId}}, {{rpId}}. Results also: {{credential}}, {{result}}, {{resultUserId}}, {{optionsUserName}}, {{optionsUserId}}, {{challenge}}. Custom template variables JSON adds more {{names}}.
How do I read options out of a nested response?
Set Options response path to the location of the WebAuthn options in the response body. It accepts dot notation (data.options) or a JSON Pointer (/data/options) and is always resolved from the JSON root, so use only keys that actually appear in the response. Leave it blank when the server returns options at the top level.
Where do I put extra fields like authenticatorSelection or attestation?
Put fields that belong inside the request object — authenticatorSelection, attestation, extensions — in Extra options body params on the API & Auth tab. They merge into {{request}}. Use Custom template variables plus the template itself for values that must sit outside the wrapper, such as rpId or a tenant identifier.
Do I need templates for a standard FIDO2 server?
No. Defaults are "{{request}}" for options and "{{credential}}" for results (spec-style). Use Payload → Flat enroll/verify preset when the server wants userId/rpId merged onto the credential. Customize templates for any other envelope.
Why did I get Invalid challenge after a successful browser ceremony?
The browser signed the server challenge correctly, but the verify/enroll-complete request keyed the wrong user. Set Result userId source to match how your FIDO server stores the pending challenge (often options.user.name / email). Never rewrite a server-issued rp.id.