
Continuous Authentication with UEBA
A continuous authentication platform that uses behavioral risk analysis to detect suspicious sign-ins and autonomously execute policy-driven identity responses.

Traditional authentication answers a question at a single point in time, should this user be allowed in?
That assumption becomes weaker once a session has begun. Credentials can be compromised, sessions can be hijacked and legitimate accounts can begin behaving in ways that no longer resemble the user behind them.
I built Continuous Authentication with UEBA to explore a different model, treating authentication as an ongoing risk-evaluation problem rather than a one-time gate.
The result is an end-to-end identity security platform that ingests authentication activity, constructs behavioral context, evaluates anomalies, applies configurable risk policy and exposes the evidence behind each decision to an analyst.
The interesting problem was not anomaly detection in isolation.
It was designing the system around it. How events move through the platform, how behavioral context is constructed, how uncertain model outputs become operational decisions and how those decisions remain explainable and controllable.
From authentication events to security decisions
The platform is built around an asynchronous event-processing pipeline.
Authentication activity enters through a provider-independent ingestion boundary and is normalized into an internal representation before downstream processing. Accepted events are handed off to background workers, allowing ingestion to remain decoupled from the more expensive work involved in behavioral analysis.
Conceptually, the processing path looks like this:

This separation was intentional.
Authentication ingestion is primarily an API and validation problem. Behavioral scoring is a stateful analytical workload. Enforcement is an external side-effect with a very different failure profile.
Treating them as distinct stages makes the system easier to reason about and prevents a model inference from becoming an uncontrolled security action.
Behavioral risk is contextual
A suspicious authentication event rarely looks suspicious in isolation.
Logging in at an unusual time may be perfectly legitimate. Accessing a new machine may be routine. A burst of authentication activity may be harmless.
The useful signal appears when activity is evaluated relative to both individual behavior and the wider environment.

The scoring pipeline therefore builds behavioral context from recent authentication history and combines complementary anomaly signals rather than relying on a single heuristic or model.
One part asks:
How unusual is this event for this user?
Another part asks:
How unusual does this activity look relative to broader system behavior.
The resulting signals are normalized and combined into an unified risk representation that can be consumed by the policy layer.
This hybrid approach also creates an important architectural boundary, machine learning estimates abnormality; policy decides what abnormality means operationally.
The model does not own the decision
One of the core design principles of the project is that an anomaly score should never directly become an account lockout.
Model outputs are evidence, not policy.

A dedicated decision layer translates behavioral risk into operational states and determines the appropriate response under the tenant's configured policy.
That allows the same detection pipeline to operate under different modes:
- Observe suspicious activity without taking action.
- Surface activity for analyst review.
- Permit configured identity responses when policy allows it.
Keeping detection and response separate makes the system substantially safer to evaluate and operate. It also creates room for threshold changes, policy experimentation, additional models and new identity providers without coupling those decisions to the inference implementation.
Explainability as a systems requirement

An anomaly detector that produces a number without context is difficult to use in a security workflow.
For every evaluated authentication event, the platform maintains an evidence trail connecting the original activity to the behavioral context, model signals, resulting risk assessment, policy decision, and any downstream response.
The analyst interface is built on top of that evidence rather than exposing a black-box score.
This makes it possible to answer questions such as:
- What activity triggered the decision?
- Which behavioral signals contributed to the risk?
- What action did the policy recommend?
- Was an external response actually executed?
- What happened previously for the same identity?
That distinction became important throughout the design, observability is not an interface added after the ML system is complete. It is part of the ML system itself.
Privacy before persistence
Behavior analytics naturally involves identity and activity data, which makes the data boundary part of the architecture rather than a secondary concern.
The normal processing path transforms sensitive identifiers before persistence while retaining the relational structure required for behavioral analysis.
This allows the system to reason about recurring users, devices, hosts, and activity patterns without making raw identity data the default representation throughout the analytical pipeline.
The objective was not merely to add anonymization as a storage feature, but to establish a clear point in the event lifecycle after which downstream components no longer need access to the original identifiers.
A deliberately compact architecture
The platform uses separate runtime processes for its API, background processing, and analyst interface, but I deliberately avoided decomposing the implementation into a large collection of independent services.
Instead, the backend retains clear internal domain boundaries while sharing common contracts, persistence primitives, policy logic, and ML infrastructure.
This provides asynchronous workload isolation where it matters without paying the coordination cost of a distributed architecture everywhere else.
The resulting deployment consists of a small set of containerized services backed by relational persistence and a lightweight streaming layer. The same boundaries work for local development while remaining portable to container-based cloud infrastructure.
Architecture should reflect operational requirements, not architecture diagrams.
The project needed asynchronous processing and independent workers. It did not need a dozen network boundaries to achieve them.
Building the system around the ML
The most valuable part of this project was designing everything that happens before and after inference.
The anomaly models are important, but a deployable behavioral-security system also needs:
- Stable ingestion contracts
- Asynchronous workload handling
- Historical feature construction
- Privacy boundaries
- Reproducible model artifacts
- Persistent decision evidence
- Configurable policy
- Controlled external side-effects
- Interface through which humans can understand the result
Building those pieces together changed the nature of the problem.
It stopped being an anomaly detection experiment and became a systems engineering problem in which machine learning is one component of a larger decision architecture.
That is the distinction I wanted this project to explore.