GaitAuth™ Authentication
Note: The authenticator functionality outlined on this page is currently in experimental beta and the interface to this portion of the SDK may change over time. Current support is for iOS, with Android coming soon.
Using GaitAuth Authenticator
objects, you can automatically collect gait features, score those features, apply authentication logic to the scores, and produce an authenticated
, unauthenticated
, or inconclusive
authentication status.
Authentication configurations are a customizable set of rules that take inputs (like feature scores) and produce an authentication result.
Creating an Authenticator
Before you begin, make sure you’ve set up the SDK and loaded a trained model.
An Authenticator
instance collects data from the device and allows you to query the authentication status at any time. To create a new authenticator, you’ll want to provide a configuration that determines the authentication behavior:
Android
double QUANTILE_THRESHOLD = 0.8; // your desire quantile threshold
GaitQuantileConfig config = new GaitQuantileConfig(QUANTILE_THRESHOLD);
authenticator = GaitAuth.getInstance().createAuthenticator(config, model);
iOS
let authenticator = unifyId.gaitAuth.authenticator(
config: GaitQuantileConfig(
...
),
model: model
)
When an authenticator is created, depending on its configuration, certain processes may begin. For example:
- A gait-based configuration causes feature collection to automatically begin, removing the need to explicitly call
startFeatureUpdates
. - A configuration that uses the device unlock status may begin listening for lock/unlock events.
Authentication Status
The current authentication status can be queried with the status
function. A completion handler should be provided to process the authentication result.
Android
authenticator.getStatus(new AuthenticationListener() {
@Override
public void onComplete(AuthenticationResult authenticationResult) {
// Authentication status obtained
}
@Override
public void onFailure(GaitAuthException e) {
// Failure to querying authentication status
}
});
iOS
authenticator.status { result in
switch result {
case .success(let authenticationResult: AuthenticationResult):
// Authentication status obtained
case .failure(let error: GaitAuthError):
// Failure querying authentication status
}
}
A result of .success
does not necessarily mean that the user should be authenticated. It means that querying for the status was successful. To see the actual authentication result, check authenticationResult.status
, and it should be one of .authenticated
, .unauthenticated
, or .inconclusive
.
In addition to status
, each successful authentication result also has an authenticationResult.context
property which provides additional information about the authentication decision. Depending on the configuration being used, different context values are provided.
The status
can be queried multiple times for an authenticator, and as long as the authenticator
instance is allocated it will continue any processes it has begun (e.g., collecting features or listening for unlock events). To stop these processes, ensure there are no more references to it so it will be de-allocated.
Configurations
Authenticators use configurations, which define the rules for determining authentication status. Configurations can expose options to customize their behavior. Additionally, based on the inputs/signals a configuration uses, an authenticator that uses it may begin certain data collection processes.
Currently, a gait-based quantile configuration and a device authentication configuration are available in the SDK. As new configurations are added, they will be documented below.
Gait Quantile Config
The Gait Quantile Config takes recent feature scores and returns an authenticated
result if splitting the features across numQuantiles
quantiles, all data at or above the nth (n = quantile
) quantile are at or above the score threshold (threshold
). A few examples:
numQuantiles: 100
,quantile: 75
,threshold: 0.5
The result isauthenticated
if the top 25% of scores are at or above 0.5.numQuantiles: 100
,quantile: 20
,threshold: 0.5
The result isauthenticated
if the top 80% of scores are at or above 0.5.numQuantiles: 5
,quantile: 2
,threshold: 0.8
The result isauthenticated
if the top 60% of scores are at or above 0.8.
Create the Authenticator
To create an authenticator
with the quantile configuration, provide a GaitQuantileConfig
and a trained model.
The configuration has the following options:
minNumScores
Minimum number of scores to require. Otherwise,inconclusive
will be returned as the result.maxNumScores
Maximum number of scores to use, ordered by most recent. Additional scores are not used.maxScoreAge
Maximum allowed age for scores, in seconds. Scores older than this limit are not used.numQuantiles
Number of quantiles.quantile
Quantile number to require.threshold
Score threshold to require.
Because a model is needed to score features, a trained/downloaded model is also required. Your complete call will look something like this:
Android
double QUANTILE_THRESHOLD = 0.8;
GaitQuantileConfig config = new GaitQuantileConfig(QUANTILE_THRESHOLD);
config.setMinNumScores(5);
config.setMaxNumScores(50);
config.setMaxScoreAge(300);
config.setNumQuantiles(100);
config.setQuantile(50);
Authenticator authenticator = GaitAuth.getInstance().createAuthenticator(config, gaitModel);
iOS
let authenticator = unifyId.gaitAuth.authenticator(
config: GaitQuantileConfig(
minScores: 5,
maxScores: 50,
maxScoreAge: 300,
numQuantiles: 100,
quantile: 50,
threshold: 0.8,
),
model: model
)
Feature Collection
When an authenticator is created with a GaitQuantileConfig
, feature collection begins, and the features are stored locally in a buffer. Calling status
on the authenticator queries the features in this buffer. No separate call to startFeatureUpdates
is required.
To stop feature collection, ensure there are no more references to the authenticator instance so that it will be de-allocated.
Context
Along with a status
, authentication results also contain a context
property.
Android
In Android, for authenticators created with a GaitQuantileConfig
, the context
is Map<String, Object>
with the following values:
Map<String, Object> context = result.getContext();
// Get Number of features collected and scores
int featureCount = (int) context.get("featuresCount");
// Get list of GaitScore objects
List<GaitScore> scores = (List<GaitScore>) context.get("featureScores");
// Get string explanation for non-authenticated results
if (context.containsKey("reason")) {
String reason = (String) context.get("reason");
}
iOS
In iOS, for authenticators created with a GaitQuantileConfig
, the context
is a dictionary with the following values:
[
"featuresCount": ..., // Number of features collected and scored
"featureScores": [...], // Array of GaitScore objects
"reason": ... // String explanation for non-authenticated results
]
The featuresCount
value represents the number of features scored and used to produce the authentication result. Features older than maxScoreAge
or beyond maxScores
are not included in this count. featureScores
is the array (with length featuresCount
) of GaitScore
objects, each of which includes a date
and value
for each feature.
The reason
value is present only when the authentication result is unauthenticated
or inconclusive
.
Device Authentication Config
The Device Authentication Config produces the following behavior:
authenticated
if the device is currently, or has recently been, unlockedunauthenticated
if the device is currently locked or has not recently been unlockedinconclusive
if a determination cannot be made
Depending on the maxUnlockAge
option, the authenticator either looks at the current state or uses a lookback window.
Create the Authenticator
To create an authenticator
with the device authentication configuration, provide a DeviceAuthenticationConfig
. Unlike the quantile configuration, no model is provided because device authentication does not require it.
The configuration has a single option:
maxUnlockAge
How far back, in seconds, to detect an unlock. If no value is provided, the default behavior is to only consider the current locked/unlocked state. Using a value of60
would allow the authenticator to returnauthenticated
if the device is currently locked, but was unlocked within the last minute.
To create an authenticator that considers only the current state:
Android
long MAX_LOCK_AGE = 60000; // your desire max lock age
DeviceAuthenticationConfig config = new DeviceAuthenticationConfig(MAX_LOCK_AGE);
try {
Authenticator authenticator = GaitAuth.getInstance().createAuthenticator(config);
} catch (GaitAuthException e) {
// Failure to create Authenticator with the provided DeviceAuthenticatorConfig
}
iOS
let authenticator = unifyId.gaitAuth.authenticator(
config: DeviceAuthenticationConfig()
)
Context
Android
In Android, for authenticators created with a DeviceAuthenticationConfig
, the context
is a Map<String, Object>
with the following values:
// Get most recent unlock method
String lastUnlockMethod = (String) context.get("lastUnlockMethod");
// Get most recent unlock date
String lastUnlockDate = (String) context.get("lastUnlockDate");
// Get current lock/unlock state of device
String unlockState = (String) context.get("unlockState");
// Get string explanation for non-authenticated results
if (context.containsKey("reason")) {
String reason = (String) context.get("reason");
}
iOS
In iOS, for authenticators created with a DeviceAuthenticationConfig
, the context
is a dictionary with the following values:
[
"lastUnlockMethod": ..., // Most recent unlock method
"lastUnlockDate": ..., // Most recent unlock date
"unlockState": ..., // Current lock/unlock state of device
"reason": ... // String explanation for non-authenticated results
]
The lastUnlockMethod
is one of passcode
, fingerprint
, face
, or unknown
, and describes how the phone was most recently unlocked. It does not necessarily mean that the phone is currently unlocked. The lastUnlockDate
is the corresponding unlock time.
The unlockState
represents the current unlock state of the device and is one of locked
, unlocked
, or unknown
.
The reason
value is present only when the authentication result is unauthenticated
or inconclusive
.