Your users' identity data stays in Europe. Full stop.

Passwordless sign-in, OIDC and sessions on EU-resident infrastructure with no US cloud — and the plane that holds the data can be brought in-house.

Magic link · TOTP 2FA · OIDC provider · No password table

Jurisdiction is a product feature.

A US-headquartered vendor can be compelled under US law to hand over data, wherever it physically sits. Timonier is an EU company, and your end-users' records are stored and processed under EU jurisdiction by architecture rather than by policy.

  • Cloud Act
  • Schrems II
  • Adequacy decisions
  • EU residency

    Identity records, sessions and tokens stored and processed inside the European Union. No third-country transfers.

  • Accountable by design

    Every operator action that changes a user or a project is recorded: who did it, and what it touched.

  • No US cloud

    No US-headquartered hyperscaler in the stack, and lean enough to run on a single modest machine.

Identity data does not cross this line.

The plane that holds your end-users lives on infrastructure you can own. The SaaS half configures it and never becomes its system of record.

The end-user browser and the operator dashboard both talk to the data plane directly; neither reaches end-user records through the control plane. The data plane holds users, sessions, tokens and attributes. Two things cross the boundary into the control plane: configuration, which the data plane reads from it, and an operator audit trail, which the data plane writes to it. Emails, session records and attributes do not cross.

End-user browser signs in on your domain
Operator dashboard your team, in their browser
Data plane users · sessions · tokens · attributes Your machine, an EU VM, or our EU host. Records are stored and processed here and nowhere else.
configuration, read-only
audit trail — ids and counts
emails, sessions, attributes
Control plane projects · apps · keys · branding · workflows No emails, no sessions, no attributes. The operator audit trail holds record identifiers and counts of what each action touched.
identity data configuration and control does not cross

Even on the hosted plan, your operators' browsers fetch end-user records from the data plane directly. The control plane holds configuration and an audit trail of who did what, and is not the system of record for end-user identity.

One attribute change, three domains.

Authentication is the way in. What your users do next flows to targeting and to automation — and when they ask to be forgotten, that flows too.

First flow: your application calls CDP with a subject's attributes. CDP writes a subject.attributes.updated event, which is delivered independently to feature flags and to automation — the two are parallel consumers of the same event, and neither is downstream of the other. Second flow: a self-serve account erasure in auth calls CDP, which drops the subject and emits subject.erased, again delivered independently to feature flags and to automation.

An attribute change travels written to an outbox in the same transaction, relayed over authenticated internal HTTP
Your app after your user signs in
CDP subject attributes
Feature flags Attributes enrich targeting. Values you pass at evaluation still win.
Automation Your conditions, matched as an and/or tree, firing an email or a signed webhook.
A deletion propagates when the end-user erases their own account
Auth self-serve account erasure
CDP resolves its own keys, drops the subject
Feature flags projection dropped
Automation subject dropped
subject attributes erasure

Linking a subject to a signed-in user is a call your application makes, so you decide what Timonier ever learns about them. Everything downstream of that call is ours to deliver — including the erasure.

Scaffold your auth in one command.

The Next.js SDK writes the BFF route, your env file and the layout wrapper, so tokens stay server-side.

# Scaffold the BFF handler, env file, and layout wrapper
npx timonier-nextjs init

# Required env vars written by init:
# TIMONIER_PLATFORM_URL=https://auth.example.com
# TIMONIER_PROJECT_SLUG=acme
# TIMONIER_APP_SLUG=my-app
# TIMONIER_SESSION_SECRET=<generated 32-byte secret>

# server.ts — route handler
import { createAuthRouteHandlers } from "@timonier/nextjs/server";
export const { GET, POST } = createAuthRouteHandlers();
import { createClient } from "@timonier/browser";

const client = createClient({
  projectSlug: "acme",
  appSlug: "my-spa",
  clientId: "01234567-89ab-cdef-0123-456789abcdef",
  baseUrl: "https://auth.example.com",
});

The browser SDK is published but still early — token management, PKCE and session APIs are landing incrementally. For production SPAs today, point any OIDC client at the discovery document.

# Point any standard OIDC client at the discovery URL:
GET https://auth.example.com/.well-known/openid-configuration

# The document exposes authorization_endpoint, token_endpoint,
# jwks_uri, and userinfo_endpoint. Works with standard OIDC
# client libraries — no proprietary glue required.

Or run the whole data plane yourself.

Hosted by default, yours to bring in-house when you need it. Same software either way.

Email us to self-host

Keep authentication in Europe, by design.

EU jurisdiction is the default, not a setting.

Get started