Skip to content
Docs · Workspaces, issuers and tokens

Concepts

A few ideas explain almost everything in Usher: where things live, who issues tokens, where people sign in, and how long each token lasts.

Workspaces, projects and environments

  • A workspace is your team or company in Usher Console. Its members and its audit log belong to it.
  • A project is one product: your web app, or a partner portal. A workspace can hold many.
  • An environment is one running copy of a project, usually development and production. Environments are where people, applications, keys and settings live.

Workspace · Acme Ltd

Project · Web

  • development · wise-otter-42
  • production · acme

Project · Partner portal

  • development · calm-heron-17
  • production · acme-partners
Each environment is its own issuer, with its own users, keys and Lobby.

Environments share nothing that matters. Each has its own Postgres schema, its own signing keys, and its own secrets sealed under its own data key. A person who signs up in development does not exist in production, and a token from one can never be verified with the other’s keys.

Issuers

Each environment is its own OpenID Connect issuer, at its own host on the tenant domain:

Issuer
https://<handle>.id.hallelo.net
  • Production environments have a handle you choose. Handles that read as Usher, a sign-in service or a well-known brand are refused, and a handle once used is never given out again.
  • Development environments get a random handle, such as wise-otter-42, which nobody will mistake for a brand.

The issuer is fixed when the environment is created, because every token it signs names it in iss, and every app that trusts it checks that value.

The tenant domain is a different registrable domain from Usher’s own (usher.hallelo.net), so a customer’s sign-in pages are never same-site with Usher Console, and cookies are host-only: a browser sends an environment’s cookies to that environment alone.

The Lobby

The Lobby is the sign-in page each environment hosts at its issuer. Your app sends people there; it signs them in and sends them back.

  • It always names the app the person is going to, in the “Continuing to” chip.
  • It offers only the methods the environment allows: passkeys, emailed codes, magic links, social accounts (Google, GitHub, Microsoft, Apple) and passwords.
  • It can require a second factor: an authenticator app (with backup codes) or a passkey.
  • It can be open to anyone, or limited to a guest list of addresses and domains.

It looks the same whichever product sent the person. That is deliberate: people learn what a real Lobby looks like, and notice when a page isn’t one.

Usher accounts

Most environments have their own users. Usher accounts are different: one account that signs a person in to every product that uses Usher accounts, such as Mentor, Sidekick and Hallelo. People manage theirs at account.usher.hallelo.net.

Tokens and lifetimes

TokenDefaultCan be set toWhat it’s for
Authorisation code5 minutesFixedSwapped once for tokens. Single-use.
ID token10 minutes1 to 60 minutesTells your app who signed in. Not for calling APIs.
Access token10 minutes1 to 60 minutesSent to your API, which checks it.
Refresh token30 days1 to 90 daysGets new access tokens. Rotates on every use. Needs offline_access.
Machine access token15 minutes1 to 60 minutesFor client_credentials: servers with no person behind them.
Emailed code, magic link10 minutesFixedSingle sign-in. A code allows three tries.

Sessions in the Lobby have lifetimes too: a session ends after 7 days without use (1 to 30), and after 30 days in all (1 to 90). Changing something sensitive, such as an email address, needs a sign-in from the last 10 minutes.

Signing keys

Tokens are signed with RS256 by default; an environment can use ES256 or EdDSA instead. The public keys are published at the environment’s jwks_uri, so your libraries fetch them, and pick up new ones when keys are rotated.

Scopes

ScopeWhat your app receives
openidRequired. An ID token with the person’s sub.
profileTheir name and picture.
emailTheir email address, and whether it’s verified.
offline_accessA refresh token, so they stay signed in.