Passkeys
Passkeys, a cutting-edge authentication method, offer faster, easier, and more secure sign-ins across devices and applications. Unlike traditional passwords, passkeys use public-key cryptography to eliminate shared secrets, making them inherently resistant to phishing and credential theft. Their ease of use makes them a simple and effective solution for your authentication needs.
By adopting passkeys, businesses can enhance security, improve user experience, reduce password fatigue, and minimize IT support overhead for password recovery.
This document provides an in-depth look at passkeys, including their key features, use cases, configuration, and API implementation.
Key Features
Passkeys introduce a secure and seamless authentication process with several advantages. They offer a flexible approach to authentication, allowing users to choose from various options that best suit their needs.
- Enhanced Security – Eliminates weak passwords and reduces vulnerabilities by using public-key cryptography.
- Phishing Resistance – Authentication is tied to specific services, preventing credential theft.
- Improved User Experience – Enables effortless login through biometrics or device authentication, eliminating the need for memorized passwords.
- Cross-Device Compatibility – Supports authentication across multiple devices and platforms.
Business Use Cases
Passkeys enhance authentication security and user experience across both B2B and B2C environments by eliminating passwords, reducing credential theft risks, and improving login convenience.
- Seamless Workforce Authentication: Enterprises can enhance employee security while reducing password reset requests and IT support costs.
- Customer Account Protection: B2C platforms can leverage passkeys to safeguard users from phishing attacks and credential leaks.
- Frictionless User Onboarding: New users can register instantly without passwords, improving conversion rates and reducing account recovery issues.
- Regulatory Compliance: Organizations in finance, healthcare, and other regulated industries can use passkeys to meet security standards like GDPR and SOC 2.
- Cross-Device Authentication: Users can seamlessly access their accounts across different devices without password resets or multi-factor authentication (MFA) prompts.
Authenticator Options for Passkeys
Passkeys rely on authenticators to store and manage cryptographic key pairs. LoginRadius supports the following types of authenticators:
- Platform Authenticators:
- Built into device operating systems or hardware.
- Use biometric verification (e.g., fingerprints, facial recognition) or secure device methods (e.g., PINs or Windows Hello).
- Roaming Authenticators (Cross-Platform):
- Portable external security keys (e.g., USB-based authenticators)
- Allow users to authenticate securely across multiple devices.
Configuration
The Configuration section guides you through setting up Passkeys in the Admin Console and explains their usage via APIs.
If you encounter a 'Feature not available' message, it means that the particular feature is not enabled in your account. Please contact the LoginRadius support team for assistance in enabling this feature.
Admin Console Configuration
-
Navigate to Authentication > Passkeys section of the LoginRadius admin console.
-
Enable the Passkey Authentication toggle.
-
Configure the following settings as per the business requirements:
-
Passkey Selection: Choose between Autofill, Button, or Both.
- Autofill allows users to select the passkey from the autofill form.
- The button displays a "Sign In with Passkey" button on the login page.
- Both enable the Autofill and Button options.
-
Progressive Enrollment: This feature allows you to prompt users to establish a passkey during email/password login if needed. Users can skip this step, and it will reappear after a specified delay, which you can set in the 'Progressive Enrollment Delay' option.
- Progressive Enrollment Delay (Days): Specify the number of days after which the progressive enrollment option will reappear for users who skip it.
-
Local Enrollment: Enable this to require users to generate a local passkey when logging in on a new device using a cross-device passkey. Users can skip this step if needed.
-
Relying Party Display Name: This is the brand name of the site or service the user is trying to access. Enter the brand name of the relying party(site) here.
-
Relying Party ID: Enter the base domain name without schema or ports.
-
Relying Party Origins: Enter the exact domain name with schema and port, if applicable. Example: https://.hub.loginradius.com
-
-
Click the Update button to apply the configurations.
API Implementation
LoginRadius provides multiple APIs that are associated with Passkeys. These API’s include all the functionalities required for passkeys like:
Common Setup: Encoding Helpers
WebAuthn APIs return and expect binary data in ArrayBuffer
format, but APIs require base64url-encoded strings.
Define these helper functions once and use them for both registration and login:
function base64UrlEncode(buffer) {
return btoa(String.fromCharCode(...new Uint8Array(buffer)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
function base64UrlDecode(base64url) {
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/")
.padEnd(base64url.length + (4 - base64url.length % 4) % 4, "=");
return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
}
Passkeys Registration:
- Initiate Passkey Registration
- Trigger WebAuthn Passkey UI
- Complete Registration (Finish API)
Start the registration flow by calling the Register Begin By Passkey API. It returns a publicKey object used by the browser to initiate WebAuthn.
API Endpoint: Registration Begin By Passkey API
Sample Response:
{
"RegisterBeginCredential": {
"publicKey": {
"rp": {
"name": "LoginRadius App",
"id": "localhost"
},
"user": {
"name": "f04d624989314945a950c6a8f71959d0",
"displayName": "f04d624989314945a950c6a8f71959d0",
"id": "ZjA0ZDYyNDk4OTMxNDk0NWE5NTBjNmE4ZjcxOTU5ZDA"
},
"challenge": "1x9aUZmA5hCXdvt8szxILDmnWUWWkXgkAE61tC_7yJc",
"pubKeyCredParams": [...],
"timeout": 60000,
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": "preferred"
}
}
}
}
Use the browser-native navigator.credentials.create()
to show the biometric/passkey prompt.
Important: Decode these fields before calling the API:
publicKey.challenge
publicKey.user.id
Note: The LoginRadius API returns these values, but decoding and invoking navigator.credentials.create()
are performed fully on the client side—LoginRadius does not control WebAuthn behavior, which is handled by the browser.
const publicKey = response.RegisterBeginCredential.publicKey;
// Decode base64url fields into Uint8Array
publicKey.challenge = base64UrlDecode(publicKey.challenge);
publicKey.user.id = base64UrlDecode(publicKey.user.id);
// Trigger the passkey registration UI
const credential = await navigator.credentials.create({ publicKey });
WebAuthn Output Format
The credential object returned by the browser looks like this:
{
"id": "string",
"rawId": "string",
"type": "public-key",
"response": {
"attestationObject": "string",
"clientDataJSON": "string"
}
}
📌 After a successful operation, the browser returns a credential object.
After receiving the credential object from the browser via navigator.credentials.create(), you must encode certain fields back to base64url format before sending them to the Registration Finish By Passkey API
Here’s how you can prepare the request payload:
{
"Email": [
{ "Type": "Primary", "Value": "usertest@yopmail.com" }
],
"PasskeyCredential": {
"id": "<credential.id>",
"rawId": "<base64url(rawId)>",
"type": "public-key",
"response": {
"attestationObject": "<base64url(attestationObject)>",
"clientDataJSON": "<base64url(clientDataJSON)>"
}
}
}
JS Example of payload creation
const payload = {
Email: [
{
Type: "Primary",
Value: "usertest@yopmail.com"
}
],
PasskeyCredential: {
id: credential.id,
rawId: base64UrlEncode(credential.rawId),
type: credential.type,
response: {
attestationObject: base64UrlEncode(credential.response.attestationObject),
clientDataJSON: base64UrlEncode(credential.response.clientDataJSON)
}
}
};
Why is this step important?
The WebAuthn API returns binary data in ArrayBuffer format, but the LoginRadius API expects these values to be base64url-encoded strings. Failing to encode them correctly will result in errors when calling the finish endpoint.
Passkey Login:
The Passkey Login flow enables users to authenticate securely using a previously registered passkey. It follows the WebAuthn standard and leverages the browser’s native capabilities (e.g., biometrics, PIN, security keys). LoginRadius offers APIs that work in conjunction with WebAuthn to facilitate a seamless login process.
- Initiate Login (Begin API)
- Trigger WebAuthn Login (Browser)
- Complete Login (Finish API)
Initiate Call the Login Begin By Passkey API to get a WebAuthn-compatible publicKey object. This object contains a challenge and allowed credentials for the user.
Request Parameter
- apikey: Your LoginRadius API key
- identifier: User's identifier (usually email)
Sample Response:
{
"LoginBeginCredential": {
"publicKey": {
"challenge": "<base64url-challenge>",
"timeout": 60000,
"rpId": "localhost",
"allowCredentials": [
{ "type": "public-key", "id": "<base64url-id>" }
],
"userVerification": "preferred"
}
}
}
Call navigator.credentials.get() after decoding challenge and allowCredentials[].id:
const publicKey = response.LoginBeginCredential.publicKey;
publicKey.challenge = base64UrlDecode(publicKey.challenge);
publicKey.allowCredentials = publicKey.allowCredentials.map(cred => ({
...cred,
id: base64UrlDecode(cred.id)
}));
const credential = await navigator.credentials.get({ publicKey });
WebAuthn Login Output Format
The browser returns a credential object containing binary response fields like authenticatorData, clientDataJSON, and signature.
{
"id": "string",
"rawId": "string",
"type": "public-key",
"response": {
"authenticatorData": "string",
"clientDataJSON": "string",
"signature": "string",
"userHandle": "string"
}
}
Use the credential obtained from navigator.credentials.get() and pass it to the Login Finish By Passkey API to finalize authentication and receive a session token.
Include the credential response inside the request body under the PasskeyCredential field:
{
"email": "usertest@yopmail.com",
"PasskeyCredential": {
"id": "<credential.id>",
"rawId": "<base64url(rawId)>",
"type": "public-key",
"response": {
"authenticatorData": "<base64url(authenticatorData)>",
"clientDataJSON": "<base64url(clientDataJSON)>",
"signature": "<base64url(signature)>",
"userHandle": "<base64url(userHandle)>"
}
}
}
JS Example of payload creation
const payload = {
email:"usghjsgsjh@yopmail.com",
PasskeyCredential: {
id: credential.id,
rawId: base64UrlEncode(credential.rawId),
type: credential.type,
response: {
authenticatorData: base64UrlEncode(credential.response.authenticatorData),
clientDataJSON: base64UrlEncode(credential.response.clientDataJSON),
signature: base64UrlEncode(credential.response.signature),
userHandle: base64UrlEncode(credential.response.userHandle)
}
}
}
Additional APIs are available to help you meet your use cases. The documentation provides an overview and guidance on how to use them.