Security Key Test Guide

A reference for the DeskTest.net Security Key Test. Covers how it verifies a FIDO2 / WebAuthn key using a throwaway credential, how to read the verdict, and what to do when a key will not complete the ceremony.

Open the Security Key Test →

What does the Security Key Test check?

The tool drives the browser's WebAuthn API (navigator.credentials.create) to confirm that a FIDO2 authenticator - a roaming USB / NFC key such as a YubiKey, or a built-in platform authenticator such as Windows Hello, Touch ID, or an Android fingerprint sensor - can actually complete a credential ceremony in this browser. It runs in two steps:

  1. Support detection. Confirms window.PublicKeyCredential and navigator.credentials.create exist, that the page is a secure context (HTTPS), and asks PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() whether a built-in platform authenticator is present. No credential is created in this step.
  2. WebAuthn ceremony. When you press Test my key, the tool calls navigator.credentials.create() with a throwaway credential: a random challenge and random user.id from crypto.getRandomValues, a relying party of just { name: 'DeskTest.net' } (no rp.id, so the browser uses the current origin), key parameters for ES256 (-7) and RS256 (-257), userVerification: 'preferred', and a 60-second timeout. Your browser then asks you to touch the key or approve with the platform authenticator. On success the returned credential is discarded immediately.
This is a capability test, not a registration. Nothing is registered with DeskTest.net or any other site, nothing is saved to your key's storage in a way this tool keeps, and nothing is transmitted. It answers one question: "will this key work here?"

When should I run this?

Reading the results

Step 1 lists the detected WebAuthn capabilities: whether PublicKeyCredential and credentials.create() exist, whether the page is a secure context, and whether a built-in platform authenticator is available. A missing platform authenticator is not a failure - a roaming USB / NFC key can still be used.

Step 2 shows the ceremony outcome. On success it reports the attachment - platform for a built-in authenticator or cross-platform for a removable key - the credential type, and any transports the browser reported (usb, nfc, ble, internal, hybrid).

Each step row carries a status badge: Pending, Running, Pass, or Fail. On a fail the row expands with the diagnosis and a fix checklist. The verdict panel at the top names the most likely cause and a recommended next step. Copy Diagnostic Report copies a plain-text summary - browser, support flags, the ceremony outcome, and the diagnosis tag - to paste into a ticket. No part of the report contains the credential itself.

Common failures and fixes

The tool produces a named diagnosis for every failure path, matching the error the WebAuthn API returned.

webauthn-unsupported: WebAuthn is not available

No PublicKeyCredential object exists. The browser is too old, sandboxed, or running with WebAuthn disabled by policy. Update to a current Chrome, Edge, Firefox, or Safari, or check the browser's policy settings.

insecure-context: not a secure context

WebAuthn only runs over HTTPS (or localhost). If the page reports window.isSecureContext === false the browser refuses the ceremony. On DeskTest.net the page is HTTPS; you would only see this on a local copy served over plain HTTP or from a file:// path.

not-allowed: no key used, cancelled, or timed out

This is the most common result and maps to NotAllowedError. The ceremony ended without a credential: the prompt was dismissed, no key was touched within 60 seconds, or no authenticator was available to answer.

  1. Insert the USB key (or hold the NFC key to the reader) before pressing the button, then touch it when it blinks.
  2. If you meant to use Windows Hello or Touch ID, make sure it is enrolled and approve the system prompt.
  3. Keep this tab in the foreground; some browsers cancel the request if the tab loses focus while the prompt is open.
  4. Run the test again and complete the gesture within the time limit.

security-error: blocked for a security reason

A SecurityError means the page is not a valid secure context for WebAuthn, or the relying-party domain did not match the origin. Open the tool over HTTPS at its real domain, and do not run it inside a sandboxed iframe or an unusual embedded browser.

not-supported: key cannot do the requested type

A NotSupportedError means the authenticator could not satisfy either requested algorithm (ES256 or RS256). This is rare for modern FIDO2 keys. Update the key's firmware with its vendor manager, or try a different current key.

constraint: a requested condition could not be met

A ConstraintError means the key could not satisfy user verification, most often because no PIN or biometric is set on it. Set a PIN with the key's vendor manager and retest, or use a platform authenticator that is already enrolled.

invalid-state: authenticator in a conflicting state

An InvalidStateError in a normal registration means an eligible credential already exists; for this throwaway test it usually points at a key that is busy or in an unexpected mode. Remove and re-insert the key, close any companion key-manager app, and run the test again.

For IT admins

WebAuthn ceremonies are entirely local: the browser talks to the authenticator over USB, NFC, Bluetooth, or an internal platform API. There is no network hop for the test to fail on, so a failing result points at the key, the browser, the OS, or policy - never a firewall.

Roaming vs platform. A cross-platform attachment is a removable key (YubiKey and similar); platform is the machine's built-in authenticator (Windows Hello, Touch ID). If step 1 reports no platform authenticator, that only means the device has none enrolled; a USB key still works.

Policy blocks. Managed Chrome and Edge can restrict WebAuthn and attestation behavior through enterprise policy. On Windows, a security key needs the appropriate WebAuthn / FIDO support and a set PIN. If one machine fails while a peer passes, suspect local policy, a driver, or the USB port, not the browser build alone.

Enrollment is separate. This test proves the key can complete a ceremony; it does not enroll the key with your identity provider. After a pass, register the key in the real system (Entra ID, Okta, Google, and so on) through that provider's own flow.

Transports. The reported transports hint at how the key connected (usb, nfc, ble, internal, hybrid). A key that only reports hybrid may be a phone acting as a passkey over the cross-device flow rather than the physical key you expected.

Privacy: the throwaway credential

The ceremony uses a random 32-byte challenge and a random 16-byte user.id, both generated in your browser with crypto.getRandomValues. The relying party is only a display name; there is no rp.id, so the browser scopes the credential to the current origin automatically. When the authenticator returns a credential, the tool reads only non-identifying facts (attachment type, transports) and then drops the credential object. It is never stored in the page, never written to disk by this tool, and never sent anywhere - there is no network request in the whole flow.

For discoverable-key models, the authenticator itself may briefly hold a resident credential scoped to desktest.net; because nothing here ever authenticates against it, it is inert and can be cleared from the key's credential manager if you wish. Because the tool requests attestation: 'none', no attestation certificate or hardware identifier is requested or seen.

Behind the scenes

How the security key test runs The browser tab generates a random challenge and user id, calls credentials.create, and the browser talks directly to the security key or platform authenticator over USB, NFC, or an internal API. There is no server and no network request. The returned credential is discarded. YOUR BROWSER (this tab) credentials.create() random challenge + user id generated locally Security key USB / NFC key, or built-in Windows Hello / Touch ID challenge touch = signed All local. No server. Credential discarded on return. No network CSP lists no connect-src. Nothing registered or sent.
The whole ceremony is a local exchange between the tab and the authenticator. No server is involved, and the credential is thrown away the instant it returns.

WebAuthn is designed so the credential ceremony never needs the relying party's server to be reachable at ceremony time - the browser mediates directly with the authenticator. That is why this tool can fully exercise a key with a Content-Security-Policy that lists no connect-src at all: there is nothing to connect to. Open DevTools, Network tab, during a run and you will see zero requests.

Because there is no rp.id in the options, the browser derives it from the page origin, so the throwaway credential is scoped to desktest.net and could never be used to sign in elsewhere even if it were kept. The two requested algorithms, ES256 and RS256, cover essentially every FIDO2 authenticator in circulation; ES256 alone satisfies the vast majority.

The gesture requirement is deliberate. credentials.create() is called from within the click on Test my key so the browser has a fresh user activation, which is what lets it show the authenticator prompt. That is also why the test cannot run itself automatically - a real person has to press the button and touch the key.

Elsewhere on the web: