Skip to content

Identity for your apps, on open standards

Shows you in.

One account. Every door.

Usher signs people in to your apps with OpenID Connect and OAuth 2.1: passkeys, codes, social sign-in and organisations, with every environment kept apart from every other.

Free to start. Runs on your own servers too.

The Lobby

A sign‑in page that welcomes, not interrogates.

The Lobby is the sign-in page Usher hosts for your app. It always says where the person is going, and it looks the same whichever product sent them, so people learn to trust it.

Continuing to
Theme
  • Names the product you’re going to, every time.
  • Passkeys, emailed codes and magic links, with passwords only if you want them.
  • The same calm page, light or dark, in every product.

This is a working copy of the Lobby. It runs in this page, sends nothing, and signs nobody in.

UsherUsherContinuing to Hallelo

Welcome back.

One Usher account signs you in to Mentor, Sidekick and Hallelo.

New here?

Secured by Usher

Standards, not lock-in

Speaks the protocols your stack already knows.

Usher is an OpenID Connect provider first. Use our SDK when it suits you, or any OIDC library in any language. If you ever leave, your apps don’t have to change how they sign people in.

Refresh tokens, consent and scopes included.
  • OIDC Core · Discovery

    OpenID Connect

    A discovery document per environment, ID tokens and userinfo. Any certified client library works.

  • S256 only

    OAuth 2.1 with PKCE

    Authorisation code with PKCE for every client, public or confidential. No implicit flow, no passwords in the token endpoint.

  • RS256 · ES256 · EdDSA

    JWKS and key rotation

    Each environment signs with its own keys, published at its jwks_uri. Rotate them without breaking signed-in people.

  • RFC 7662 · RFC 7009

    Introspection and revocation

    Ask whether a token is still good, or end it now. Usher checks its own sessions on every request, so ending one takes effect at once.

  • RP-initiated and back-channel logout

    Sign out from your app, or have Usher tell every app when a session ends anywhere.

  • RFC 9449

    DPoP

    Bind tokens to a key the client holds, so a stolen token is no use on its own.

  • WebAuthn

    Passkeys

    First-class, not an add-on. People sign in with a fingerprint, a face or a security key, and there is nothing to phish.

  • TOTP

    Authenticator apps

    Time-based codes from any authenticator, with backup codes. Make a second factor optional or required.

  • Magic links

    One tap from the inbox. Short-lived, single-use, and bound to the environment that sent them.

  • Email codes

    Six digits, for people who sign in on one device and read email on another.

  • Social sign-in

    Google, GitHub, Microsoft and Apple. An account is only linked when its email has been proved.

  • Organisations and teams

    Members, roles and invitations for the businesses that use your app.

  • Coming soon

    SAML

    Single sign-on with your customers’ workforce identity providers.

  • Coming soon

    SCIM

    Provisioning and deprovisioning from your customers’ directories.

How a sign-in works

Five steps, every one of them standard.

This is OpenID Connect’s authorisation code flow with PKCE, the same flow every serious identity provider speaks. Scroll through it.

  1. 01

    Your app sends them to the Lobby.

    When someone chooses Continue with Usher, your app redirects them to your environment’s authorisation endpoint, with a PKCE challenge and a state value it will check later.

    GET acme.id.hallelo.net/api/auth/oauth2/authorize
      ?response_type=code
      &client_id=acme_web
      &redirect_uri=https://app.acme.example/callback
      &scope=openid profile email offline_access
      &state=k3Jx…
      &code_challenge=E9Mel…cM
      &code_challenge_method=S256
  2. 02

    They sign in, their way.

    A passkey, an emailed code, a magic link, a social account or a password: the Lobby offers only what your environment allows, and always says which app they’re going to.

    UsherUsherContinuing to Acme

    Welcome back.

    Use a passkey
    Email me a code
  3. 03

    They agree to share.

    The first time, people see what your app is asking for (their profile, their email, staying signed in) and agree once.

    Acme would like to:

    • See your name and picture
    • See your email address
    • Keep you signed in
    CancelAllow
  4. 04

    Usher hands back a code.

    The browser returns to your redirect URI with a single-use code that lasts five minutes, and the state you sent, which your app checks.

    302 Found
    Location: https://app.acme.example/callback
      ?code=SplxlOBeZQQYbYS6WxSbIA
      &state=k3Jx…
  5. 05

    Your app swaps it for tokens.

    Your server sends the code and the PKCE verifier to the token endpoint. Back come an ID token that says who they are, an access token for your API, and a refresh token to stay signed in.

    POST acme.id.hallelo.net/api/auth/oauth2/token
      grant_type=authorization_code&code=Splx…
      &code_verifier=dBjftJeZ4CVP…
    
    {
      "token_type": "Bearer",
      "access_token": "eyJhbGciOiJSUzI1NiIs…",
      "id_token": "eyJhbGciOiJSUzI1NiIs…",
      "refresh_token": "8xLOxBtZp8…",
      "expires_in": 600
    }

Isolation by design

Every environment is a building of its own.

Your production and development environments, and every other customer’s, share nothing that matters. A mistake in one cannot read, sign for or sign in to another.

Its own Postgres schema
Not a tenant column in a shared table: a schema made for the environment, and nothing else in it.
Its own signing keys
Tokens from one environment can never verify against another’s keys.
Its own sealed secrets
Sealed with the environment’s own data key, which is itself wrapped by a master key.
Its own host
Issuers live on a separate domain from Usher’s site and Console, with host-only cookies.

usher.hallelo.net

The site, Usher Console, Usher accounts

*.id.hallelo.net

One issuer per environment, on a separate domain

Environment

Users, sessions and tokens live in a schema made for this environment. Queries run against that schema, never a shared table with a tenant column.

Copy Acme production’s sealed Google client secret into Northwind production.

For developers

Your first sign‑in, three ways.

Drop in the SDK when it arrives, use the OIDC library you already trust, or start by reading the discovery document. It’s all the same protocol underneath.

app/layout.tsx · app/page.tsxComing with the SDK
// app/layout.tsx
import { UsherProvider } from '@usher/nextjs'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <UsherProvider>{children}</UsherProvider>
      </body>
    </html>
  )
}

// app/page.tsx
import { SignIn, UserButton, currentUser } from '@usher/nextjs'

export default async function Page() {
  const user = await currentUser()
  return user ? <UserButton /> : <SignIn />
}

Run it yourself

Your servers, your keys.

Use Usher as a service, or run the same platform on your own servers, with your own keys and your own database.

  • Docker

    One Compose file: the apps, Postgres, Valkey, the Caddy edge and the egress proxy. Containers run with no new privileges and with capabilities dropped.

  • Ubuntu

    A plain Ubuntu server is enough. Caddy terminates TLS, and secrets are files handed to the containers, never baked into images.

  • Postgres

    Postgres holds everything, one schema per environment. It and Valkey sit on a network with no route to the internet.

From a checkout of Usher
# on an Ubuntu server with Docker Engine and the Compose plugin
bash infra/scripts/setup-env.sh --prod \
  --domain usher.example --tenant-domain usherid.example

docker compose -f compose.yaml -f compose.prod.yaml \
  --profile core --profile apps --profile edge up -d --wait

pnpm db:migrate   # applies the database migrations

The full self-hosting guide is on its way. The commands above are the shape of it.

Show your users in.

Create a workspace and a project, and your first environment comes with its own issuer, keys and Lobby.

Sign in once. Welcome everywhere.