Skip to content

Sign in once, signed in everywhere

Someone signs in to Omxus on one site. They open another site that uses Omxus, and it already knows them: no popup, no click. That is the Google experience, built on plain OpenID Connect.

What the person sees

  1. A site shows Log in. One click opens a 500 × 600 popup on auth.omxus.com. They sign in (or create an account), the popup closes itself, and the site shows their name.
  2. They open another site. It signs them in on arrival.
  3. They sign out on a site. That tab stays signed out.

How it works

One cookie on the provider. Signing in on the hosted page (/oidc/authorize) sets __Host-omxus_std on auth.omxus.com: HttpOnly, first-party to the provider. Your site never sees it.

Silent sign-in with prompt=none. Your site bounces through /oidc/authorize with prompt=none. The provider answers at once, with no screen:

Answer Meaning What your site does
?code=… Signed in to Omxus, and this site is allowed Exchange the code as usual
error=login_required Not signed in to Omxus Stay signed out; show Log in
error=consent_required Signed in, but has not said yes to this site Show Log in; one press of Continue fixes it for good
error=interaction_required Signed in, but needs a username for this site Show Log in

None of these is an error to the person. Never show them.

First-party sites skip the Continue press. Sites run by the same operator as the provider are listed as first-party (FIRST_PARTY_CLIENTS on the provider). For them prompt=none needs no earlier grant, and they share one username. A third-party site always gets consent_required until the person says yes once. That boundary is deliberate: zero-click sign-in never extends silently to a site the person has not chosen.

In a browser-only site

Use omxus-oidc.mjs. It has no dependencies; copy it into your site.

Copy it from the auth repo

omxus-oidc.mjs is not served at auth.omxus.com/sdk/ yet (404, checked 30 Oct 2026). Copy sdk/omxus-oidc.mjs from the auth source.

import { createOidcClient, finishPopup, takeReturnPath, stayedSignedOut } from './omxus-oidc.mjs';

const oidc = createOidcClient({
  issuer: 'https://auth.omxus.com',
  clientId: 'YOUR_CLIENT_ID',
  redirectUri: location.origin + '/login',
});

// The button. Call signInPopup inside the click, or the browser blocks the popup.
button.onclick = () => oidc.signInPopup().then(({ claims }) => save(claims));

// On every page, while signed out. Runs once per tab; true means the page is leaving.
if (!signedIn) oidc.signInSilently();

// On /login (your redirect URI):
if (!finishPopup()) {
  try {
    save((await oidc.handleCallback()).claims);
  } catch (e) {
    if (!e.silent) throw e;     // a silent miss: login_required and friends
  }
  location.replace(takeReturnPath());
}

// On sign-out, so this tab does not bounce straight back in:
stayedSignedOut();

Checked against the SDK source on 30 Oct 2026: createOidcClient returns signInPopup, signInSilently and handleCallback; a silent miss throws with e.silent === true. Untested end to end from outside the auth repo.

If the browser blocks the popup, or opens it and closes it at once, signInPopup falls back to a full-page sign-in. Never assume the popup appeared.

In a site with a server

Use the Worker template (integrations/worker/auth.mjs in the auth source):

Route Does
/auth/start?popup=1 Sign in through the popup
/auth/start?prompt=none&return_to=/x The silent check; a miss lands on /x?signin=none

return_to must point at an origin you allow in the template's settings.

Register with the standard door

A new client gets the minimal door by default, which has no Create account. For a site where new people sign up, register with door: "standard":

curl -X POST https://auth.omxus.com/oidc/register \
  -H 'content-type: application/json' \
  -d '{"client_name":"Site Name","door":"standard","redirect_uris":["https://example.com/login"]}'

Choosing speed or zero clicks

The silent check is a full-page bounce. On a phone, for a first-time visitor, it costs 5 to 7 seconds (Lighthouse, 25 Sep 2026). Pick per site:

  • Search-traffic sites: run the silent check only when this browser has signed in to your site before (set a localStorage flag after sign-in). Fast first visits; someone signed in elsewhere presses the button once.
  • Sites people arrive at already signed in: run it on every new tab.

Gotchas

  • Firefox bounce-tracking protection. Firefox may classify auth.omxus.com as a bounce tracker, because people only pass through it in redirects, and purge its cookie. People are then quietly signed out. Keep the silent check to once per tab and never add more silent bounces. The real sign-in click on auth.omxus.com counts as user activation, which helps. Firefox sign-outs reported? Check this first.
  • Testing with Playwright. Some sites skip the silent check when navigator.webdriver is true; hide it to test. route.fetch() follows redirects unless you pass maxRedirects: 0.
  • Sign-out is per site. Signing out of your site does not sign the person out of Omxus or of other sites. Do not promise "sign out everywhere".

See also