Getting started

Let's get started!

In this guide, you will learn how to integrate the Keyless SDK in your mobile application. Keyless SDK enables you to enroll and authenticate users through the Keyless platform.

Since Keyless has more advanced features than just a simple authentication product, the guide is split into multiple functional sections with more details, with proper code snippets and examples for both iOS and Android.

For any questions or comments (at any time) during the integration phase please reach out to your primary Keyless contact or to info@keyless.io.

Prerequisites

Android 6.0 (API level 23) and above

Gradle 6.5+

Android Gradle Plugin 4.0.0+

AndroidX

To allow Keyless to handle the result of registerForActivityResult, you must call Keyless from an Activity implementing ActivityResultCaller. Your best option is to extend any androidX activity that implements the interface for you, for example let your Activity extend the generic ComponentActivity or the more widespread AppCompatActivity

If you use Progurad add the following rules:

# Keyless Proguard 
-keep class io.keyless.sdk.** {*;}
-keepclassmembers class io.keyless.sdk.** {*;}

Installation

Add the following within the repositories section of the settings.gradle file of your Android application.

Replace the YOUR_CLOUDSMITH_TOKEN text with the CloudSmith token for partners provided to you by Keyless.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url "https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/maven/"
        }
    }
}

Add the following to the dependencies block of your project build.gradle file, typically app/build.gradle.

app/build.gradle
dependencies {
  // ...
  
  implementation 'io.keyless:keyless-android-sdk:+'
}

Make sure you have the following options in the android block of the same file

app/build.gradle
android {
    // ...
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    // add the following only if you're using Kotlin
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Configuration

Now all the dependencies should be set. To start using the Keyless SDK you just need to configure it.

First initialize the Keyless SDK in your Application class:

// MainApplication
override fun onCreate() {
  super.onCreate()
  // Initialize Keyless
  Keyless.initialize(this)
}

Make sure to add your application to you Manifest

<application
    ...
    android:name=".MainApplication"
    ...
</application>

Then configure the Keyless SDK from your MainActivity, ViewModel or any class you use to communicate with Keyless.

Note: configure is asynchronous so wait for the completion callback before calling the next Keyless APIs

The configure method requires aSetupConfiguration as parameter. You should listen to the result as follows:

val setupConfiguration = SetupConfiguration.builder
  .withApiKey("apiKey")
  .withHosts(listOf("host"))
  .build()

Keyless.configure(setupConfiguration) { result ->
    when (result) {
        is Keyless.KeylessResult.Success -> {
            Log.d("KeylessSDK", "configure success")
            // Keyless is ready, you can now call
            // enroll/authenticate/deEnroll ...
        }
        is Keyless.KeylessResult.Failure ->{
            Log.d("KeylessSDK", "configure error")
            // Inspect result.error for more info
        }
    }
}

SetupConfiguration parameters

It is possible to specify configuration parameters using the SetupConfiguration builder. In addition to the apiKey (.withApiKey()) and hosts (.withHosts) above, you can also specify the following optional configuration parameters:

Logging enabled

Using the withLoggingEnabled() method it is possible to activate the logging on Keyless analytics tool. These logs do not include any sensitive data from your users. Keyless SDK logs predefined events to help monitor your app usage.

Logging is disabled by default.

Lockout policy

This is a feature will block users for a given amount of time if there are too many failed authentication attempts.

After a number (lockoutAttemptsThreshold) of failed authentication attempts the user will be locked out.

The user will remain locked out for the specified lockoutDuration.

The attempts are reset after the specified lockoutAttemptsResetAfter time.

Account lockoutDuration must be greater than or equal to the value of lockoutAttemptsResetAfter or the lockoutDuration will be reset by the other timer.

You can specify it using the following api:

fun withLockoutPolicy(
    lockoutDuration: Long,                //seconds - default 300 seconds
    lockoutAttemptsResetAfter: Long,      //seconds - default 180 seconds
    lockoutAttemptsThreshold: Int         //number  - default 5 attempts
)

Tampered device check

Checking for rooted/jailbroken phones is an unreliable process but you can enable the check with the following api: withTamperedDeviceCheck(). If you enable this check and the phone is tampered the Keyless SDK will return an error and avoid performing any operation.

Enrollment circuits

To speed up enrollment you can specify a different number of enrollment circuits (there is a default to 5 enrollment circuits). You do not need to change that but in case it is needed there is a dedicated api: withNumberOfEnrollmentCircuits(numberOfEnrollmentCircuits: Int)

Networking module

The SDK exposes an API to specify which function shall be called to perform network requests. You can specify a custom "networking module" adding withNetworkingModule from the SetupConfigurationBuilder. Your implementation of the networking module must conform to the interface below.

public interface KLNetworkingModule {
    public fun sendHTTPRequest(
        baseUrl: String,
        path: String,
        method: String,
        headers: Map<String, String>,
        body: String
    ): KLHTTPResponse

    public data class KLHTTPResponse(
        val errorCode: Int,
        val httpCode: Int,
        val responseBody: String
    )
}

Last updated