Skip to main content

Register a FIDO2 authenticator

In this process, you are registering a new FIDO2 authenticator. If the user does does not exist yet, a new user is created. In the registration process, WebAuthn credentials must be created. For the credential creation our JavaScript solution can handle the communication between the WebAuthn API and the Authentication Cloud API.

The following diagram shows the end-to-end sequence of an registration operation for a FIDO2 authenticator. The steps that must be performed to integrate the Authentication Cloud into your application are in bold. Some steps are included in the JavaScript solution.

Send an HTTP request to the registration endpoint

For detailed information on the HTTP request parameters and response fields, see the Registration endpoint page of the API reference documentation.

Send the POST https://{instance}.mauth.nevis.cloud/api/v1/users/enroll call with your instance ID, and configure the HTTP request as follows:

  1. Send your access key or intent token in the Authorization Bearer token header. For more information on the intent token, see Intent endpoint.
  2. Set the channel parameter to fido2.
  3. Set the username and displayName parameters. The displayName parameter is a human-readable name of the user. The length is limited to 64 bytes.

    Use unique static information for the username parameter. To link a user to your internal systems, you might use, for example, an internal customer ID or employee ID, and provide that as a username in the user registration request. It is important to use information that does not change over the life cycle of a user.

    Do not use a username with any Personally Identifiable Information (PII). For example, an email address is not recommended because it is not only PII data, but it also might change over the lifecycle of a user.

    Preventing User Impersonation

    To prevent impersonation, ensure you only link users to your backend records after strongly authenticating them first.

  4. Optionally, set the fido2Options parameters. These parameters change the default registration settings. The following parameters can be configured:
    • userVerification: Use this parameter to customize the requirement for user verification. The default value is preferred.
    • authenticatorAttachment: Use this parameter to select the preferred authentication attachment modality.
    • requireResidentKey: Set the value to true only if residentKey is required. This parameter is retained for backwards compatibility with WebAuthn Level 1.
    • residentKey: Set the value to required to enable autofill UI. This creates a client-side discoverable credential.
    • attestation: Use this parameter to customize the attestation conveyance preference. The default value is none.

HTTP request example

cURL code sample for registration using custom FIDO2 options
curl "https://$instance.mauth.nevis.cloud/api/v1/users/enroll" \
-XPOST \
-H "Authorization: Bearer $access_key" \
-H 'Content-Type: application/json;charset=utf-8' \
-d "{ \"username\":\"$username\",
\"channel\":\"fido2\",
\"displayName\":\"$displayName\",
\"fido2Options\": {
\"authenticatorSelection\": {
\"userVerification\":\"required\",
\"authenticatorAttachment\":\"platform\",
\"requireResidentKey\":false,
\"residentKey\":\"discouraged\"
},
\"attestation\":\"none\"
}
}"

HTTP response example

201 Created: Register FIDO2 device

{
"authenticators": [],
"createdAt": "2022-03-04T11:04:51.523566769Z",
"enrollment": {
"credentialCreationOptions": {
"attestation": "none",
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"requireResidentKey": false,
"residentKey": "discouraged",
"userVerification": "required"
},
"challenge": "h6U-j...PUrw",
"excludeCredentials": [],
"pubKeyCredParams": [
{
"alg": -65535,
"type": "public-key"
},
...
{
"alg": -36,
"type": "public-key"
}
],
"rp": {
"id": "your-nevis-dev.mauth.nevis.cloud",
"name": "NEVIS Authentication Cloud: your-nevis-dev"
},
"timeout": 60000,
"user": {
"displayName": "John Doe",
"id": "ZmY0Mj...1YTky",
"name": "u_12654"
}
},
"statusToken": "eyJh...9.eyJh...ZQI-MuCQ",
"transactionId": "e7bf20-...-56b6683"
},
"phones": [],
"recoveryCodes": null,
"status": "new",
"updatedAt": "2022-03-04T11:04:51.523567669Z",
"userId": "ff4-a...d5a92",
"username": "u_12654"
}

Start polling the status endpoint

To verify the success of the registration operation, start polling the status endpoint from your frontend application. The recommended polling interval is 1.5 seconds. Depending on your circumstances, such as user needs and production system capabilities, you might need to adjust the wait times between two polling cycles.

For detailed information on the HTTP request parameters and response fields, see the Status endpoint page of the API reference documentation.

Send the POST https://{instance}.mauth.nevis.cloud/api/v1/status call with your instance ID, and configure the HTTP request as follows:

  1. Send the statusToken that was retrieved during the registration operation.

  2. Poll for the status as long as status is pending.

When you receive a succeeded, failed, or unknown status, you can react accordingly. If the status is succeeded, continue with verifying the operation from your backend application.

HTTP request examples

Code sample for status polling
# Set $statusToken
curl "https://$instance.mauth.nevis.cloud/api/v1/status" \
-XPOST \
-H 'Content-Type: application/json' \
-d "{ \"statusToken\": \"$statusToken\" }"

HTTP response examples

200 OK: Pending - The operation is still waiting for confirmation by the user

{
"transactionId": "b7d44592-91f3-4f4b-9e37-202a3061edc3",
"status": "pending",
"userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
"username": "Userxyz123",
"token": "eyJhb...Fl9bpEXGGw",
"createdAt": "2020-10-09T12:52:48Z",
"lastUpdatedAt": "2020-10-09T12:52:48Z"
}

Forward the credentialCreationOptions object

The WebAuthn API requires the credentialCreationOptions object to create a new credential. This object can be found in the registration response. To create a new credential, your application backend has to pass the credentialCreationOptions to the frontend or to the native mobile app.

Create a WebAuthn credential with the JavaScript solution

Once the credentialCreationOptions is forwarded to the browser, apply the Authentication Cloud JavaScript template to create a new WebAuthn credential. The frontend of the relying party must include a JavaScript solution to connect to the Authentication Cloud API.

The template includes the following WebAuthn calls:

  1. Using the @github/webauthn-json client-side Javascript library which is a convenience wrapper for the WebAuthn API.
  2. Checking if WebAuthn is supported by the browser.
  3. Creating the registerOptions object that will be needed by the @github/webauthn-json library.
  4. Calling the @github/webauthn-json library to create a new WebAuthn credential. As a result, a serverPublicKeyCredential object is returned.
    note

    After this step, a native browser dialog prompts the user to perform an authorization gesture. The dialog prompts differ depending on the available and connected authenticators. Once a user has given consent by performing the gesture, the authenticator generates a public and private credential key pair, and returns the public key as part of the response.

  5. Extending ServerPublicKeyCredential with the following attributes to provide Authentication Cloud with vital information:
    • userFriendlyName: the name of the new authenticator
    • userAgent: used by the backend for logging and audit purposes
  6. Sending the credentials to the Authentication Cloud backend attestation endpoint. This endpoint does not require a token.
  7. Handling the success or failure response, based on the attestation endpoint response.

JavaScript template

JavaScript template for creating a new credential
// 0
import {
create,
parseCreationOptionsFromJSON,
get,
parseRequestOptionsFromJSON,
} from "https://unpkg.com/@github/[email protected]/dist/esm/webauthn-json.browser-ponyfill.js";

...

function defaultHeaders() {
return {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=utf-8',
};
}

function isWebAuthnNotSupportedByTheBrowser() {
if (window.PublicKeyCredential === undefined || typeof window.PublicKeyCredential !== 'function') {
let errorMessage = 'Oh no! This browser doesn\'t currently support WebAuthn.';
if (window.location.protocol === 'http:' && (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1')){
errorMessage = 'WebAuthn only supports secure connections. For testing over HTTP, you can use the origin "localhost".';
}
console.log(errorMessage);
return true;
} else {
return false;
}
}

// 1
if (isWebAuthnNotSupportedByTheBrowser()) {
// case when the browser does not support WebAuthn
}

// 2
const registerOptions = {
publicKey: credentialCreationOptions
};

// 3
const parsedCredentialCreationOptions = parseCreationOptionsFromJSON(registerOptions);
const serverPublicKeyCredential = (await create(parsedCredentialCreationOptions)).toJSON();

// 4
serverPublicKeyCredential.userFriendlyName = "The authenticator name can be customized";
serverPublicKeyCredential.userAgent = navigator.userAgent;

// 5
const response = await fetch(
'https://<your-instance>.mauth.nevis.cloud/_app/attestation/result', {
method: 'POST',
credentials: 'same-origin',
headers: defaultHeaders(),
body: JSON.stringify(updatedServerPublicKeyCredential),
});
const result = await response.json();

// 6
if (result.status === 'ok') {
// handle success
} else {
// handle failure, you can find more details in result.errorMessage
}

Forward the server response to your application backend

The server response must be sent to your application backend to verify the operation from the server side.

Verify the operation

Once the authentication is successful and you receive the server response, verify the operation. Use of the following verification methods:

  • HTTP request to the status endpoint
  • HTTP request to the introspect endpoint

Send an HTTP request to the status endpoint

By calling the status endpoint from your backend application, you request Authentication Cloud to verify the validity and the authenticity of the operation. This is done by using the statusToken from the previous HTTP response.

For detailed information on the HTTP request parameters and response fields, see the Status endpoint page of the API reference documentation.

Send the POST https://{instance}.mauth.nevis.cloud/api/v1/status call with your instance ID and include the statusToken that was retrieved during the operation.

Send an HTTP request to the introspect endpoint

By calling the introspect endpoint from your backend application, you request Authentication Cloud to verify the validity and the authenticity of the user. This is done by using the transaction token returned by the status endpoint.

For detailed information on the HTTP request parameters and response fields, see the Introspect endpoint page of the API reference documentation.

Send the POST https://{instance}.mauth.nevis.cloud/api/v1/introspect call with your instance ID, and configure the HTTP request to the introspect endpoint as follows:

  1. Send your access key in the Authorization Bearer token header.
  2. Add your token that you want to verify.

HTTP request examples

cURL code sample for checking the validity and authenticity of a token
# Set $token
curl "https://$instance.mauth.nevis.cloud/api/v1/introspect" \
-XPOST \
-H "Authorization: Bearer $access_key" \
--data-urlencode "token=$token"

HTTP response examples

200 OK: Active and valid access key

{
"active": true,
"iat": 1642436165000,
"sub": "c8edb1d1-6dac-470f-b2fb-c25277a5c5b6",
"aud": "api",
"iss": "https://{instance}.mauth.nevis.cloud/"
}