Inspect WebAuthn Credential Data

Paste a serialized registration or authentication response to inspect its client and authenticator data. Decoding shows the fields but does not verify signatures, attestation or a server challenge.

Runs locally in your browser
Credential data is parsed only in this browser. This page does not create a credential, call navigator.credentials, or validate a signature against a server challenge.
WebAuthn credential JSONSerialized PublicKeyCredential response
Decoded client and authenticator data

Inspect ceremony evidence, verify it server-side

A production relying party must verify challenge, origin, RP ID hash, user presence or verification policy, signature, algorithms, attestation policy, and sign-counter behavior.

How to decode a WebAuthn credential and check its flags

This page reads a serialized PublicKeyCredential — the JSON a relying party receives from navigator.credentials.create() or navigator.credentials.get() — and turns both of its halves into readable fields — usually the quickest way to see what a failing registration or assertion actually contained. clientDataJSON is decoded from Base64URL and parsed, and the authenticator data is split into the RP ID hash, the flags byte, the sign counter and, for a registration, the AAGUID, the credential ID and the COSE public key.

Everything runs in the browser. The page never calls navigator.credentials, never contacts a relying party and never sends the credential anywhere. Decoding is not verifying: the signature, the attestation statement and the challenge comparison all belong on your server.

  1. Paste the credential JSON into the first panel. Either the complete object with id, rawId, type and response, or the response object on its own is accepted.
  2. Press Inspect credential. The summary fills with the ceremony type, origin, challenge, cross-origin flag, credential ID, RP ID hash, sign count, AAGUID and COSE key fields, and the chips light up for UP, UV, BE, BS, AT and ED.
  3. Press Authentication example or Registration example when you want a known-good credential to compare against. The authentication example carries a bare 37-byte authenticatorData; the registration example is an attestationObject whose CBOR map holds the authenticator data, a zero AAGUID and a P-256 key.
  4. Read the findings list alongside the values. It restates what the decoded bytes do not prove — that a challenge was compared with a server session, that an origin matched an allowlist, that a signature was checked.
  5. Use Copy report to take the JSON report, then Clear to empty the panel and reset the summary before the next credential.

What the decoded fields mean

Flags, counters and identifiers

The flags byte is the part of the authenticator data that describes the ceremony rather than the credential. UP reports that a user was present, UV that the user was verified with a PIN or biometric, BE that the credential may be copied to another authenticator and BS that it currently is — a synced passkey sets both. AT marks the attested credential data (AAGUID, credential ID and public key) that only exists in a registration, and ED marks extension data.

The sign counter is a 32-bit unsigned integer the authenticator increments on each assertion. Comparing it with the value stored for that credential is the classic clone check, but a counter that never moves proves nothing on its own: many platform authenticators return zero permanently. The RP ID hash is the SHA-256 of the relying party ID the credential was created for, and comparing it with the expected value is what shows that a credential captured on one site is not being replayed at another.

Where each field comes from

clientDataJSON is Base64URL-encoded JSON that the browser assembles from the challenge, the origin and the ceremony type, webauthn.create or webauthn.get. The page decodes it, parses it and reports crossOrigin when the browser marked the flow as embedded in another page. The bytes that follow are a compact binary structure: 32 bytes of RP ID hash, one flags byte, four bytes of counter, and then the attested credential data only if the AT flag is set.

A registration response carries an attestationObject, a CBOR map that holds the same authenticator data under authData; the page walks the CBOR map to reach it. The attestation format and statement that sit beside it are not shown and are not checked here. Fields the browser adds around the response, such as transports and clientExtensionResults, are not part of the report either.

What still has to happen on the server

A decoded credential is evidence, not proof. The relying party still has to compare the challenge with the one it issued for that session, check the origin against its own, compare the RP ID hash with the expected RP ID, and verify the signature over the authenticator data and the SHA-256 of clientDataJSON with the public key it stored at registration.

It also has to apply its own user-verification and attestation policy, restrict the algorithms it accepts, and decide what the sign counter and the backup flags mean for its threat model. This page names the COSE values it recognises — ES256, EdDSA, ES384, ES512, PS256, PS384, PS512, RS256, RS384, RS512, with the P-256, P-384, P-521, Ed25519 and Ed448 curves — and prints any other value as its raw number, which is a label rather than a policy decision.

Recent tools: