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.
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.
Minimum Requirements
- SDK Minimum Version 21
- Kotlin Minimum Version: 1.8.22
- Java Minimum Version: 17
- 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="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-feature android:name="android.hardware.location.gps" />
<uses-feature android:name="android.hardware.location" />
PERMISSION | USAGE STATUS |
---|---|
USE_BIOMETRIC | REQUIRED |
READ_GSERVICES | REQUIRED |
ACCESS_WIFI_STATE | REQUIRED |
ACCESS_NETWORK_STATE | REQUIRED |
ACCESS_COARSE_LOCATION | REQUIRED |
ACCESS_FINE_LOCATION | OPTIONAL |
Integration Steps
At its core, the solution functions through three straightforward steps:
- Start by embedding Device Intelligence SDK with your mobile application.
- 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.
- 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.
sessionKey
anduserid
are generated / retrieved by the client backend and sent to your application- Your mobile application initialises our SDK through the
init
function by setting these attributes -- Session ID (mandatory unique UUID)
- User ID (optional)
- Flow (optional)
- Invoke the
submit
function in SDK to pass the data to Bureau backend. - Upon successful submission of the parameters, a
callback
is received in the SDK. The next steps can be taken based on thecallback
(success/failure). - If the callback is successful, your mobile application relays the
success
to your backend - Invoke Bureau's backend API
/v1/suppliers/device-fingerprint
to fetch insights- Input :
sessionId
- Input :
- 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.3.3
dependencies {
//add the following dependency in your gradle file
implementation 'id.bureau:corelib:2.3.3'
}
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,
SESSION_ID, //mandatory
Environment.ENV_SANDBOX,
)
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.
Device Intelligence API Document.
API Requests
The URL to Bureau's API service is either:
- Sandbox - https://api.sandbox.bureau.id/v1/suppliers/device-fingerprint
- Production - https://api.bureau.id/v1/suppliers/device-fingerprint
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.sandbox.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.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": "Altantis",
"country": "Persia",
"latitude": 76.1212,
"longitude": 99.29292,
"region": "Atlantis"
},
"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,
"behaviouralRiskLevel": "UNKNOWN",
"confidenceScore": 100,
"createdAt": 1712573578096,
"debuggable": false,
"developerMode": false,
"deviceRiskLevel": "MEDIUM",
"deviceRiskScore": 25.56,
"emulator": false,
"factoryResetRisk": "LOW",
"factoryResetTime": null,
"fingerprint": "6db7755c-1232-4f9d-ae1e-52bd952fac68",
"firstSeenDays": 1,
"googlePlayStoreInstall": true,
"isAppCloned": true,
"isAppTampered": null,
"isDebuggingEnabled": false,
"isHookingDetected": true,
"isOEMUnlockAllowed": false,
"isSimPresent": true,
"merchantId": "org_4KRtxKTsONjo",
"mitmAttackDetected": false,
"mockgps": false,
"model": "A063",
"networkInformation": {
"ipType": "HOME",
"isp": "Atria Convergence Technologies Pvt. Ltd."
},
"package": "id.bureau.sdkdemo",
"remoteDesktop": false,
"requestId": "e2c6bc4a-0054-4c2d-9b1b-8eec8cd42964",
"riskCauses": [
"IS_APP_CLONED"
],
"riskLevel": "MEDIUM",
"riskScore": 25.56,
"rooted": false,
"sessionId": "3ad55d53-08be-46d5-8103-a8d0b570d6f5",
"statusCode": 200,
"timestamp": 1712734628699,
"totalUniqueUserId": 5,
"userId": "test",
"voiceCallDetected": false
}
{
"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
}
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 Attributes | Description |
---|---|
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. |
IP | IP address of the user. |
VPN | Boolean 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). |
isCrawler | Boolean Flag to indicate if the IP being used by the user is associated with a crawler. |
isProxy | Boolean Flag to indicate if the IP being used by the user is a proxy. |
isTor | Boolean Flag to indicate if the IP being used by the user is of a Tor network. |
threatLevel | The threat level associated with the IP. Possible values can be ["low", "medium", "high"] |
IPType | The type of IP, ["v4", "v6"] |
OS | The OS of the user's device. |
developerMode | Boolean Flag to indicate if the user has turned on developer options on their android OS |
accessibilityEnabled | Boolean Flag to indicate if the user has turned on the accessibility feature on android |
adbEnabled | Boolean Flag to indicate if the user enabled the android debugger bridge with the phone connecting the laptop and mobile |
debuggable | Boolean Flag to indicate if the app is in debug mode. |
emulator | Boolean Flag to indicate if the app is being run on an emulator. |
fingerprint | A hash generated for the device, this identifier will be unique for a device. |
firstSeenDays | The number of days from which the device is identified on Bureau's network. |
isAppCloned | Boolean Flag to indicate if the app is cloned. |
isAppTampered | Boolean Flag to indicate if the app is tampered. |
mitmAttackDetected | Boolean Flag to indicate if the payload has been intercepted. |
mockgps | Boolean Flag to indicate if the user is spoofing their GPS location. This will need users permission for background location. |
model | The device model. |
package | The package name. |
rooted | Boolean Flag to indicate if the device is rooted. |
remoteDesktop | Boolean Flag to indicate whether a remote desktop monitoring session is detected |
voiceCallDetected | Boolean Flag to indicate if a voice call was active when device data was collected |
googlePlayStoreInstall | Boolean Flag to Indicate if the app was installed from playstore or out of playstore |
isOEMUnlockAllowed | Boolean Flag to indicate if the user's device has enabled unlocking of the original software build |
isSimPresent | Boolean Flag to indicate if the user's device has SIM present in any slot |
sessionId | The session identifier, that was used to invoke the SDK. |
riskLevel | Alternative 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. |
riskScore | Alternative scoring models that uses data derived from the above raw signals. |
userId | The userID that was sent as part of the request body. |
totalUniqueUserId | The total number of unique usersIDs associated to the fingerprint. |
confidenceScore | The confidence score of the generated fingerprint. |
Updated 1 day ago