Register Mobile Biometrics

Registers native mobile biometrics for the user using the client SDK

About client-facing steps

A journey is a sequence of steps that are executed when it's invoked by a client application (known as the "client"). Some steps require involvement from the client, such as to collect user input. Other steps, like validating a token, are executed in the backend by the Mosaic journey engine alone.

When invoked, the journey begins executing the steps while the client waits for further instructions. When a journey reaches a client-facing step, the journey asks the client for the required input and then waits for the client to respond. The client presents their own UI if user interaction is required, and returns input to the journey. The journey then proceeds in a similar manner until it's completed.

Description

This client-facing step is used to register biometric credentials on a user's mobile device for biometric authentication (e.g., Face ID). Once registered, users can login with biometrics using the Mobile Biometrics Authentication step.

Biometric credentials are bound to a specific user and Mosaic application. The user may be provided implicitly by the journey if the user is already authenticated; otherwise, a user identifier must be specified in the step configuration. Credentials should only be registered to a user that has verified their identity—for example, using email OTP, document verification, or externally using a legacy system.

When triggered, this step instructs the client to register biometric credentials on the device and provides the user identifier. The client then uses the Authentication SDK to perform the client-side registration, where the user identifier may be used as input to the registration call.

Once credentials are registered on the device, the SDK returns a registration result that includes the key ID and public key. The client sends this result back to the journey using the IDO SDK, and the step completes the registration in the platform. If successful, the journey proceeds to the next step. If it fails or is cancelled, the journey is either aborted or proceeds to the dedicated cancel or failure branches (if configured).

To support biometric registration, you'll need to:

  • Configure the Register Mobile Biometrics journey step
  • Implement the Authentication SDK calls required for registration, as described here
  • Implement the IDO SDK call that submits the client response back to the journey (see Android IDO SDK reference or iOS IDO SDK reference )
Note

For requirements and instructions on how to set up Authentication SDK on Android and iOS, see the Android quickstart and the iOS quickstart (skip Step 3 and 4). For Android, this requires the Authentication SDK with compileSdk 34 (or greater) and minSdk 23.

Configuration

Field Description
User Auth State Indicates if the user has authenticated in this journey. If the user is authenticated (default), the user context is provided implicitly by the journey. If not, a user identifier must be configured.
User Identifier User identifier, specified as an expression. Only configured if the journey doesn't authenticate the user before invoking this step.
Error Output Variable Name of the variable that stores any errors returned by step
Failure Behavior Determines the behavior in case of failure, which either aborts the journey or proceeds to a failure branch of the control flow (default).
Custom Branches Additional journey branches supported for this step. The client can select a branch by returning the branch ID. For each branch, you can define a schema for the information that the client is expected to return (used by the code generator and for autocompleting journey expressions) and a display name to label it in the editor.
Branch Output Variable Name of the variable used to store the data returned by the client, which can be used in subsequent journey steps.
Cancel Behavior Determines the behavior of client cancellation, which either aborts the journey (default) or proceeds to a cancel branch of the control flow

Example

Consider a journey that authenticates the user (e.g., using password) before initiating a biometric registration. In our example, the User Auth State is set to The user is already authenticated in the step configuration.

When executed, this step sends a callback to the client with the IDO service response object. It will have the journeyStepId set to registerNativeBiometrics and the data will include the user identifier. In the example below, the user identifier is used as input to the biometric registration call. Once registration is completed, the client submits the result back to the journey to complete the step.

KotlinSwift
Copy
Copied
// Stores the user identifier provided by the journey
val userId = idoResponse.responseData.optString("user_identifier") 
applicationContext?.let {
  // Registers biometric credentials on the device using the Authentication SDK
    TSAuthentication.registerNativeBiometrics(it, userId, object: TSAuthCallback<TSBiometricsRegistrationResult, TSBiometricsRegistrationError>{
        override fun error(error: TSBiometricsRegistrationError) {
            //handle registration error
        }

        override fun success(result: TSBiometricsRegistrationResult) {
            Log.d(TAG, "Biometrics registration success")
            // Submits the registration result back to the journey using the IDO SDK
            submitResponse(TSIdoClientResponseOptionType.ClientInput.type, BiometricsRegistrationResult(result.keyId(), result.publicKey()))
        }
    })
}

data class BiometricsRegistrationResult(val publicKeyId: String, val publicKey: String, val os: String = "Android")
Copy
Copied
guard let userId = response.data?["user_identifier"] as? String else {
            return debugPrint("[DEBUG]: No user identifier found in response")?
        }
        
        // Registers biometric credentials on the device using the Authentication SDK
        TSAuthentication.shared.registerNativeBiometrics(username: userId) { result in
            switch result {
            case .success(let response):

                var data: [String: Any] = [
                    "publicKey": response.publicKey,
                    "publicKeyId": response.publicKeyId,
                    "os": "ios"
                ]

                if let attestation = response.attestation {
                    data["attestation"] = attestation
                }

                // Submits the registration result back to the journey using the IDO SDK
                TSIdo.submitClientResponse(clientResponseOptionId: .clientInput, data: data)
            case .failure(let error):
                debugPrint("[DEBUG] Error: \(error)")
                TSIdo.submitClientResponse(clientResponseOptionId: .fail)
            }
        }