Core Concepts
This page clarifies terminology and models that appear repeatedly in WebAuthn. It is recommended to read the Overview first, then this page, and finally review the Flows and Reference.
Public Key Credential Model
The core of WebAuthn is asymmetric key pairs. Whenever a user registers an account on a Relying Party (RP), the authenticator generates a brand new pair of keys:
- Private key: Stored within the secure hardware of the Authenticator, never leaves the authenticator, and neither the RP nor the browser can access it.
- Public key: Returned to the RP and stored bound to the user's account.
Key properties:
- One RP, one account, one key pair: Keys are isolated by
(rpId, user account), making credentials from different sites unrelated and unable to be used for cross-site tracking. - Login via signature: During authentication, the authenticator signs the challenge issued by the RP using the private key; the RP verifies the signature using the stored public key. The server never stores any secret usable for login.
Tips
This is why WebAuthn is resistant to server compromise: the database only contains the public key; if breached, attackers can neither forge signatures nor derive the private key.
Credential ID and credentialPublicKey
After successful registration, the RP needs to store two things:
- Credential ID: A unique handle assigned by the authenticator to this key pair (a byte string, commonly stored as Base64URL-encoded). During authentication, the RP returns it via
allowCredentialsso the authenticator can locate the corresponding private key. - credentialPublicKey: The user's public key, encoded in COSE (CBOR Object Signing and Encryption) Key format (RFC 8152). It is a CBOR map containing key type (
kty), algorithm (alg, such as -7 for ES256), and curve/coordinate or modulus parameters.
The RP server typically parses the public key and persists it in a form convenient for signature verification, such as PEM or raw COSE.
attestation and assertion
These are two easily confused words with completely different meanings:
- attestation (Attestation): Occurs during the registration ceremony. The authenticator, when returning the new public key, can attach a verifiable claim stating "what model/vendor this authenticator is" (
attestationObject), allowing the RP to verify the authenticator's origin and trustworthiness. - assertion (Assertion): Occurs during the authentication ceremony. The authenticator's signature result for the challenge, used to prove to the RP that the user currently possesses the corresponding private key.
Attestation format is identified by the fmt field; common types:
| fmt | Meaning |
|---|---|
none | No attestation provided; authenticator origin is unverifiable. Recommended for most consumer scenarios, best privacy. |
packed | FIDO2 universal format, may contain authenticator signature and X.509 certificate chain. |
fido-u2f | Format compatible with legacy U2F security keys. |
tpm | Attestation based on TPM. |
apple | Anonymous attestation for Apple platform authenticators. |
android-key / android-safetynet | Android platform-related attestation. |
Warning
Only in enterprise/high-assurance scenarios (needing to restrict to "only accept certain vendor authenticators") is it necessary to truly parse and verify attestation certificate chains. Most applications should request attestation: "none", avoiding unnecessary privacy exposure and implementation complexity.
ceremony: registration and authentication
The WebAuthn specification uses ceremony (ceremony) to refer to a complete interaction process involving users, browsers, authenticators, and the RP. There are two types:
- Registration ceremony: Creates a new credential by calling
navigator.credentials.create(), producing attestation. - Authentication ceremony: Uses an existing credential to log in by calling
navigator.credentials.get(), producing assertion.
The server-side logic of both is symmetrical: both must first issue options with a challenge, then verify the authenticator's response. Details in Flows.
challenge and Replay Prevention
challenge (Challenge) is a cryptographic random number (recommended ≥ 16 bytes) generated by the RP at the start of each ceremony, issued to the browser, and ultimately written into clientDataJSON and included in the authenticator's signing scope.
Replay prevention key points:
- challenge must be generated by the server, bound to the current session, and one-time, invalidated immediately after verification.
- The RP must verify that the returned challenge byte-for-byte matches the one it issued.
- Do not use predictable values (timestamps, auto-incrementing IDs) as the challenge.
rpId and Origin Binding
The cryptographic foundation for phishing resistance rests on two levels of binding:
- rpId: The identifier for the RP, must be the registrable domain of the current page origin or a subdomain. For example, when the origin is
https://login.example.com,rpIdcan belogin.example.comorexample.com, but notexample.org. The authenticator computes SHA-256 ofrpIdto getrpIdHash, writes it toauthenticatorData, and binds it with the credential. - origin: The browser writes the complete origin of the current page (such as
https://login.example.com) intoclientDataJSON.origin; this value is filled in by the browser and cannot be forged by page JavaScript.
Phishing resistance principle: A phishing site example.evil.com cannot set rpId to example.com (fails domain matching). Even if it tricks the user, the authenticator will not return a signature usable for example.com. Meanwhile, when the RP verifies the signature, it will discover that clientDataJSON.origin is not the expected legitimate origin and reject it.
Caution
Once rpId is set for a credential, it cannot be changed. If cross-subdomain use is needed later, use the registrable domain (such as example.com) rather than a specific hostname during registration, otherwise existing credentials will be unable to be used on other subdomains.
user verification (UV) and user presence (UP)
The authenticator reports two critical flags in authenticatorData.flags:
- UP (User Presence): Proves "someone physically operated the authenticator" (such as touching a security key). Nearly all ceremonies require UP=1.
- UV (User Verification): Proves "the operator is the account owner," achieved through local verification using PIN, fingerprint, facial recognition, etc. UV=1 means this is multi-factor (possessing the authenticator + biometric/PIN).
The RP expresses expectations through the userVerification parameter: required (must have UV), preferred (attempt UV), discouraged (no UV needed, only UP). The RP must verify the flags according to business requirements during signature verification, not trust the request parameters.
resident key / discoverable credential
- Non-resident credential: The private key is not stored in an enumerable location within the authenticator; during authentication, the RP must provide the Credential ID via
allowCredentialsto use it. Suitable for "enter username first, then authenticate" second-factor scenarios. - Resident key / discoverable credential: The credential and user handle are stored within the authenticator and can be enumerated by the browser. Supports username-less login, the technical foundation of Passkey. Requested via
authenticatorSelection.residentKey(required/preferred/discouraged).
signature counter Anti-cloning
authenticatorData contains a signature counter signCount that monotonically increments each time the authenticator signs. The RP should store the previously observed count:
- If the new value > previous value: Normal, update storage.
- If the new value ≤ previous value (and not always 0): Possible credential cloning, should alert or reject.
Warning
Some platform authenticators (especially synced Passkeys) always return signCount = 0. In such cases, the counter is meaningless; the RP should not reject login based on this alone, only handle true regression scenarios like "decreasing from non-zero to a smaller non-zero value."
attestation Privacy Considerations
If attestation certificates are unique across a batch of authenticators, they become identifiers correlatable across sites, damaging user privacy. To address this:
- FIDO specs require attestation certificates to cover at least 100k devices (batch attestation) to avoid single-device identification.
- Platform authenticators commonly use anonymized attestation (such as Apple's anonymous CA, Android's anonymization CA).
- Unless there is a specific enterprise compliance need, the RP should request
attestation: "none", preventing the browser from transmitting or stripping identifiable information.
Next step: Enter Registration and Authentication Flows to see complete ceremonies and code examples.