AuthLoop
Continuous authentication that keeps checking whether a session still looks like you.

Overview
Authentication is usually a single event, but session risk is continuous. That gap is where an unlocked laptop, a stolen session cookie, or an insider quietly lives. AuthLoop closes it the only honest way available to a browser: it measures how someone types, moves their cursor, and reacts, then keeps asking how unusual the current session looks. It never claims to know who is at the keyboard. It produces a risk score and a ranked list of what raised it, and a separate policy layer turns that into decisions: allow, monitor, step-up, restrict or terminate. You can also play the other side, taking a stranger's session and trying to pass off as them.
Problem
People stay logged in for hours or days. Everything after the login is trusted on the strength of a check that happened once, possibly on a different day, possibly by a different person. Rather than trying to classify a user as legitimate or malicious, AuthLoop decides how much unusualness a system should tolerate before it interrupts someone, and what it costs the honest user when it gets that wrong.
Solution
A browser app that calibrates a behavioural baseline from four short tasks, then measures the session continuously while the user works through a capture-the-flag sandbox. Around a dozen derived numbers are computed in the page, including raw keystrokes, mouse paths and typed text which never leave the browser. Device and network signals are added server-side, with IP-to-region resolved against a local database so no address ever leaves the machine. A security slider moves only the thresholds so that the same session can be waved through or challenged depending on how much oddity you are willing to accept.
Architecture
Five stages: Collection → Feature processing → Risk → Policy → Action. The risk engine is pure functions over plain data with no database access, and answers only 'how unusual is this'. The policy engine never sees a signal, only a number, and answers 'what should we do'. Risk combines as the worst weighted family plus a bounded corroboration term from the rest, so a matching device can never dilute a behavioural anomaly while several signals agreeing still count for more than one. Session risk is sticky and evidence-weighted: it rises at the full weight of the evidence and falls at a quarter of it, scaled by how much behaviour an observation actually contained. Missing data never creates risk, and 'we cannot tell' is a distinct state from 'this looks fine' all the way to the UI. The attacker mode follows a similar structure, just that baselines are randomised beforehand.
Tech Stack
Challenges
- A single weak reading could erase the session's entire risk history. I replaced memoryless scoring with evidence-weighted risk that builds over time.
- My attacker simulation originally modeled noisy users, not real impostors. Symmetric disruptions cancelled out, giving 0% detection. I fixed it with consistent directional shifts across each attack session.
- Averaging signal families diluted the strongest evidence. A radically different typist on a trusted device scored just 24/100. I changed aggregation so strong signals can't be averaged away.
Lessons Learned
- Tests validate assumptions, not reality. My blind spots became my test suite's blind spots.
- A better number isn't always a better system. Honest failure cases matter more than tuned metrics.
- Detection without recovery is incomplete security. False positives need a safe way back in.
Future Improvements
- The baseline was set as static to prevent poisoning and drift, but in a real system, user behaviours might change over time and continuous learning could be securely implemented.
- The CTF style challenge could be extended to include more of the recorded features from the user.
- The evaluation lacks real data. Synthetic attackers are close to circular, and genuine mimicry data is scarce. More real-world attacker data is the key next test.