- Print
- DarkLight
Like our Javascript Tags Deployment, Darwinium's SDK is designed to fit into your existing implementation without the need to call 3rd party APIs from directly within your app - simply append collected profiling data as a header, Dwn-Profiling
to an existing request, and have this processed by an edge step infront of an API, or call the API with this data from your backend.
Option 1: Add a step to your API endpoint to process SDK profiling data automatically
Option 2: Manually process profiling data using a backend call
Initial configuration & Repository Access
Darwinium's iOS and Android SDKs are kept up-to-date using modern package management tools (git, artifactory).
To access this, you will require an API Token. A token can be obtained by going to the Darwinium Portal and clicking Preferences:
Once in the preferences screen, click SDK Access and then click Generate Token
This will provide a username (the same as the username used to access Darwinium) and token. Note these down as they will only appear once.
Setup - Android
Darwinium's Android SDK currently works with API level 33 and above (Android 10.0) per Play Store Guidelines. If you require support for older versions of Android, please contact our team on support@darwinium.com
This guide assumes your project uses Gradle and Kotlin as a language. It will work with Java implementations, although slightly different implementation will be required (beyond the scope of this guide).
Add the Darwinium maven repo
Open settings.gradle
in your project's root, and add the Darwinium maven repo to the dependencyResolutionManagement
section of the file. An example of this full section is shown below:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// Darwinium Maven repository. Variables stored in gradle.properties
maven {
name = 'DarwiniumMavenRepo'
url = "${dwn_maven_url}"
credentials {
username = "${dwn_maven_user}"
password = "${dwn_maven_pwd}"
}
}
}
}
Next, add your credentials (username, API token) to gradle.properties
:
dwn_maven_url=https://packages.darwinium.com/artifactory/dwn-maven/
dwn_maven_user=<your email address>
dwn_maven_pwd=<API Token>
Add the Darwinium SDK as a dependency
Open build.gradle
in your project's root, and add the following under the dependencies
section:
implementation 'com.darwinium:android_sdk:1.14.6+'
Also the following libraries not add as dependencies for darwinium SDK, if you want to detection location or advertising_id, need add the followings in app build.grade
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-ads-lite:20.3.0'
Proguard
if you use Proguard, add the following lines to proguard-rules.pro
-keep class com.darwinium.dwn_sdk.DwnProfilingSDK { public *; }
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
Add SDK profiling into your APP
import the Darwinium SDK using:
import com.darwinium.dwn_sdk.DwnProfilingSDK
Start profiling
It usually makes sense to configure and start profiling on your activity's onCreate()
method. For example:
override fun onCreate(savedInstanceState: Bundle?) {
dwnProfiling.start()
super.onCreate(savedInstanceState)
// ...other view logic
setContentView(R.layout.example_view)
Adding fields for Behavioral Biometrics
Darwinium can profile behavioral biometrics for android Text Views. This is done using the .addTextView(textViewRef, darwiniumContext)
function. For example:
val nameInput = this.findViewById<TextView>(R.id.txtName)
val passwordInput = this.findViewById<TextView>(R.id.txtPassword)
dwnProfiling.addTextView(nameInput, "USER_NAME")
dwnProfiling.addTextView(passwordInput, "PASSWORD")
Collecting/sending profiling data
You will want to provide the intelligence gathered by SDK profiling when an action such when a login API request to your backend occurs. The simplest way of achieving this is to add profile data as a header, Dwn-Profiling
, to your existing request. Consider the following example:
//you can collect profiling at any time.
//this is a base64 encoded string
val fpData = dwnProfiling.collect()
val request = Request.Builder()
.url("https://path/to/your/api")
.post(body)
.addHeader("Dwn-Profiling", fpData)
.build()
Permissions
Darwinium's android SDK is able to use a number of extended permissions to obtain profiling data. These can be edited in AndroidManifest.xml
:
<!-- provides extensive details on phone sim details under profiling.android.sim_info -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<!-- provides fine-grained GPS insights in profiling.android.location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- provides WIFI profiling insights in profiling.android.wifi -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- provides connection insights in profiling.android.connection -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- for advertising id -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<!-- This permission will boost our ability to detect rooted device -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
You can delegate the process of requesting permissions to the SDK using the combination of dwnProfiling.requestPermissions()
and an onRequestPermissionsResult
handler in your activity similar to the following:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
dwnProfiling.processPermissions(requestCode, grantResults)
}
Setup - iOS
Add the Darwinium SDK as a package dependency
The SDK supports both Swift Package Manager (SPM) and CocoaPods.
For SPM, add Darwinium sdk by using the following URL
https://packages.darwinium.com/sdk/dwn_ios_sdk.git
For CocoaPods, add the following lines in the Podfile
pod 'dwn_ios_sdk', :git => 'https://packages.darwinium.com/sdk/dwn_ios_sdk.git', :tag => '<version>'
Darwinium SDK depends on SwiftProtobuf which will be automatically loaded when dwn_ios_sdk loaded
Example: Adding using XCode
Using XCode, Navigate to your project settings and select the Package Dependencies tab:
If using SPM for example, click the "+" button. In the top right-hand side enter the following package URL:
https://packages.darwinium.com/sdk/dwn_ios_sdk.git
You will be prompted for a username and password. Enter the details collected in Initial configuration & Repository Access.
This will provide a package called dwn_ios_sdk. Add this as a dependency, and ensure that your project is selected as a target.
Add profiling boilerplate
Identify a view that you wish to have profiled, and add the following:
import DwnSDK_Framework
Start Profiling
In your view code, create and start your profiling. For example:
struct ContentView: View {
//create an instance of the sdk
private let sdk: DwnProfilingSDK
@StateObject var locationManager = LocationManager()
init () {
//initialize and start profiling
let config: [String: Any] = ["Max Swipes":5, "Max Sensor Count": "150", "SensorCheckInSeconds": 0.1]
sdk = DwnProfilingSDK()
sdk.setConfig(config)
sdk.start()
Adding Fields for Behavioral Biometrics
Darwinium can profile behavioral biometrics for android Text Views. This is done using the .addTextField(placeholder, darwiniumContext)
function. For example:
sdk.addTextField(placeholder: "User name", context: "user_name")
sdk.addTextField(placeholder: "Password", context: "password")
Collecting / Sending profiling data
You will want to provide the intelligence gathered by SDK profiling when an action such when a login API request to your backend occurs. The simplest way of achieving this is to add profile data as a header, Dwn-Profiling
, to your existing request. Consider the following example:
let fpData = sdk.getDwnProfiling()
var request = URLRequest(url: URL(string: "https://path/to/your/api")!,timeoutInterval: Double.infinity)
//append profiling as a header to your existing request
request.addValue(fpData, forHTTPHeaderField: "Dwn-Profiling")
Permissions
Darwinium's iOS profiling is greatly enhanced by enabling AppTrackingTransparency
and CoreLocation (GPS). We do not explicitly request these permissions ourselves, and they must be manually requested through code in your views/ changes to your Info.plist
.
Generate Event including the Profiling Data
After collecting profiling data, the Darwinium risk engine should be invoked. That decodes the profileBlob and returns risk assessment about the user action.
If using an Edge Deployment to generate events, adding the profileBlob to a header dwn-profiling on the existing request to your back end is sufficient. The Darwinium Edge worker will extract the profiling data from the request directly.
If using API to generate events, the profileBlob should be sent to your backend and then included as header dwn-profiling on the API call to Darwinium.
See:
Size of largest profileBlobs typically 4-5kb
- May need to increase permitted header length granted to the request
- If a form POST, dwn-profiling can be included in request body
- The more behavioural biometrics fields mapped, the larger the profileBlob size
Tracking Journeys with the SDK + CDN
You may use a session cookie to join steps as part of a journey, however more often than not mobile APIs will use a different session management method.
It's common for an ephemeral authorization token (such as a JWT or a random string) to be returned to the client from a login call, which will be sent on subsequent events to prove to your backend that your app's user has already logged in.
In order to join steps using SDK with such a session management method, you will need to specify a primary_session_tie
value. This is a unique identifier that is re-used for each subsequent call which indicates to Darwinium that it is the same session. This token may be mapped from any place, including headers, URL or body.
Since it is most common to use an authorization token for this purposes, session_tie attributes are considered PII, to prevent them from being sent un-hashed to Darwinium's backend, or viewed by unprivileged users.
In this example, a journey consists of two POST requests: /login
and /transact
. The first takes a JSON login request with a username (mapped below) and password (not mapped) and on success, returns a JSON body containing a field called sessionId
. This sessionId
field is then sent in the request body of subsequent events to mark this user as already having been authenticated.
Request for /login
:
{
"username": "your name",
}
Response for /login
:
{
"sessionId": "xxxxxxxxxx"
}
Request for /transact
:
{
"sessionId": "xxxxxxxxxx"
}
This journey will ensure that Darwinium treats this entire session as being part of the same journey.
api_version: darwinium.com/api/journey/v1
journey_name: link_device
steps:
- step_name: login
event_type: pre_authentication
proxy_event:
url: /login
host: domain
method: POST
url_match_type: Exact
request:
body_rule:
jsonpath:
- name: $.username
extract_to_attribute: identity['ACCOUNT'].username.username
response:
body_rule:
jsonpath:
- name: $.sessionId
extract_to_attribute: primary_session_tie
- step_name: transaction
proxy_event:
url: /transact
host: sessiontie
method: POST
url_match_type: Prefix
request:
body_rule:
jsonpath:
- name: $.sessionId
extract_to_attribute: primary_session_tie
When you map a session_tie from the response, it will mean that the next event with this value mapped in the request will be considered to be in the same journey. However, it will not resolve to see if this value has been seen before. This is because in practice session tokens contained in the response are almost always newly issued tokens.
Refreshing Session Tie
In your app, there may be a facility to allow a new ephemeral authorization token to be re-issued during the same session. Darwinium can be made aware of this by mapping the old token into the request and the new token into the response.
In this example (following the one above), there is an API to refresh the token called /refresh-token
, which takes the existing ephemeral authorization token in the request and issues the new one in the response (i.e. follows the same format as the request for transact).
The configuration to follow this session and replace the session_tie with a new one is below.
- step_name: transaction
proxy_event:
url: /refresh-token
host: sessiontie
method: POST
url_match_type: Prefix
request:
body_rule:
jsonpath:
- name: $.sessionId
extract_to_attribute: primary_session_tie
response:
body_rule:
jsonpath:
- name: $.sessionId
extract_to_attribute: primary_session_tie
:::
Example Projects
Barebones boilerplate projects are available for both Android and iOS using our git repo. Follow the Initial Configuration and Repository Access guide above to obtain an api token, and checkout the projects below:
Android
git clone https://packages.darwinium.com/sdk/dwn_android_sdk_sample.git
iOS
git clone https://packages.darwinium.com/sdk/dwn_ios_sdk_sample.git