FIDO2 (Authentication)
This is a technical guide on how to implement the FIDO2 authentication by simply following the steps below.
What is FIDO2?
FIDO2 enables users to leverage common devices to easily authenticate to online services in both mobile and desktop environments.
It is one of multiple different authentication methods.

When is a user able to use FIDO2 authentication?
| Criteria | Example | Configuration |
|---|---|---|
| User Verification Setup | The user has to log in to the portal and can enroll the FIDO2 using either the cidaas App or any other custom Authenticator App | |
| Allowed Verification Methods | An app setting to configure FIDO2 authentication as a login method. | ![]() |
Understanding the Flow and APIs
| API | Description | Link |
|---|---|---|
| Get the configured authentication methods | Displays the configured authentication methods of a user | Link to API |
| Initiate the authentication | This API is used to initiate the configured authentications, e.g., when a user clicks on the Backup code authentication, it initiates the Backup code authentication. | Link to API |
| Perform the authentication | After successfully authenticating by entering the Backup code, the enrollment completion will finally enroll the user. | Link to API |
| Finish up the authentication and continue login | Continue the login process once the authentication is successful. | Link to API |
Step 1: Allow FIDO2 in the App settings
In the Admin portal, you need to make the FIDO2 verification type an allowed authentication method under App advanced settings.
To do that,
You can change your existing application, by navigating to Apps -> App Settings -> Edit -> Advanced Settings -> Authentication -> MFA -> Authentication -> FIDO2.

Step 2: Rendering the user verification methods
Before initiating the FIDO2 authentication, perform an Authorization (Authz) Call and generate the requestId, then use it in the upcoming API calls.
The first call will be to get the configured verification methods for a user. Based on the response, you provide a selection of verification methods for your user. Below is a demo of how this can look by presenting different verification icons.
Call the configured verification methods of a user. This will filter the user configured verification methods and the app level configuration.

| API | Description | Link |
|---|---|---|
| Get the configured authentication methods | Displays the configured authentication methods of a user | Link to API |
This API requires you to provide the user identifier(could be an email, mobile number or any other identifiers) and the
requestId. It returns thetypeasFIDO2if the user has configured.
Request
curl --location '{{base_url}}/verification-srv/public/graph/user/setup' \
--header 'content-type: application/json' \
--data-raw '{
"request_id": "df08cabb-4b8c-4181-9f6f-f6948802ebf7",
"identifier": "[email protected]"
}'
This will return the list of all verification methods available for the user to authenticate.
Response
{
"success": true,
"status": 200,
"data": {
"configured_list": [
{
"type": "FIDO2"
}
]
}
}
Step 3: Initiating FIDO2 authentication
When the user selects FIDO2 in the list of authentication methods, the initiate API needs to be called. To support cross-domain authentication, you can pass domainURL and allowedDomains in the request body.
Cross-Domain Authentication Support:
domainURL: (Optional) The domain URL to be used as the Relying Party ID (RP ID) for FIDO2 cross-domain authentication. This allows you to host enrollment and authentication pages on different domains. ThedomainURLwill be used as the RP ID during both credential creation (registration) and assertion (authentication) phases.
Note: If
domainURLis provided
| API | Description | Link |
|---|---|---|
| Initiate the authentication | Initiates the login authentication process via FIDO2 verification method | Link to API |
This API initiates the
FIDO2authentication. It returns anexchange_id,status_id, maskedsubandfido2_entityhaving a server challenge which is useful for the Step 4
Request
curl --location '{{base_url}}/verification-srv/authentication/fido2/initiation' \
--header 'content-type: application/json' \
--data-raw '{
"usage_type": "PASSWORDLESS_AUTHENTICATION",
"request_id": "df08cabb-4b8c-4181-9f6f-f6948802ebf7",
"medium_id": "cd7e9166-99d1-4d36-bc8f-3c8ffb2ad011",
"identifier": "[email protected]",
"domainURL": "https://anotherdomain.com"
}'
This will return a status_id, exchange_id, fido2_entity and masked sub which are unique for this process and the following steps will rely on this being provided.
Response
{
"success": true,
"status": 200,
"data": {
"exchange_id": {
"exchange_id": "455fd20d-837d-43a6-a212-a02eeea1a46b",
"expires_at": "2024-01-10T20:45:51.781Z"
},
"medium_text": "[email protected]",
"sub": "6837c08e-d748-4091-8d8e-a3e24f30e0f8",
"status_id": "710792ba-32f9-4d2d-8584-fefa3a6d94b8",
"fido2_entity": {
"type": "LOGIN",
"fidoRequestId": "string",
"server_challenge": {
"challenge": "string",
"rp": {
"id": "string",
"name": "string"
},
"user": {
"id": "string",
"name": "string",
"displayName": "string"
},
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": "discouraged"
},
"attestation": "none",
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -7
}
]
}
}
}
}
Step 4: Perform the authentication
When the user completes the FIDO2 authentication, the following API needs to be called.
This API requires you to provide the fido2_client_response (response from browser fido authentication) and exchange_id (exchange id received from Step 3)
| API | Description | Link |
|---|---|---|
| Perform the authentication | Complete the authentication process using the mobile App on FIDO2 authentication method. | Link to API |
This API performs the authentication when the user completes FIDO authentication in the browser. It returns a new
exchange_idandstatus_idwhich is required as input for the Step 5.
Request
curl --location '{{base_url}}/verification-srv/authentication/fido2/verification' \
--header 'Content-Type: application/json' \
--data '{
"exchange_id": "455fd20d-837d-43a6-a212-a02eeea1a46b",
"type": "FIDO2",
"fido2_client_response": {
"client_response": {
"rawId": "AY3Orx4_ZM1XVflAy-c4FXJyL",
"response": {
"authenticatorData": "KnpyH6ouogUi",
"signature": "MEUCI",
"userHandle": null,
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY"
},
"authenticatorAttachment": "cross-platform",
"getClientExtensionResults": {},
"id": "AY3Orx4_ZM1XVflAy-c4FXJyL",
"type": "public-key"
},
"fidoRequestId": "ce4ef9e3-43bc-4c5b-a56d-56d926b83ce3"
}
}'
This will return a new exchange_id which is unique for this process and the following steps will rely on this being provided.
Response
{
"success": true,
"status": 200,
"data": {
"exchange_id": {
"exchange_id": "dab51b25-2ae9-4bbe-ad5a-6f1d8c554dd5",
"expires_at": "2024-01-12T08:13:56.052Z"
},
"sub": "6837c08e-d748-4091-8d8e-a3e24f30e0f8",
"status_id": "710792ba-32f9-4d2d-8584-fefa3a6d94b8"
}
}
Step 5: Finish up the login process
Once the user has successfully completed the authentication, finish the login process by calling the following API. This will redirect when the authentication is successful to the provided redirect_uri including a code or an access_token depending on the OAuth2 Flow used. Link to API
curl --location '{{base_url}}/login-srv/verification/login' \
--header 'content-type: application/x-www-form-urlencoded' \
--data-urlencode 'requestId=df08cabb-4b8c-4181-9f6f-f6948802ebf7' \
--data-urlencode 'verificationType=FIDO2' \
--data-urlencode 'sub=6837c08e-d748-4091-8d8e-a3e24f30e0f8' \
--data-urlencode 'status_id=710792ba-32f9-4d2d-8584-fefa3a6d94b8' \
| API | Description | Link |
|---|---|---|
| Continue Login After Passwordless Authentication | Continue the login process once the authentication is successful. | Link to API |
Implementation using Javascript SDK
To authenticate the user via FIDO2 using the JavaScript SDK, follow the below steps
To install the cidaas-sdk please perform the following command
npm install cidaas-javascript-sdk
The import to your webapp will be done by using:
const cidaas = new CidaasSDK.WebAuth(options);
Step 1: Rendering the user verification methods
const mfaList = await this.cidaas.getMFAList({
identifier: e.identifier,
request_id: this.route.snapshot.queryParams['requestId'],
});
The UI will be rendered based on this response by displaying all configured verification methods.
Step 2: Initiating a FIDO2 authentication
When the user selects FIDO2 in the list of authentication methods, the initiateMFA method needs to be called.
const payload: IInitiateMFAPayload = {};
// pushIndex is the index of the type FIDO2 in the list and deviceIndex is the index of the device in the mediums list
const medium_id = mfaList[pushIndex]['mediums'][deviceIndex]['id'];
// usage_type should be PASSWORDLESS_AUTHENTICATION or MULTIFACTOR_AUTHENTICATION or INITIAL_AUTHENTICATION
payload['usage_type'] = 'PASSWORDLESS_AUTHENTICATION';
// requestId should come in the login hosted page query param
payload['request_id'] = this.route.snapshot.queryParams['requestId'];
payload['medium_id'] = medium_id;
payload['type'] = this.verificationType;
// Optional: For cross-domain FIDO2 authentication
payload['domainURL'] = 'https://yourdomain.com';
const initResp = await this.cidaas.initiateMFA(payload);
Step 3: Perform the authentication
When the user completes the FIDO2 browser authentication, the authenticateMFA method needs to be called.
function authenticate() {
let publicKey = generatePublicKeyCred(initResp.server_challenge);
this.navigator.credentials.get({ publicKey }).then((response) => {
// create the FIDO2 public key credential, you can use any other methods to generate this public key credential
let publicKeyCredential = publicKeyCredentialToJSON(response);
// setting up the payload for the FIDO2 authentication
const authenticatePayload: any = {
sub: initResp.sub,
exchange_id: initResp.exchange_id.exchange_id,
type: this.verificationType,
fido2_client_response: {
client_response: publicKeyCredential,
fidoRequestId: initResp.fido2_entity.fidoRequestId,
}
};
const authenticateResp = await this.cidaas.authenticateMFA(authenticatePayload);
}
}
function generatePublicKeyCred(serverChallenge) {
// decode base64 string of challenge
serverChallenge.challenge = this.decode(serverChallenge.challenge);
for (let allowCred of serverChallenge.allowCredentials) {
// decode base64 string of credId
allowCred.id = this.decode(allowCred.id);
}
return serverChallenge;
}
function publicKeyCredentialToJSON(pubKeyCred) {
if (pubKeyCred instanceof Array) {
let arr: any = [];
for (let i of pubKeyCred) {
arr.push(this. publicKeyCredentialToJSON(i))
}
return arr;
}
if (pubKeyCred instanceof ArrayBuffer) {
return this.encode(pubKeyCred);
}
if (pubKeyCred instanceof Object) {
let obj = {};
for (let key in pubKeyCred) {
obj[key] = this.publicKeyCredentialToJSON(pubKeyCred[key]);
}
return obj;
}
return pubKeyCred;
}
Step 4: Continue the Login Process
Once the user successfully completed the authentication, finish the login process by calling the passwordlessLogin method. This will redirect to the provided redirect_uri including a code or an access_token depending on the OAuth2 flow used.
let options = {
requestId: this.route.snapshot.queryParams['requestId'],
verificationType: this.verificationType,
sub: this.sub,
status_id: this.status_id
};
this.cidaas.passwordlessLogin(options);
Need Support?
Please contact us directly on our support page.