Open-source identity for people & agents

Know who’s
behind the request.

One account can have a whole cast of characters. Doorman connects verified people, browsers and agents, and adds private activity estimates to the analytics you already use.

Developer preview. Inferred labels are experimental.

Who’s coming in?
A human
A little illustration of a bigger identity question. No tracking in this animation.
Identity meets activity

One account.
Different operators.

A login tells you which account is open. Doorman adds context about the activity behind it: direct human use, an AI assistant, or a conventional script.

Use verified credentials where available. Use private, experimental scores where you need an estimate. Keep unknown activity visible in your reports.

Explore agent classification
01 / Observe

Patterns, without recordings.

Optional movement and timing summaries meet server-owned API patterns. Add optional local-font and runtime evidence. No key values, form content or coordinate trails.

What is collected →
02 / Assess

Assistants aren’t attacks.

Jev scores human, assistant and scripted activity separately from abuse. Connect suspicious actions across likely related sessions, even when IPs rotate. Tune thresholds on confirmed outcomes.

Follow related activity →
03 / Understand

Your analytics, with context.

Send assessed windows and inferred account profiles to PostHog, Mixpanel and your warehouse. Verified identities stay distinct from estimates.

Build an account report →

Developer preview. Scores are uncalibrated; agent-brand recognition and reliable headcounts are not established. Read the public-data results →

Browsers change.
The connection can stay.

Doorman gives a browser a random visitor ID and saves a small history of its signals, such as screen size and browser family.

A first-party cookie remembers that ID. If it disappears, Doorman compares the next visit with past observations and restores the ID when there’s enough evidence.

Understand browser matching
Try it with an example browser

Change a signal.
Follow the identity.

Choose a change below and watch the visitor ID. This demo uses made-up browser data; it does not collect yours.

Simulated browser
Chrome on macOS1440 × 900 · 8 cores

Synthetic signals only.
No browser data is collected.

visitor.identify()Initializing
Visitor identityvis_…

Starting the local matching engine.

Identity confidence
0Match needed: 0.901
// Run a scenario to inspect the response.

Each option starts from the same example history. All except “Return with cookie” remove the cookie first. The scores shown here normally stay on your server; they demonstrate the matching rules, not real-world accuracy. How matching works ↗

A browser client.
An endpoint.
Your database.

Add the client to your app and mount Doorman on your server. The client sends a small observation; the server looks up history and returns a visitor ID.

  1. Choose your serverUse Node, Next.js, Cloudflare Workers or native Elixir.
  2. Connect storageKeep visitor history in your own Postgres or D1 database.
  3. Call identify()Get a browser ID. Read confidence and risk privately on the server.
Run your first example
client.ts
import { createVisitorClient } from "@aarondovturkel/doorman-browser";

const visitor = createVisitorClient({
  endpoint: "/api/visitor",
});

const identity = await visitor.identify();

// { visitorId, isReturning }
// Scores stay on your server.
// Destroy the client when collection should stop.
visitor.destroy();
Optional AI, powered by Jev

Small questions.
Useful context.

Jev is an AI model from TypeSafe. It helps Doorman choose useful lookup signals, compare a shortlist of browser histories, and assess automation and suspicious signals. The optional operator service asks separate questions about human, assistant and scripted activity.

Use those estimates to inform your own checks, such as when to request a CAPTCHA. Doorman returns information; your app decides what happens next.

Meet Jev and the scores

Enable learning to ask Jev about anonymous visits across devices using earlier login-confirmed sessions. Suggestions stay private until a login confirms the person. Set up learning →

Browser matching and risk
Does this browser look familiar?sameVisitor
Compares this visit with recent history, allowing for ordinary changes.
Does the session look automated?automation
Uses available signals and aggregate event counts.
Do the signals look inconsistent?suspicious
Looks for unusual technical combinations, not a person’s intent.

Scores are experimental estimates. Missing signals alone do not mean abuse.

A browser is one thing.
A person is another.

Two people can share a laptop. One person can use a laptop and a phone. An AI assistant can act with that person’s permission.

After your app verifies a login or agent credential, Doorman can connect those visits to a known identity. It records who is making a request and whose account they are using.

Learn the few terms you’ll need
Try a shared account

Same account.
Different hands.

An “actor” is the person or agent making a request. Try the examples to see how Doorman checks their permission to use this account.

Example people and credentials.Real permission checks.Runs in your browser.

identities.assess(context)Loading
Acting asaccount_owner
DelegationNot required

Enable JavaScript to run the local scenarios.

Account evidence
Actor kind
Requested scope
Inspect the actual response
Real permission checksNo AI calls · your app decides access

In an application, your login system verifies these identities. Doorman checks the permission you recorded; it does not guess who is at the keyboard.Build this into your app ↗

Prepare your analytics
for the agentic era.

Keep your analytics. Let Doorman handle identification. As agents become more of your users, see who is behind an account and tailor the experience to them. Doorman handles identification across anonymous visits, login, profile updates and logout, so your reports get consistent identity context.

Record verified people and agents separately from inferred activity labels. Reports can show which actions have a verified agent credential, which windows look assistant-operated, and where evidence is still missing.

Connect your analytics

Agents can also use your API directly. Add optionalAPI activity middleware to bring those requests into the picture, with private Jev risk assessments.

An example workspace
  • AlexPerson
  • SamPerson
  • Alex’s assistantAgent

Illustrative data. Your app supplies verified identities.

Useful context.
Clear boundaries.

Browser data stays in your database. If you enable Jev, a compact set of signals goes to your chosen AI provider. Doorman respects browser privacy restrictions and never captures form values, actual keystrokes or browsing history.

Risk scores stay on your server by default. Doorman does not replace login, prove who is at the keyboard, or automatically block anyone.

See exactly what is collected

Start with
one returning browser.

Run a local example, inspect browser continuity, then add private activity scores and analytics context as your application needs them.

Get startedExplore the source on GitHub ↗

Search documentation

Search setup instructions, examples and the API reference.

Local search. No query leaves your browser.