CertiLayerCertiLayer
← Blog
machine-learningproductbehavioral-biometrics

Building a Trust Score: Inside CertiLayer's HCS Model

Youssef Emad·Sep 10, 2026·4 min read

Most bot-detection products expose a single number: a score from 0 to 1 telling you how confident the system is that a session is human. The interesting engineering isn't the number itself — it's everything that has to happen to make that number trustworthy across wildly different kinds of sessions.

This post walks through how CertiLayer's Human Confidence Score (HCS) is built.

The starting point: one modality isn't enough

Early in building this system, it became clear that betting everything on a single behavioral channel is fragile. A model trained purely on mouse movement does well against naive automation but can be pushed against once an adversary specifically targets mouse jitter. A model trained purely on keystroke timing has the same weakness for keyboard-only attacks, and it's blind on touch-only mobile sessions where there's no keyboard activity to measure at all.

The fix is architectural, not just "more data": combine multiple independently-trained models, each specialized on a different behavioral modality, and let their disagreement be informative. If a session looks human on mouse behavior but distinctly non-human on keystroke rhythm, that mismatch is itself a signal worth weighting — a single end-to-end model tends to average that mismatch away instead of surfacing it.

The 34-feature schema

Every session gets encoded across five modalities:

ModalityExample features
Keyboarddwell time, flight time, digraph latency
Mousevelocity, acceleration, curvature, micro-corrections
Touchpressure, gesture velocity, multi-touch patterns
Scrollscroll velocity, direction changes, pause points
Navigationtime-on-element, tab/focus transitions, page dwell

Not every session produces every feature — a desktop session has no touch data, a session that never scrolls has sparse scroll features. The pipeline has to handle missing modalities gracefully rather than assuming a complete feature vector, which shapes a lot of the downstream model design.

Three models, one score

The scoring ensemble behind HCS combines outputs from a gradient-boosted classifier trained on the full tabular feature set, and a set of autoencoder-based models trained per modality (keyboard, mouse, touch) to detect anomalous behavioral patterns rather than classify them directly — anomaly detection is valuable here because it can flag behavior that doesn't look like anything in the training distribution at all, including attack patterns that didn't exist when the model was trained.

The final score is a weighted combination: the tabular classifier carries the largest weight since it has the richest joint view of the session, and each modality-specific anomaly signal contributes proportionally to how much that modality is typically observed in legitimate traffic.

```text HCS = w_classifier · P(human | tabular features)

  • w_keyboard · (1 − anomaly_keyboard)
  • w_mouse · (1 − anomaly_mouse)
  • w_touch · (1 − anomaly_touch) ```

Turning a score into a decision

A raw float isn't actionable on its own — it needs thresholds that map to what a product actually does with it. In practice this collapses into three bands:

  • Human Verified — high confidence, no friction added.
  • Human Likely — reasonably confident, but the calling application may choose to apply a lighter secondary check for high-value actions (checkout, account creation).
  • Synthetic / Unknown — low confidence — this is where a policy engine decides what happens next, whether that's a step-up challenge, a rate limit, or an outright block, depending on the sensitivity of the action being protected.

That last point matters: the ML model's job is to produce a well-calibrated confidence score, not to make the final allow/block decision. Keeping those two responsibilities separate — scoring vs. policy — is what lets the same model serve very different risk appetites, from a public blog comment form to a banking login, without retraining anything.

Why this is still an open problem

No trust-scoring system is "done." Behavioral patterns drift as devices, browsers, and input methods change, and adversarial pressure increases in direct proportion to how valuable it becomes to bypass the system. The realistic goal isn't a static model that solves bot detection permanently — it's a scoring architecture that can absorb new modalities and retrain on new adversarial patterns without a full redesign every time attackers adapt.

Related