Android Native

Welcome to our android native plugin designed to seamlessly integrate with the Bureau's Device Intelligence, enhancing the functionality of mobile apps or webpages.

Overview: Device Intelligence

Our Device Intelligence module empowers you to gain comprehensive insights into your users by meticulously gathering data on their devices. This data serves as the foundation for creating a distinctive identifier for each user, known as a device fingerprint. The device fingerprint not only enables user identification but also facilitates the tracking of user activities across various sessions.

Key Features:

Seamless Integration: Effortlessly incorporate the plugin into your existing applications, ensuring a smooth and unobtrusive user experience.

Anti-Fraud Accuracy: Benefit from our solution's exceptional anti-fraud capabilities, safeguarding your platform against potential threats while maintaining accuracy and reliability.

Trusted Device View: Obtain a reliable view of trusted devices, allowing you to make informed decisions without compromising user interactions.

Getting Started:

To integrate our native SDK into your project, follow the comprehensive documentation provided below. Ensure a seamless implementation and unlock the full potential of Device Intelligence for your application.


Getting Started

Minimum Requirements

  • minSdkVersion 21
  • AndroidX
  • The XML below is a representation of the permissions required. Please refer to the table below.
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <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" /> //OPTIONAL
  <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-permission android:name="android.permission.ACCESS_GPS" />

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

  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> //OPTIONAL
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> //OPTIONAL
  <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  <uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
PERMISSIONUSAGE STATUS
USE_BIOMETRICREQUIRED
USE_FINGERPRINTREQUIRED
READ_GSERVICESREQUIRED
ACCESS_WIFI_STATEREQUIRED
ACCESS_NETWORK_STATEREQUIRED
ACCESS_GPSREQUIRED
CHANGE_WIFI_STATEREQUIRED
SYSTEM_ALERT_WINDOWREQUIRED
ACTION_MANAGE_OVERLAY_PERMISSIONREQUIRED
CHANGE_NETWORK_STATEREQUIRED
MANAGE_EXTERNAL STORAGEOPTIONAL
ACCESS_COARSE_LOCATIONREQUIRED
ACCESS_FINE_LOCATIONOPTIONAL

Integration Steps

At its core, the solution functions through three straightforward steps:

  1. Start by embedding Device Intelligence SDK with your mobile application.
  2. Initialize the SDK using either the Client ID or Credential ID. This enables us to gather user and device data. We will then thoroughly analyze and enhance the collected data in the background.
  3. You can then utilize our API to access insights, aiding you in deciding the subsequent actions for your user, whether it's permitting, obstructing, or redirecting them.

Flow Diagram

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

  1. sessionKey and userid are generated / retrieved by the client backend and sent to your application
  2. Your mobile application initialises our SDK through the init function by setting these attributes -
    1. Session ID (mandatory unique UUID)
    2. User ID (optional)
    3. Flow (optional)
  3. Invoke the submit function in SDK to pass the data to Bureau backend.
  4. Upon successful submission of the parameters, a callback is received in the SDK. The next steps can be taken based on the callback (success/failure).
  5. If the callback is successful, your mobile application relays the success to your backend
  6. Invoke Bureau's backend API /v1/suppliers/device-fingerprint to fetch insights
    1. Input :sessionId
  7. Based on the insights provided (fingerprint, and risk signals), you can determine the next steps for the user, such as allowing, blocking, or redirecting them.

Step 1 - SDK Implementation

Add 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 following lines in your module level build.gradle.

The latest version is 2.1.1

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

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

  • androidx.appcompat:appcompat:1.2.0

Step 2 - Initialise SDK

The SDK is initialised in the client app.

import com.bureau.devicefingerprint.BureauAPI
import com.bureau.base.Environment

//Get SDK Instance with Client Id and Environment
val bureauAPI : BureauAPI  = BureauAPI.getBureauApiInstance(
            this,
            YOUR_CLIENT_ID,
            Environment.ENV_SANDBOX,
        ) 
        		bureauApi.setSessionId(SESSION_ID)//mandatory

						bureauAPI.setFlow(YOUR_FLOW_NAME)//mandatory
            
            bureauAPI.setUserId(YOUR_USER_ID)//mandatory

import com.bureau.devicefingerprint.BureauAPI
import com.bureau.base.Environment

//Get SDK Instance with Client Id and Environment
String sessionId = UUID.randomUUID().toString()
BureauAPI bureauAPI  = BureauAPI.getBureauApiInstance(
            this,
            YOUR_CLIENT_ID,
            Environment.ENV_SANDBOX
        ) 
        
        		bureauApi.setSessionId(SESSION_ID)//mandatory

						bureauAPI.setFlow(YOUR_FLOW_NAME)//mandatory
            
            bureauAPI.setUserId(YOUR_USER_ID)//mandatory
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.

Step 3 - Submit SDK

Once the submit function is called, the data relating to the user and device is automatically synced in the background.

import com.bureau.devicefingerprint.models.ErrorResponse
import com.bureau.devicefingerprint.models.SubmitResponse
import com.bureau.devicefingerprint.tools.DataCallback

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

                override fun onResult(message: SubmitResponse) {
                  
                }
            })
import com.bureau.devicefingerprint.models.ErrorResponse
import com.bureau.devicefingerprint.models.SubmitResponse
import com.bureau.devicefingerprint.tools.DataCallback

//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
   }
}));

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 4 - 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.

Please find below the link to the respective API documentations:

Device Intelligence - https://docs.bureau.id/reference/device-intelligence

API Requests

The URL to Bureau's API service is either:

Authentication

API's are authenticated via an clientID and secret, they have to be base64 encoded and sent in the header with the parameter name as Authorisation.

Authorisation : Base64(clientID:secret)

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

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

API Response

Bureau's Backend API will return one of the following HTTP status codes for every request:

{
  "GPSLocation": {
    "city": "Bengaluru",
    "country": "India",
    "latitude": 51.5207,
    "longitude": -0.1550,
    "region": "Karnataka"
  },
  "IP": "49.207.195.96",
  "IPLocation": {
    "city": "Bengaluru",
    "country": "India",
    "latitude": 51.5207,
    "longitude": -0.1550,
    "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": 1043550,
    "swipeActivityDetected": false
  },
  "behaviouralRiskLevel": "LOW",
  "behaviouralRiskScore": 0,
  "botDetectionScore": 0,
  "confidenceScore": 20,
  "createdAt": 1705596471168,
  "debuggable": true,
  "developerMode": false,
  "deviceRiskLevel": "VERY_HIGH",
  "deviceRiskScore": 86.58,
  "emulator": false,
  "fingerprint": "e8d99e90-7a5b-4139-aa4a-86af09e48162",
  "firstSeenDays": 18,
  "googlePlayStoreInstall": false,
  "isAppCloned": true,
  "isAppTampered": null,
  "isTrainingSession": false,
  "merchantId": "auth0|623980a33d162b006930a877",
  "mitmAttackDetected": false,
  "mockgps": false,
  "model": "SM-M326B",
  "networkInformation": {
    "ipType": "HOME",
    "isp": "Jon Doe Pvt Ltd"
  },
  "package": "id.XXX.deviceintelligence",
  "remoteDesktop": true,
  "requestId": "SqzZaF0XBcwEfVw=",
  "riskLevel": "VERY_HIGH",
  "riskScore": 60.605999999999995,
  "rooted": false,
  "sessionId": "e0a0406c-2547-4400-b0f8-2d379b3e54bf",
  "statusCode": 200,
  "timestamp": 1707147119206,
  "totalUniqueUserId": 2,
  "userId": "Jon Doe",
  "userSimilarityScore": 71.630401063247,
  "voiceCallDetected": true
}
{
    "statusCode": 400,
    "error": {
        "code": 0,
        "type": "BAD_REQUEST",
        "message": "Session key is missing",
        "description": "request does not contain additionalData.sessionKey param in request",
        "referenceId": "24f94ae8-xxxx-48a4-xxxx-b25f99fb06d9",
        "metadata": null
    },
    "timestamp": 1658402143450,
    "merchantId": "auth0|61dfbbxxxx3420071be7021",
    "requestId": "66403193-xxxx-44bc-xxxx-14735a45dfeb"
}
{
  "data": null,
  "errors": {
    "status": 401,
    "errorCode": "UNAUTHORIZED",
    "service": "Overwatch"
  },
  "message": "",
  "meta": {
    "length": 0,
    "took": 0,
    "total": 0
  }
}
{
    "error": {
        "code": 422,
        "description": "Failed to find fingerprint for given session key",
        "message": "NO_RECORD_FOUND",
        "metadata": null,
        "referenceId": "",
        "type": "NO_RECORD_FOUND"
    },
    "merchantId": "auth0|61dfbbxxxx420071be7021",
    "requestId": "24e1aa7f-xxxx-404d-xxxx-5f8a0227e8f0",
    "statusCode": 422,
    "timestamp": 1658402132141
}
{
  "error": {
    "code": 0,
    "description": "",
    "message": "Server encountered an error",
    "metadata": null,
    "referenceId": "86529a18-a5cb-4da9-91b0-8d04cdb9167e",
    "type": "INTERNAL_SERVER_ERROR"
  },
  "merchantId": "auth0|61dfxxxx0071be7021",
  "requestId": "c69d86f0-xxxx-4ef0-xxxx-e687d595a507",
  "statusCode": 500,
  "timestamp": 1657009043753
}

Responses

HTTP Status Code Description

The Bureau's Backend API attempts to return the appropriate HTTP status code for every request. The following table illustrates the possible status codes and their meanings:

Status CodeStatus SummaryDescription
200Successful RequestThe request succeeded.
400Bad RequestRequest is not well-formed, syntactically incorrect, or violates schema. The server could not understand the request. Indicates one of these conditions:
1. The API cannot convert the payload data to the underlying data type.
2. The data is not in the expected data format.
3. A required field is not available.
4. A simple data validation error occurred.
401UnauthorisedThe server rejected the request because authentication credentials provided was not valid.
422No Record FoundThe API can't carry out the requested action to get the fingerprint generated from the provided Session Key or Session ID. It's possible that the sent Session Key or Session ID is incorrect.
500Internal Server ErrorA problem happened with the system or application. Even though the client's request seems right, something unexpected took place on the server.

Insight Response Descriptions

Bureau's Device Intelligence solution combines device and behavioral data to identify devices using fingerprints. With the application of Bureau's proprietary signal detection and fraud risk model, you can use these data to adeptly unveil and thwart fraudulent activities.

Signal AttributesDescription
GPSLocation(city, country, latitude, longitude, region)GPS Based location of the user's device. User's consent is required to be taken to get this details.
IPLocation(city, country, latitude, longitude, region)IP based location of the user.
IPIP address of the user.
VPNBoolean Flag to indicate if the IP being used by the user is a VPN. (Note the VPN within the IPSecurity JSON object should be used and not the one outside).
isCrawlerBoolean Flag to indicate if the IP being used by the user is associated with a crawler.
isProxyBoolean Flag to indicate if the IP being used by the user is a proxy.
isTorBoolean Flag to indicate if the IP being used by the user is of a Tor network.
threatLevelThe threat level associated with the IP. Possible values can be ["low", "medium", "high"]
IPTypeThe type of IP, ["v4", "v6"]
OSThe OS of the user's device.
developerModeBoolean Flag to indicate if the user has turned on developer options on their android OS
accessibilityEnabledBoolean Flag to indicate if the user has turned on the accessibility feature on android
adbEnabledBoolean Flag to indicate if the user enabled the android debugger bridge with the phone connecting the laptop and mobile
googlePlayStoreInstallBoolean Flag to indicate if the app has been installed outside of the Google Playstore
debuggableBoolean Flag to indicate if the app is in debug mode.
emulatorBoolean Flag to indicate if the app is being run on an emulator.
fingerprintA hash generated for the device, this identifier will be unique for a device.
firstSeenDaysThe number of days from which the device is identified on Bureau's network.
isAppClonedBoolean Flag to indicate if the app is cloned.
isAppTamperedBoolean Flag to indicate if the app is tampered.
mitmAttackDetectedBoolean Flag to indicate if the payload has been intercepted.
mockgpsBoolean Flag to indicate if the user is spoofing their GPS location. This will need users permission for background location.
modelThe device model.
packageThe package name.
rootedBoolean Flag to indicate if the device is rooted.
remoteDesktopBoolean Flag to indicate whether a remote desktop monitoring session is detected
voiceCallDetectedBoolean Flag to indicate if a voice call was active when device data was collected
sessionIdThe session identifier, that was used to invoke the SDK.
riskLevelAlternative scoring models that incorporates data that is derived from the above raw signals. The possible values for the score are Low, Medium, High, and Very High.
riskScoreAlternative scoring models that uses data derived from the above raw signals.
userIdThe userID that was sent as part of the request body.
totalUniqueUserIdThe total number of unique usersIDs associated to the fingerprint.
confidenceScoreThe confidence score of the generated fingerprint.

Go-live Checklist

To determine if your app has been tampered with, we will need your package name and signature hash code. Please share this information with us before going live.

The hash code can be obtained from the PackageManager using the GET_SIGNING_CERTIFICATES permission. The signingInfo.signingCertificateHistory property will return a byte array containing the hash code.