SDK Reference
Everything you need to integrate keystroke biometrics into your application — from a single npm install to a full native C++ embedding.
Overview
TrueStroke SDK Reference
TrueStroke is a cross-platform C++17 behavioral biometric SDK that identifies users by their unconscious keystroke rhythm. It runs entirely on-device with sub-millisecond inference, detects account takeover the moment it happens, and never sends raw biometric data anywhere.
The SDK provides three API surfaces: a C++ API for native integrations, a stable C ABI for cross-language FFI, and a TypeScript wrapper for browser usage via WASM.
Quick Start
Get up and running in minutes
Prerequisites
- C++17 compiler (Clang 14+, GCC 10+, MSVC 2019+)
- CMake 3.16+
- Optional: Emscripten SDK for WASM builds
- Optional: Node.js 18+ for TypeScript
Build the SDK
cd sdk
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)Run Tests
cd sdk/build
ctest --output-on-failure
# All 10 test suites pass:
# test_ring_buffer ......... Passed
# test_feature_extractor ... Passed
# test_isolation_forest .... Passed
# test_mahalanobis ......... Passed
# test_crypto .............. Passed
# test_liveness ............ Passed
# test_engine .............. Passed
# test_federated ........... Passed
# test_c_api ............... Passed
# test_differentiation ..... PassedBuild for WASM
cd wasm
chmod +x build.sh
./build.sh
# Produces dist/truestroke.js and dist/truestroke.wasmTypeScript / Browser API
@truestroke/core npm package
Installation
npm install @truestroke/coreBasic Usage
import { TrueStroke } from '@truestroke/core';
const ts = await TrueStroke.init({ userId: 'user_123' });
// Attach to any input element (auto-captures keystrokes)
ts.attachTo(document.querySelector('#my-input'));
// Or feed events manually
document.addEventListener('keydown', (e) => ts.feedKeyDown(e.code, e.timeStamp));
document.addEventListener('keyup', (e) => ts.feedKeyUp(e.code, e.timeStamp));
// Listen for anomalies
ts.onAnomaly((event) => {
console.log(`Imposter detected: confidence=${event.confidence}`);
showReauthPrompt();
});
// Reactive listeners
ts.onConfidenceChange((c) => updateConfidenceUI(c));
ts.onStatusChange((s) => updateStatusBadge(s));
// Liveness detection
const liveness = ts.checkLiveness();
// { isLive, isReplay, entropy, jitterPower, wpm, dwellCV, score }
// Federated learning
const gradients = ts.exportGradients();
await fetch('/api/v1/gradients', { method: 'POST', body: gradients });
// Profile
ts.saveProfile();
ts.wipeProfile(); // GDPR-compliant erasure
ts.destroy(); // CleanupTrueStrokeConfig
| Property | Type | Description | Default |
|---|---|---|---|
userId | string | Unique user identifier | required |
windowSize | number | Keystrokes per feature window | 30 |
windowStride | number | Stride between windows | 15 |
lockThreshold | number | Confidence below this triggers lock | 0.35 |
enrollMinKeystrokes | number | Min keystrokes for early scoring | 50 |
enrollFullKeystrokes | number | Keystrokes for full enrollment | 200 |
encryptProfiles | boolean | Encrypt profiles with XChaCha20 | true |
wasmUrl | string | Custom path to .wasm file | auto |
AnomalyEvent
| Property | Type | Description | Default |
|---|---|---|---|
confidence | number | Current confidence score [0.0, 1.0] | — |
windowSize | number | Number of keystrokes in scoring window | — |
timestamp | number | Event timestamp in microseconds | — |
LivenessResult
| Property | Type | Description | Default |
|---|---|---|---|
isLive | boolean | Whether human typing is detected | — |
isReplay | boolean | Whether a replay attack is detected | — |
entropy | number | Shannon entropy of timing distribution | — |
jitterPower | number | Goertzel DFT jitter power | — |
wpm | number | Typing speed in words per minute | — |
dwellCV | number | Coefficient of variation of dwell times | — |
score | number | Combined liveness score | — |
C++ API
Native integration via ts::Engine
#include <truestroke/truestroke.h>
// Create and initialise engine
ts::Engine engine;
ts::Config cfg;
cfg.lockThreshold = 0.35f;
cfg.enrollFullKeystrokes = 200;
engine.init(cfg);
// Begin enrollment
engine.enroll("user_123");
// Feed keystroke events (from platform hooks)
ts::KeyEvent ev;
ev.keyCode = 65; // 'A'
ev.pressTime = 1709000000; // microseconds
ev.releaseTime = 1709050000;
ev.pressure = 0.0f;
engine.feed(ev);
// Query state
float confidence = engine.getConfidence(); // 0.0 to 1.0
ts::Status status = engine.getStatus(); // ENROLLING | MONITORING | LOCKED
// Set anomaly callback
engine.onAnomaly([](const ts::AnomalyEvent& ae) {
std::cerr << "Anomaly: confidence=" << ae.confidence << "\n";
});
// Liveness check
auto lr = engine.checkLiveness();
// lr.isLive, lr.entropy, lr.jitterPower, lr.wpm, lr.isReplay
// Profile management
engine.saveProfile(); // encrypted binary to disk
engine.wipeProfile(); // GDPR-compliant erasure
// Federated learning (optional)
auto gradients = engine.exportGradients();
engine.importGlobalUpdate(serverResponse.data(), serverResponse.size());C API (FFI)
Stable ABI for cross-language integration
The C API enables integration from any language with C FFI support: Python, Go, Java JNI, Kotlin NDK, Swift, Rust, etc.
#include <truestroke/c_api.h>
ts_engine_t* engine = ts_engine_create();
ts_engine_init(engine);
ts_engine_enroll(engine, "user_123");
ts_key_event_t ev = {
.key_code = 65,
.press_time = t0,
.release_time = t1,
.pressure = 0.0f
};
ts_engine_feed(engine, &ev);
float confidence = ts_engine_get_confidence(engine);
// Anomaly callback
void on_anomaly(const ts_anomaly_event_t* event, void* userdata) {
// Handle anomaly
}
ts_engine_on_anomaly(engine, on_anomaly, NULL);
// Cleanup
ts_engine_destroy(engine);Federated Server API
Gradient aggregation with differential privacy
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/v1/gradients | POST | Submit gradient data (binary or base64 JSON) |
/api/v1/model | GET | Download current global model (binary) |
/api/v1/status | GET | Server status, round info, privacy budget |
/api/v1/health | GET | Health check |
Build & Run
cd server
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)
# Run the server
./federated_server --port 8080 --min-clients 5 --epsilon 8.0CLI Options
| Property | Type | Description | Default |
|---|---|---|---|
--port | int | HTTP port | 8080 |
--min-clients | int | Minimum clients per round | 5 |
--max-rounds | int | Maximum training rounds | 100 |
--epsilon | float | DP epsilon budget | 8.0 |
--delta | float | DP delta parameter | 1e-5 |
--clip-norm | float | L2 gradient clip norm | 1.0 |
Configuration
Engine tuning parameters
ts::Config cfg;
cfg.windowSize = 30; // keystrokes per feature window
cfg.windowStride = 15; // stride (50% overlap)
cfg.eifTrees = 100; // forest size
cfg.eifSubsampleSize = 256; // sub-sample per tree
cfg.eifMaxDepth = 10; // max tree depth
cfg.mahShrinkage = -1.0f; // <0 = auto Ledoit-Wolf
cfg.mahDecay = 0.01f; // exponential decay for drift
cfg.lockThreshold = 0.35f; // confidence below this = lock
cfg.hysteresisWindows = 3; // consecutive anomalous windows
cfg.enrollMinKeystrokes = 50; // minimum keystrokes for early scoring
cfg.enrollFullKeystrokes = 200; // keystrokes for full enrollment
cfg.encryptProfiles = true; // XChaCha20-Poly1305 at restengine.init(cfg) before enrollment begins. Re-initialising resets the engine state.Privacy Architecture
Privacy-first by design
All inference runs on-device. No keystroke timing, feature vectors, or profile data leaves the device during normal operation.
User profiles are encrypted with XChaCha20-Poly1305 before storage. ~800 MB/s throughput.
Complete erasure of all biometric data with a single API call.
Only differentially-private gradient updates (clipped + noised) are transmitted, never raw data.
Cumulative privacy loss (ε) tracked via Rényi DP composition across rounds.
Platform Support
| Platform | Build Method | Status |
|---|---|---|
| macOS (ARM64) | CMake native | Tested |
| macOS (x86_64) | CMake native | Tested |
| Linux (x86_64/ARM) | CMake native | Tested |
| Windows | CMake + MSVC | Tested |
| Browser (WASM) | Emscripten | Tested |
| Android | NDK + CMake | Planned |
| iOS | Xcode + CMake | Planned |