Attestation
Every registration includes an attestation statement — a claim, from the authenticator itself, about what kind of device it is and (optionally) a signature over that claim from a certificate the manufacturer controls. It answers a narrower question than people expect: not "is this person who they say they are," but "was this key pair really generated inside a genuine YubiKey / genuine platform authenticator / etc., and not software pretending to be one."
attestationType controls what the server asks for:
-
"none"— don't send attestation at all. This is what almost every consumer relying party uses (including every other demo on this site). You're trusting the platform's passkey implementation generally, not verifying a specific hardware model. -
"direct"— send the authenticator's real attestation statement, signed by a certificate chain traceable to the manufacturer. Enterprises verifying specific hardware (FIDO-certified security keys, for compliance) use this; it also means the server learns which authenticator model you used, which is exactly the privacy trade-off most consumer sites want to avoid.
Many authenticators (and browsers) anonymize or refuse "direct"
attestation by default to protect user privacy — don't be surprised if the
Inspector below shows fmt: "none" even when this page asked for
"direct". That refusal is itself the correct, expected behavior.
What the server does with it
The attestation statement is a CBOR map whose exact fields depend on its
format (fmt) — a signature and certificate chain for most formats,
something else entirely for others. The Inspector below shows the real decoded
structure, not a canned summary: the certificate chain (if any) is parsed for
its actual subject, issuer, and validity dates.
const result = await verifyRegistrationResponse({
response,
expectedChallenge: challenge.challenge,
expectedOrigin: rp.expectedOrigin,
expectedRPID: rp.expectedRPID,
});
//