Digipass S3 is now DigipassONE. This section is currently being updated to reflect our new name.

Packaging options

Prev Next

This section covers configuration tasks to ensure that your app works properly.

Adding your app to the authentication server

Prior to releasing your completed app, you must add it to the Nok Nok Authentication Server. Refer to Configure apps.

Ensure that any legal notices included with your app contain the proper attributions to third-party source licenses. Refer to the <APP_SDK_HOME>/licenses folder for the list of third-party source licenses used in the App SDK.

Embedding a local FIDO client

To avoid a dependency on a FIDO client being installed on the device, most customers embed the local client in their app. A FIDO Client is responsible for processing FIDO messages and coordinating between an app and FIDO authenticators. This applies to the UAF protocol.

To do this, include the mfac_uaf library in your project.

Signing your app with multiple APK signing certificates

This section only applies if you sign your app with multiple signing certificates. The majority of customers use one signing certificate.

When there are multiple signing certificates, the facet ID is calculated based on the first signing certificate as stated by the FIDO specifications. However, the order of certificates is not defined by Android. If the signing order or version of the certificates changes, this changes the app’s facet ID. When this occurs, your users report that their registrations have disappeared because registrations are tied to the previous facet ID.

To prevent this from happening, use the following API to automatically set the certificate, or signature in Android terminology, for your app. This is the recommended method to use.

public void autoSetSignature(
    ActivityProxy callerActivityProxy,
    java.lang.String appID,
    java.lang.String defaultSignature,
    java.lang.String[] prioritySignatures)

autoSetSignature() can also be used to recover registrations if an app was released without setting the signature. This method checks all application signatures to determine which one has registrations. By default, the API goes through the registrations in the order that Android provides them. However, it is possible there could be registrations under multiple signatures. In this case, you can specify which signatures to check first by providing the prioritySignatures list. You can also specify a defaultSignature to use if your app has no registrations.

Embedding an authenticator

Use the App SDK to embed one or more FIDO ASMs into your mobile app by adding additional dependencies to the mobile app's project.

For an example of a properly configured Android Studio project that includes an embedded authenticator, see the Tutorial App included with the App SDK. Tutorial App is discussed in depth in Exploring Tutorial App.

Embeddable ASM libraries and dependencies are delivered by an authenticator vendor as AAR libraries packaged in Maven repositories for Android Studio. The instructions below explain how to embed ASMs into your mobile application. The steps are similar for any embeddable ASM created with the Nok Nok Authenticator SDK that has the same version as the App SDK.

The following tables list the Descriptor Class Name and ASM Library Name you must provide when embedding the PIN, Native Fingerprint, Yes/No, Keyguard, and Silent ASMs.

PIN ASM

Descriptor Class Name

com.noknok.android.client.asm.descriptor.pin.pinAuthDescriptor

Dependency

asm_pin

The PIN rules can be configured via AppSDKConfig.Key. See the Client API Docs for more details.

Native Fingerprint ASM

Descriptor Class Name

com.noknok.android.client.asm.descriptor.fps.FpAuthDescriptor

Dependency

asm_native_fps

Unbound Biometric ASM

Descriptor Class Name

com.noknok.android.client.asm.descriptor.fps.UnboundBiometricDescriptor

Dependency

asm_native_fps
Note: By default, a biometric authenticator performs authentication with a bound key.
 Devices that support only weak biometrics cannot authenticate with bound keys. 
The unbound biometric ASM supports authentication performed using weak biometrics.

Biometric Class 2.5 ASM

Descriptor Class Name

com.noknok.android.client.asm.descriptor.fps.BiometricClass25Descriptor

Dependency

asm_native_fps
Note: The biometric class 2.5 ASM is a combination of bound biometric and unbound biometric. 
This class first attempts to register a bound key. If registration is successful then future authentication 
is performed using the bound key. If the device does not support bound keys, this class registers an unbound key 
and performs future authentication using the unbound key.

Yes/No ASM

Descriptor Class Name

com.noknok.android.client.asm.presence.PresenceAuthDescriptor

Dependency

asm_presence

Keyguard ASM

Descriptor Class Name

com.noknok.android.client.asm.keyguard.KgAuthDescriptor

Dependency

Asm_keyguard
Note: The Keyguard authenticator is supported on Android Lollipop (version 5.0 and later.

Silent ASM

Descriptor Class Name

com.noknok.android.client.asm.silent.MyAuthenticatorDescriptor

Dependency

asm_silent

Wear OS watch ASM

Descriptor Class Name

com.noknok.android.client.asm.watch.WatchAuthenticatorDescriptor

Dependency

asm_watch

The Wear OS watch authenticator consists of two parts communicating with each other. Integrate the asm_watch_wear library into the Wear OS app and install it on the watch so the asm_watch authenticator is available in the Android phone app.

Adding a descriptor

Create a file named asmdescriptors.json and place it in a res/raw subfolder. The example shows how to embed the PIN, Native Fingerprint, and Yes/No based ASMs:

{
    "descriptorclass":[
        "com.noknok.android.client.asm.descriptor.pin.pinAuthDescriptor",
        "com.noknok.android.client.asm.descriptor.fps.FpAuthDescriptor",
        "com.noknok.android.client.asm.presence.PresenceAuthDescriptor"
    ]
}

Adding activities to your app manifest

Android Studio automatically merges the activities from the various AndroidManifest.xml files within library projects. Consequently, declare all activities only within individual library projects.

Configuring logging

Before you release your app, strip the logging statements to save space. Another option is to leave the logging statements in place and disable them at runtime.

Stripping logging statements

To prepare a mobile application for release, all logging statements need to be stripped. This ensures that no sensitive information is sent to the Android logging system. Use the standard ProGuard tool included in the Android SDK to perform this task.

  1. Locate the ProGuard configuration file for the mobile application. This file is usually called proguard.cfg and its location depends on your project structure.

  2. Add the following statements to the ProGuard configuration to strip logging statements:

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** w(...);
    public static *** e(...);
    public static *** i(...);
}

For more information on using ProGuard, refer to https://developer.android.com/build/shrink-code

Enabling debug logging

To allow debug logging on your app, use the following commands:

import com.noknok.android.client.utils.Logger;
Logger.setLogEnabled(true);

Call this API before any calls to the App SDK. You can ignore the return value because it is the old value of setLogEnabled. This call emits no exceptions.

Client logging options

Mobile applications in the field occasionally experience problems that require a developer's attention to fix. It is often difficult to reproduce problems in the field. Developers who worked on the code for the problem application often do not have the environment or exact device with which to test. In these situations, it is helpful to be able to retrieve debug logs from the client devices as the problems occur in the field.

This section outlines a process to generate, transmit, and retrieve mobile application logs.

Enabling App SDK logging

App SDK logging allows an app to easily intercept all log messages generated by the App SDK. There is sample code in the Tutorial App to show how this is done. Refer to SampleLogger.kt for details. The following points should be considered:

  1. Calling Logger.setLogger routes all log messages to the println methods in your ILogger implementation.

  2. The interface defines two versions of println, one is called when there is an internal exception associated with the log message and the other is not.

  3. Internal exceptions do not necessarily indicate an issue. Instead, the priority value indicates the severity of the issue.

  4. Your ILogger implementation has the option of calling the existing logger if you still want to log to the console. This is what SampleLogger does.

  5. If logging is explicitly disabled by calling Logger.setLogEnabled(false), then println will not be called. By default, logging is enabled.

  6. If you use ProGaurd for stripping logging statements, your ILogger implementation should still be called.

Appending client logs to alternating files

To save logs leading up to a crash, append logs to a file. Once the file reaches a predetermined size, close it, and then begin writing to a second file. Once that file reaches a predetermined size, close it and then overwrite the first file. Each file should be large enough to hold at least one minute worth of logging data or one thousand log lines.

Transmitting client logs to a central server

Once the application restarts, both files should be uploaded to a server where they can be examined. Limits should be set to only transmit logs a certain number of times per day to the server. For example, if an application repeatedly crashes ten times a day, do not upload the logs ten times a day.

If desired, some additional information could be uploaded to identify the client device.

The Client configuration file

The client supports a configuration file, called mfac_config.json, that enables you to override default values that are hard coded in the App SDK. Place this file in a res/raw subfolder you create inside the module. The configuration information is contained in a JSON object:

{
    "Fieldname1": Value1,
    "Fieldname2": Value2
}

The most commonly used fields are listed in the sections below. For details on other fields, see the AppSDKConfig.Key class in the Client API Docs.

Note that a different client configuration file, the JSON UI Configuration file described in Customizing Strings, Styles, Images and More, contains customizations that affect the user interface.

asmSelectionEnabled

Controls whether the client prompts the user to choose an authenticator to use. This is a boolean.

  • True (default): The client prompts the user to choose an authenticator to use, if the UAF policy matches multiple authenticators.

  • False: The client automatically picks the first matching authenticator and never prompts the user. Nok Nok doesn't recommend this option.

suspendRegistrationEnabled

Controls whether the user is able to suspend a credential's registration without removing it. This is a boolean and the default is False.

clientOrder

Tries the local and/or remote client in the order specified.

This feature is for devices featuring a built-in FIDO Client and FIDO ASM (e.g. Samsung devices).

Possible values are:

  • ["LOCAL"]

  • ["LOCAL","REMOTE"]

  • ["REMOTE"]

  • ["REMOTE","LOCAL"]

The default is shown below:

"clientOrder" : ["LOCAL"]

otpConfig

Configures SMS and email OTP by specifying the maximum number of retries, the amount of time the end user has to make those attempts, and the lockout period if the user fails to enter a registered email address or phone number. You can also configure this value from the Server, see Configure non-FIDO authentication methods.

An example JSON object with all available fields:

"otpConfig": {
    "maxFalseAttempts": 3,
    "probationPeriod": 20,
    "lockoutPeriod": 20
}

Field

Description

maxFalseAttempts

Maximum number of failed attempts allowed for an end user. Recommended to be greater than 1. The default value is 3.

probationPeriod

Time in seconds during which maxFalseAttempts are allowed. The default value is 0, which means that no time limit is enforced. When this expires, maxFalseAttempts and lockoutPeriod are reset. When the user makes maxFalseAttempts, the authentication fails and the user starts over.

lockoutPeriod

After the user makes maxFalseAttempts, the user is locked out for lockoutPeriod seconds. The user cannot start a new authentication during that period. The default value is 10.

pinConfig

Configures PIN creation behavior and specifies constraints of the PIN ASM. Configure anti-hammering behavior by setting maxFalseAttempts, probationPeriod, and lockoutPeriod.

An example JSON object with all available fields:

"pinConfig": {
    "minLength": 5,
    "maxLength": 6,
    "maxRepeatDigits": 3,
    "maxSequentialDigits": 4,
    "confirmationButton": true,
    "maxFalseAttempts": 3,
    "probationPeriod": 20,
    "lockoutPeriod": 20,
    "nonReusableOldPINs": 0
}

Field

Description

minLength

Minimum PIN length. The default value is 4 and the value can’t be less than 4. Cannot be more than maxLength.

maxLength

Maximum PIN length, cannot be less than minLength. The default value is 4.

maxRepeatDigits

Maximum number of repeated digits allowed in the PIN. The default value is 0, which means all digits can be repeated.

maxSequentialDigits

Maximum number of sequential digits in the PIN. The default value is 0, which means all digits can be sequential, in either increasing or decreasing order.

confirmationButton

Boolean field that controls whether the PIN confirmation button is displayed on the PIN ASM UI. The default value is true which means the button is displayed.

The system automatically assigns true to this field if minLength and maxLength are different.

maxFalseAttempts

Maximum number of incorrect PIN attempts allowed. Should be greater than 1. The default value is 10. When the user enters an incorrect PIN more than maxFalseAttempts times, then the user's legally registered PIN is deleted.

probationPeriod

Time in seconds during which maxFalseAttempts are allowed. The default value is 0, which means then no time limit is enforced.

lockoutPeriod

Time in seconds when the user is locked out after maxFalseAttempts is reached. The default value is 0, which means the PIN is deleted after maxFalseAttempts is reached.

nonReusableOldPINs

Positive integer. The system prevents the user from using the previous nonReusableOldPINs PINs as a valid current PIN. The default value is 0, which means the system allows any previous PIN to be reused.

useRemoteASM

Controls whether your app uses remote or external authenticators. Boolean.

  • True: Remote ASMs can be used.

  • False (default): Remote ASMs cannot be used.

credentialManagerEnabled

Boolean. Controls whether the App SDK uses Google's CredentialManager APIs for passkey logic. The CredentialManager APIs support third party credential managers in addition to existing shared passkeys using Google Password Manager. Disabling this field does not require a change to your Nok Nok App SDK calls. CredentialManager APIs are supported starting from Android 14.

  • true (default): The App SDK uses Google's CredentialManager APIs for passkey logic.

  • false : CredentialManager APIs are disabled. The App SDK uses older passkey APIs.

sendCredentialProviderInfo

Boolean. Controls whether the App SDK sends information on available credential providers in its request to the Server. This information is used by the Server to suggest that the user authenticate with a passkey when a passkey is available on their device.

  • true (default): Send the additional information on available credential providers.

  • false: Do not send additional information on credential providers.

Configuring signal generation

The App SDK can generate and send signals to the Server when the user is registering or authenticating. The Server can use these signals to decide which adaptive rules and which FIDO policies to apply. Since these signals take resources and time to process on a device, you can specify when these signals are generated by editing the mfac_config.json file.

You can specify signals for device jailbreak status signal, Play Integrity data signal, user location signal, WiFi network signal, Metrics, and User on phone call signal. All of these signals allow the same configuration fields and values as described below.

Each signal’s configuration uses the following structure to control when it is generated. The field name specifies where the App SDK can place the generated signal in REST API client-server requests. The value controls whether the App SDK generates and sends the signals.

An example JSON object with all available fields for a sendLocation signal that the App SDK should never send:

"sendLocation": {
    "init": "never",
    "finish": "never",
    "protocol": "never"
}

Field

Description

init

When to place the signal in the INIT request payload. Use this field for signals used by adaptive rules.

Values: "always" | "never" | "silently"

finish

Only use this if your Server version is 6.0.2 or newer. When to place the signal in the FINISH request payload. Use this field for signals used by FIDO policy risk rules.

Values: "always" | "never" | "requested" | "silently"

protocol

Only use this if your Server version is 6.0.1 or older. When to place the signal in the FINISH request inside the protocol message. Use this field for signals used by FIDO policy risk rules.

Values: "always" | "never" | "requested" | "silently"

The values mean:

  • always: Always generate the signal.

  • never: Never generate the signal.

  • requested: Generate the signal only if it is requested by the Server.

  • silently: If the user has already granted your client app permission to access the signal, then generate it. The advantage of this option is that it doesn't prompt the user if they haven't yet granted permission. This only applies to sendLocation and sendWifiSSID since they require user permission.

Device jailBreak status signal

sendJailBreakRiskSignal controls whether the App SDK automatically generates and sends the jailbreak signal.

Configure this signal as shown below if

  • You defined an adaptive rule or a FIDO policy risk rule that uses device health (device health uses the jailbreak signal).

  • Your Server is version 7.0.0 or later.

"sendJailBreakRiskSignal":{
    "init": "always",
    "finish": "requested",
    "protocol": "never"
}

This is the default configuration, which means that the App SDK never sends the jailbreak signal in the INIT request nor in the protocol message, and sends it in the finish response payload only if the Server requests it:

"sendJailBreakRiskSignal":{
    "init": "never",
    "finish": "requested",
    "protocol": "never"
}

See table above for field descriptions.

Play Integrity data signal

sendPlayIntegrity controls whether the App SDK automatically generates and sends the Google Play Integrity signal. The App SDK sends a Play Integrity token to the Auth Server so that the Auth Server can determine if the app is legitimate, and the device running the app is valid. The Auth Server can then use this information in the PostOperation Checks and the Supplemental Checks.

To have the App SDK generate and send the Play Integrity signal to the Server, configure the sendPlayIntegrity signal in mfac_config.json. The App SDK can generate the Play Integrity Signal only if it is running on an Android device.

Use the default sendPlayIntegrity configuration shown below to generate and send this signal. This specifies that the App SDK never sends the Play Integrity signal in the INIT request nor in a protocol message. The App SDK generates and sends the Play Integrity signal in the FINISH response payload only if the Server requests it.

Setting up for Google Play Services"sendPlayIntegrity":{
    "init": "never",
    "finish": "requested",
    "protocol": "never"
}

See Setting up for Google Play Services for the required Google Play Services library.

User location signal

sendLocation controls whether the App SDK automatically generates and sends the location signal. Configure this signal (use the default configuration) if you create  /gloss that look at a user's location.

See Setting up for Google Play Services for the required Google Play Services library. See Setting up for Huawei Mobile Services for the required Huawei Mobile Services library. To enable your app to transmit location information to the Server, you must request user permission by declaring the ACCESS_FINE_LOCATION permission in the Android manifest file.

Ensure that you request permission for ACCESS_FINE_LOCATION only, as it includes permission for both providers (NETWORK_PROVIDER and GPS_PROVIDER). For example:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Below is the default configuration, which means that the App SDK generates and sends the location signal in the INIT request only if the end user already granted permission to the App SDK, sends it in the finish response payload only if the Server requests it, and never sends it in a protocol message. Location needs to be sent during INIT so it can be used by an adaptive rule.

"sendLocation":{
    "init": "silently",
    "finish": "requested",
    "protocol": "never"
}

See table above for field descriptions.

Metrics

sendMetrics controls when the App SDK sends metrics to the Server. Configure this signal if you would like to disable sending metrics to the Server.

"sendMetrics":{
    "init": "never",
    "finish": "never",
    "protocol": "never"
}

See table above for field descriptions.

WiFi network signal

sendWifiSSID controls whether the App SDK automatically generates and sends the WiFi network name. Configure this signal (use the default configuration) if you  that look at a user's WiFi network. The end user must consent to allow the App SDK to access their WiFi SSID.

Below is the default configuration, which means that the App SDK generates and sends the WiFi SSID signal in the INIT request only if the end user already granted permission to the App SDK, it generates and sends the signal in the FINISH response payload only if the Server requests it, and it never sends it in the protocol message. The WiFi network needs to be sent during INIT so it can be used by an adaptive rule.

"sendWifiSSID":{
    "init": "silently",
    "finish": "requested",
    "protocol": "never"
}

See table above for field descriptions.

User on phone call

sendInCallState controls the generation of the in-call extension, a boolean that tells if the user is on a phone call or not.

"sendInCallState": {
    "init": "never",
    "finish": "requested",
    "protocol": "never"
}

See table above for field descriptions.

Excluding database files from Backup

Beginning with Android 6.0 (API 23), Android provides the Auto Backup for Apps feature enabled by default. The ASM database files must be excluded from backup because data in these files are encrypted with a key located in the keystore, and the key does not survive the application uninstall/install cycle. As a result, if an old database is restored, the application is unable to use it.

Database files are stored in the files subfolder of the application local folder. The following fragment shows how they can be excluded from backup.

  1. Create an XML file describing the backup content in the res/xml/ directory. The following example excludes the database files for the authenticators with the 0001#0001 and 0001#0002 AAIDs. For other AAIDs, specify the correct path attribute. If there are .dat files, such as 0001#0001.dat, exclude those as well.

In the res/xml/my_backup_rules.xml file:

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <exclude domain="file" path="0001#0001"/>
    <exclude domain="file" path="0001#0001.dat"/>
    <exclude domain="file" path="0002#0002"/>
    <exclude domain="file" path="0002#0002.dat"/>
</full-backup-content>
  1. Update the AndroidManifest.xml file to specify the backup content file:

<application ...
    android:fullBackupContent="@xml/my_backup_rules">
</app>

Localizing

If you are changing the style of the user interface, including colors and images, we recommend that you create cross-platform JSON UI configuration files which also localize strings. See Customizing Strings, Styles, Images and more.

Otherwise, if you are using the default App SDK UI, you can add a new localization to the local FIDO client library and override existing location strings, layouts and icons. If you are only localizing the strings in your application, we recommend this alternative as described in this section.

The local FIDO Client library module contains string resources used in the user interface. The default English localizations are stored in the res/values/strings.xml file, but a mobile application can add its own localizations for additional languages.

For ease of development, the resource string files from different modules are copied to the following location: <APP_SDK_HOME>/values/

The following table lists the string files provided with the App SDK for localization.

String file name

Description

string_appsdk_plus.xml

AppSDKPlus module resource strings

string_appsdk_adaptive.xml

AppSDK Adaptive module resources

string_appsdk.xml

App SDK module resource strings

string_appsdk_vision.xml

App SDK Vision module resource strings

string_asm_keyguard.xml

Keyguard ASM module resource strings

string_asm_native_fps.xml

Native Fingerprint ASM module resource strings

string_asm_pin.xml

PIN ASM module resource strings

string_asm_presence.xml

Yes/No ASM module resource strings

strings_asm_silent.xml

Silent ASM module resource strings

strings_asm_watch.xml

Watch ASM module resource strings

string_asmsdk.xml

ASM SDK module resource strings

strings_asmsdk_uaf.xml

ASM SDK UAF module resource strings

string_mfac_uaf.xml

FIDO Client UAF module resource strings

The names of authenticators are stated in strings inside the local FIDO client library strings file. These strings are of the form:

"Passkey on {0}|<alternate name>".

For these strings, the SDK replaces the {0} with the authenticator name returned by the Server. The text after the | is the default name to use if the server cannot identify the authenticator. See the section Friendly Authenticator Naming for more details.

Adding a new localization to the local FIDO client

  1. Create a new folder in your project's res folder using a name of the form values-<locale>, where <locale> is the locale identifier string (LCID). For example, values-en-rau for Australian English.

  2. Copy the files listed in the above table from <APP_SDK_HOME>/values/ into the newly created folder.

  3. Translate the string values in the XML file into the target language.

Do not modify the tag names in the string_mfac_uaf.xml file. Any modification might interfere with the correct display of localized strings.