Android Native SDK

This SDK has the capabilities related to device intelligence and behavioural biometrics

Minimum Requirements

  • minSdkVersion 21
  • AndroidX
  • The XML below is a representation of the permissions required. Please refer to the table below.
PERMISSIONUSAGE STATUS
USE_BIOMETRICREQUIRED
READ_GSERVICESREQUIRED
ACCESS_WIFI_STATEREQUIRED
ACCESS_NETWORK_STATEREQUIRED
ACCESS_COARSE_LOCATIONREQUIRED
ACCESS_FINE_LOCATIONOPTIONAL
  <uses-permission android:name="android.permission.USE_BIOMETRIC" />
  <uses-permission android:name="android.permission.USE_FINGERPRINT" />
  <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  <uses-feature android:name="android.hardware.location.gps" />
  <uses-feature android:name="android.hardware.location" />

Integration Steps

Flow Diagram

This diagram shows the interactions between your mobile app and Bureau's SDK.

  1. sessionID, userid and flow are made available to your frontend application (preferable from the backend where required).
  2. Call the BureauAPI.getBureauApiInstance()function with the parameters ( need to call this initiate in onCreate() of application class)
    1. sessionId - MANDATORY
    2. credentialId - MANDATORY
    3. environment - MANDATORY - default is production
    4. applicationInstance - MANDATORY - java class application
  3. Call the setters functions for the below mandatory parameters
    1. UserID - setUserId - meant to be unique to a user e.g. hashed value of a PAN number or SSN or hash of mobile number
    2. Flow - setFlow - only allowed value is LOGIN_AUTHENTICATION - no other values are allowed
  4. If you want to collect behavior signals, then do the following-
    1. Call startSubSession to commence the collection of raw behavior data points
    2. Call stopSubSessionto end the collection of raw behavior data points
    3. Ideally, a typical flow would to start collecting after the launch of the application and stop collecting after the login or sign-in button is pressed when the user enters the username and password
  5. Finally, call the submit function to send the device and behavior data points for processing
    1. Call submitfunction
  6. A callback is received in the SDK upon successful submission of the parameters. The next steps can be taken based on the callback (success/failure)
  7. After receiving a successful callback, invoke Bureau's backend API /v2/services/behaviour-device-insights to fetch behavior and device intelligence results such as device fingerprint ID, user similarity score, and bot score.

Step 1 - SDK Implementation

Add the following lines in your root build.gradle

Properties properties  = new Properties()
properties.load(new FileInputStream(project.rootProject.file('local.properties')))
buildscript {
.....
}
allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://packages.bureau.id/api/packages/Bureau/maven" }
    }
}

Latest Version

Add the following lines in your module-level build.gradle.

The latest version is 2.3.8

dependencies {
//add the following dependency in your gradle file
    implementation 'id.bureau:corelib:2.3.8'
}

This library also uses some common Android libraries. So if you are not already using them, then add these libraries to your module-level build.gradle

  • androidx.appcompat:appcompat:1.2.0

Step 2 - Initialise SDK

The SDK is initialized in the client app. Once the submit function is called, the data relating to the user and device is automatically synced in the background.

//Get SDK Instance with Client Id and Environment
val sessionId = UUID.randomUUID().toString()
val bureauAPI : BureauAPI  = BureauAPI.getBureauApiInstance(
            this,
            YOUR_CLIENT_ID,
            sessionId,
            Environment.ENV_SANDBOX,
            true // true if you want to enable behavioral biometrics, default is false
        ) // need to call this initiate in onCreate() of application class

						val subSessionId = UUID.randomUUID().toString()
            bureauAPI.startSubSession(subSessionId) //call this to start collecting behavior biometrics signals
            
            bureauAPI.stopSubSession() //call this to stop collecting behavior biometrics signals
            
            bureauAPI.setFlow(YOUR_FLOW_NAME)//mandatory
            
            bureauAPI.setUserId(YOUR_USER_ID)//mandatory

//submit device and behavior(if enabled) data to Bureau's backend using the submit function
            bureauAPI.submit(object :
                DataCallback {
                override fun onError(errorMessage: ErrorResponse) {
                  
                }

                override fun onResult(message: SubmitResponse) {
                  
                }
            })
//Get SDK Instance with Client Id and Environment
BureauAPI bureauAPI = BureauInstanceProvider.getBureauApiInstance(context, "YOUR_CLIENT_ID", Environment.ENV_PRODUCTION);
bureauAPI.setSessionId("YOUR_SESSION_ID");  //Mandatory
bureauAPI.setFlow("your_flow_name");  //optional
bureauAPI.setUserId("your_user_id");  //optional

//Start collecting and submit data to Bureau's backend using the submit function
bureauAPI.submit((new DataCallback() {
   public void onError(@NotNull ErrorResponse errorMessage) {
       //implement your own logic
   }

   public void onResult(@NotNull SubmitResponse message) {
       //implement your own logic
   }
}));

πŸ“˜

Note

  • To initialise the SDK we need to provide CREDENTIAL_ID.
  • Session ID i.e. is mandatory and unique for each submission.
  • To obtain the fingerprint Id query Bureau backend.
  • The default environment is production. If you want to run on UAT pass ENV_SANDBOX in getBureauApiInstance function.

Response returned from the SDK

The DataCallback added in the Submit function returns whether the device data has been registered or not.

object :DataCallback{
            override fun onError(errorMessage: ErrorResponse) {
               //Failure Callback
               Log.w(TAG,"Error "+errorMessage)
            }

            override fun onResult(message: SubmitResponse) {
                //Success Callback
                Log.w(TAG,"Success "+message)
            }
        }}
bureauAPI.submit((new DataCallback() {
   public void onError(@NotNull ErrorResponse errorMessage) {
       //implement your own logic
   }

   public void onResult(@NotNull SubmitResponse message) {
       //implement your own logic
   }
}));

Step 3 - Invoke API for Insights

To access insights from users and devices, including device fingerprint, and risk signals, integrating with Bureau's backend API for Device Intelligence insights.

Sample Request and Response

Below is a sample request and response for our Device Intelligence API. Refer to our Behavior Biometrics API documentation for more details.

Contact our support team at [email protected] to get your API keys and the production endpoint for the API.

curl --location --request POST 'https://api.sandbox.bureau.id/v1/suppliers/device-fingerprint' \
--header 'Authorization: Basic MzNiNxxxx2ItZGU2M==' \
--header 'Content-Type: application/json' \
--data-raw '{
    "sessionKey": "697bb2d6-1111-1111-1111-548d6a809360"
}'

{
  "GPSLocation": {
    "city": "",
    "country": "",
    "latitude": 0,
    "longitude": 0,
    "region": ""
  },
  "IP": "106.51.82.180",
  "IPLocation": {
    "city": "Bengaluru",
    "country": "India",
    "latitude": 12.976229667663574,
    "longitude": 77.60328674316406,
    "region": "Karnataka"
  },
  "IPSecurity": {
    "VPN": false,
    "isCrawler": false,
    "isProxy": false,
    "isTor": false,
    "threatLevel": "LOW"
  },
  "IPType": "v4",
  "OS": "android",
  "accessibilityEnabled": false,
  "adbEnabled": false,
  "behaviouralFeatures": {
    "autofillActivity": "LOW",
    "backgroundAppPushActivity": "LOW",
    "copyPasteActivity": "LOW",
    "fieldFocusActivity": "LOW",
    "sessionDurationInMS": 596908510,
    "swipeActivityDetected": false
  },
  "behaviouralRiskLevel": "MEDIUM",
  "behaviouralRiskScore": 26.79,
  "botDetectionScore": 0,
  "confidenceScore": 20,
  "createdAt": 1712648006459,
  "debuggable": true,
  "developerMode": false,
  "deviceRiskLevel": "VERY_HIGH",
  "deviceRiskScore": 81.51,
  "emulator": false,
  "factoryResetRisk": "LOW",
  "factoryResetTime": null,
  "fingerprint": "68055d2e-4811-45db-a298-cb4ff17eb2c8",
  "firstSeenDays": 12,
  "googlePlayStoreInstall": false,
  "isAppCloned": true,
  "isAppTampered": null,
  "isDebuggingEnabled": null,
  "isOEMUnlockAllowed": null,
  "isSimPresent": null,
  "isTrainingSession": false,
  "merchantId": "auth0|623980a33d162b006930a877",
  "mitmAttackDetected": false,
  "mockgps": false,
  "model": "SM-M326B",
  "networkInformation": {
    "ipType": "HOME",
    "isp": "Atria Convergence Technologies Pvt. Ltd."
  },
  "package": "id.bureau.deviceintelligence",
  "remoteDesktop": false,
  "requestId": "0a55480c-faf0-44a7-a9e3-fe3353e34214",
  "riskCauses": [
    "DEBUGGER",
    "IS_APP_CLONED"
  ],
  "riskLevel": "VERY_HIGH",
  "riskScore": 65.094,
  "rooted": false,
  "sessionId": "f70a2b7d-dd75-4075-9ba1-ee4ee2e20b5a",
  "statusCode": 200,
  "timestamp": 1713427163350,
  "totalUniqueUserId": 3,
  "userId": "sriram",
  "userSimilarityScore": 23.924109706617298,
  "voiceCallDetected": false
}

Verifying App Integrity with Signature Hash

Before going live, we must ensure your app hasn't been tampered with. This helps protect both you and your users.

Here's how you can verify your app's integrity:

Gather Information

  • Package Name: This is the unique identifier for your app on the platform (e.g., com.yourcompany.myapp). It typically follows a reverse domain name structure, such as:
    • com.<yourcompany>.<appname>
    • com.<yourcompany>.<appname>:<servicename> (if using sub-organizations)
  • Signature Hash Code: This code is generated from your app's signing certificate and helps verify its authenticity.

Get the Signature Hash Code

Most development environments provide built-in tools for obtaining the signature hash code. Below is a common way (using the GET_SIGNING_CERTIFICATES permission):

  • Access your project's settings in the PackageManager.
  • Look for the permission section and ensure you have the GET_SIGNING_CERTIFICATES permission enabled.
  • Once enabled, follow the specific instructions provided by your development environment to retrieve the signature hash code. It's usually found within a property like signingInfo.signingCertificateHistory and will be a byte array representation of the hash.

You can also retrieve the signature hash using the below code snippet (refer to your development environment's documentation for specific implementation details).

πŸ“˜

Note

This is a code example, and the actual implementation might differ based on your development environment.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    context.packageManager.getPackageInfo(
        context.packageName,
        PackageManager.GET_SIGNING_CERTIFICATES,
    ).signingInfo.signingCertificateHistory
} else {
    context.packageManager
        .getPackageInfo(
            context.packageName,
            PackageManager.GET_SIGNATURES,
        ).signatures
}
  • The above code snippet checks the Android SDK version to determine the appropriate method for retrieving the signature information.
  • For Android versions 9 (Pie) and above, it uses getPackageInfo with the GET_SIGNING_CERTIFICATES flag and accesses the signingCertificateHistory property.
  • For older versions, it uses getPackageInfo with the GET_SIGNATURES flag and accesses the signatures property.

Share the Information

Once you have your package name and signature hash code, please share them with us before launching your app live. This allows us to verify the app's authenticity and protect both you and your users.