Security controls

Debug detection

Android SDK has an ability to detect if the app works in debug mode or with debuggable environment (for example if it's running on emulator). If debug mode detection is enabled and debug is detected, then the SDK will not allow to execute any security related flow. Also special event will be logged on the Token Server instance indicating that connection from potentially unreliable device was sent.

Root detection

The SDK is capable to detect whenever device running the application is rooted. If detection is enabled and device is rooted, then the SDK will not allow to execute any security related flow. Also special event will be logged on the Token Server instance indicating that connection from potentially unreliable device was sent.

Tampering detection

To validate the app has not been tampered with the client secret can be sent encrypted (depending on the client configuration in the Token Server) to any request using the client secret to the Token Server. The client secret encryption is done using the application signature which naturally changes across different app versions so once the application gets updated/changed server will not be able to validate it anymore. For that reason the client secret is tied to a specific application version and will also be changed once application is updated. It is done by a process called Dynamic Client Update (DCU). For more info on this topic please refer to Dynamic Client Update.

How to disable root/debug detection

You may want to disable root or debug detection (or both), for example during your development process. The SDK uses the Context.getPackageName() method to search for a class called {your.application.package}.SecurityController. The class should contain two public static boolean fields named debugDetection and/or rootDetection, for example:

package com.onegini.mobile.android.demo;

public final class SecurityController {
  public static final boolean debugDetection = false;
  public static final boolean rootDetection = false;
}

This way you can temporarily disable both security controls.

In case you use product flavours and dynamically change the applicationId using applicationIdSuffix it might be that the SecurityController class cannot be found by the SDK. In that case you need to manually specify the location of the SecurityController class. You can do that by using the OneginiClientBuilder#setSecurityController() method. Below you can find a code example.

  private static OneginiClient buildSDK(final Context context) {
    final Context applicationContext = context.getApplicationContext();
    final CreatePinRequestHandler createPinRequestHandler = new CreatePinRequestHandler(applicationContext);
    final PinAuthenticationRequestHandler pinAuthenticationRequestHandler = new PinAuthenticationRequestHandler(applicationContext);

    // will throw OneginiConfigNotFoundException if OneginiConfigModel class can't be found
    return new OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
        .setSecurityController(SecurityController.class)
        .build();
  }

Please note, that the SecurityController can't be obfuscated. Otherwise the SDK won't be able to find it. If you want to use SecurityController in an obfuscated app, you should add a proper "keep" rule, for example:

-keep class com.onegini.mobile.android.demo.SecurityController { *; }