Download the Cheat Sheet as a
PDF or
continue reading.
Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.
1. WebAuthn Ceremonies#
Authentication with passkeys is based on the two processes, also called
ceremonies, registration(aka the attestation phase) andlogin
(aka the assertion phase).
Each phase requires a random challenge generated by the server, which is
signed by the authenticator and sent back to the WebAuthn server to verify the user.
Want to experiment with passkey flows? Try our Passkeys Debugger.
I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.
10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.
user: Contains data about the user account requesting attestation. The ID is a byte sequence chosen by the Relying Party, that must not contain personal information. The username or e-mail address is saved instead in the name or displayName attribute. Read more about this in section 4.1 Database Schema.
challenge: A randomly generated base64URL encoded BufferSource that needs to be signed by the authenticator.
pubKeyCredParams: Specified attributes of the credential to be created, usually the supported algorithm(s).
timeout: Optional time in milliseconds for the client to wait for the call to complete.
excludeCredentials: Optional list of credentials to limit the creation of multiple passkeys on one device.
attestation: Can be used to request that the attestation object is passed on to the Relying Party in a specific form. Possible values are none (default), indirect, direct and enterprise.
extensions: Optional request(s) for additional processing, such as specific return values. e.g.
credProbs requests information on whether the created credential is discoverable
prf allows the Relying Party to use outputs from a pseudo-random function (PRF) associated with a credential
Subscribe to our Passkeys Substack for the latest news, insights and strategies.
allowCredentials: Optional list of credentials that are allowed for authentication, indicating the callers preference by descending order. This list would be filled with PublicKeyCredentialDescriptors.
userVerification: Optional value to specify requirements for user verification during the operation. Possible values are preferred (default), required or discouraged.
2.3 Attestation#
During the Attestation / Registration Ceremony, the Authenticator returns
this Registration Response. You can try this yourself in the Passkeys Debugger.
Passkeys are generated with COSE algorithms, indicating the used algorithm
in the algorithm-attibute of parsedCredentialPublicKey in the attestation object.
Here's an overview of the most relevant COSE algorithms:
2.3.2 transport#
The transports -property indicates mechanisms through which an
authenticator can communicate with a client. Some common, sample value
combinations are:
No "transports"property set: default behavior which gives no indications
2.4 Assertion#
During the Assertion / Login Ceremony, the Authenticator returns this
Login Response. You can try this yourself in the Passkeys Debugger.
The assertion contains some important components like flags, signature and
userHandle.
2.4.1 flags#
Here's an overview of the most relevant flags and their combinations:
2.4.2 signature#
The signature is used to verify that the user trying to log in, actually
has the private key. The signature is created by concatenating the
authenticatorData and clientDataHash (i.e. the SHA-256 version of
ClientDataJSON) and signing the result with the private key (in the
authenticator). To verify with the public key, we concatenate
authenticatorData and clientDataHash as well. If the verification result
returns true, the authentication is successful.
2.4.3 userHandle#
The userHandle is the actual user_id. Read more about the user_id in
section 4.1 Database Schema.
2.5 authenticatorSelection#
The authenticatorSelection - object allows the server to
dictate¨settings for the authenticator and credential creation with the
following values:
2.5.1 authenticatorAttachment#
Platform: The authenticator is attached to the client's platform and is therefore not removable.
Cross-platform: The authenticator is not bound to the client's platform and can be used on multiple devices.
2.5.2 residentKey#
Required: The authenticator must create a resident key (if not possible the operation should fail).
Preferred: The authenticator should try to create a resident key (if not possible it should create a non-resident key).
Discouraged: The authenticator must create a non-resident key (if not possible the operation should fail).
Resident Keys (also called Discoverable Credential):
Resident keys are stored on the authenticator and retrieved during
authentication. ¨This way the client can discover a list of possible
keys, which is why [Conditional UI](/blog/user-transition-passkeys-> conditional-ui) requires resident keys.
Non-Resident Keys (also called Non-Discoverable Credential):
In case of non-resident keys, the credential ID is stored on the server
and not on the authenticator. During each authentication, the authenticator
derives the private key from a seed within the credential ID and an internal
master key that is saved on the authenticator.
2.5.3 userVerification#
Required: The operation should verify the user.
Preferred: The operation should verify the user, but can proceed without it (standard option)
Discouraged: The operation should not verify the user.
Warning: If set to "Preferred", the user or his device can skip
the user verification in the authentication process (read more in this
article).
Become part of our Passkeys Community for updates and support.
Conditional UI (passkey autofill) displays available passkeys in a
selection dropdown for the user, when a user has a resident key registered
with the relying party. ¨It improves the usability of passkeys, but requires
additional development efforts and is not available for all OS / browser
combinations.
Conditional UI is not available on all combinations of operating systems and
browsers (yet). Here's an overview of the current browser coverage (March
2024):
A full, minimalistic code for a Conditional UI method looks like this:
3.3.2 Browser Compatibility Check#
Conditional UI only works with resident keys / discoverable credentials
Its recommended to provide a different server endpoint to start the
Conditional UI login.
The client needs to meet multiple requirements:
JavaScript must be enabled and the web page must provide an HTML input field.
Timeout parameters should be disregarded
To avoid errors, the server should first test the clients availability with
this function:
3.3.3 Autocomplete Token in Input Fields#
The input field should receive an HTML autofill token, that signals the client
to populate passkeys to the ongoing request. Besides passkeys, the autofill
tokens can be paired with existing tokens, e.g. usernames and passwords:
autocomplete="username webauthn": Besides displaying passkeys, this also suggests username autofill.
autocomplete="current-password webauthn": Besides displaying passkeys, this further prompts for password autofill.
4. WebAuthn Server#
4.1 Database Schema#
There is no mandatory or standardized database schema for WebAuthn servers.
¨However, this example database schema can be used to store the required
information and provide all functionalities of a WebAuthn server:
Bold attributes are mandatory for a minimal viable implementation, while the others are only needed for optional, but helpful features.
4.1.1 Authentication-relevant data#
Credential ID: This is a unique ID thats generated by the authenticator during registration of a passkey. It should be used to look up the actual user account thats associated with the passkey. ¨Additionally the userHandle (from user_id) should then be compared to validate the account used for authentication. Dont use the user.name attribute for comparison as it can change over time.
User ID (user_id): Unique ID specified by the Relying Party to represent a user account in their system. Its returned as the userHandle within the assertion-object.
4.1.2 Metadata for display and selection of passkeys:#
User DisplayName (user.displayName): User-friendly, readable name that is typically the full name of the user. ¨Its shown to the user, but not used during authentication.
User Name (user.name): Unique and readable name that is typically an e-mail address or a username. It can be shown to the user, but it's not used during authentication.
4.2 Relying Party ID (rpId)#
The Relying Party ID (rpID) is a domain stored within the passkey, ensuring
the passkey only works for the correct domain (browser URL, see this article
for native apps). During authentication, the rpID is checked against the
browser URL and only allowed in these two cases:
The URL matches precisely the rpId OR
The URL is a subdomain that matches the rpId and the parent domain is not on the Public Suffix List
Here are examples for (dis-)allowed combinations:
5. Helpful Websites and Tools#
Here's a list of useful tools & websites for implementing passkeys.
Passkeys Debugger: Tool for debugging the WebAuthn Responses as JSON and testing WebAuthn operations with different options.
Chrome Device Log: Tool for showing a log of your device's WebAuthn operations (only avaible on Chrome via chrome://device-log)
If you want to implement passkeys with just a few lines of code into any
application, you can also use Corbado Complete (for new apps)
or Corbado Connect (for
existing apps)
Share this article
Table of Contents
Enjoyed this read?
🤝 Join our Passkeys Community
Share passkeys implementation tips and get support to free the world from passwords.