Overview
Orgs, clients, tenants, users and pages, and how they compose.
Everything in LoginWith belongs to one org. Inside it, clients are the apps that receive tokens, tenants are the groups users act in, users are the people, and pages are where they sign in.
Org
An org is the administrative boundary, and the issuer. It has a slug
(acme), and its OAuth endpoints and signing keys live at
https://acme.loginwith.dev/ — the iss of every token it mints. Every other
resource below belongs to exactly one org.
People who administer an org are its members, as owner or member.
Client
A client is an OAuth client registered in the org — the client_id your
app identifies itself with, and the aud of every token minted for it. On the
API a client has an id (cli_…), a name, a logo, redirect_uris, and
confidential:
- Public (
confidential: false) — a browser app or SPA. It holds no secret and runs the authorization code flow with PKCE. - Confidential (
confidential: true) — a backend. It holds aclient_secret, shown once when created or rotated, and may restrict where it can be used from with anip_allowlist. It can runclient_credentialsas itself, back a login as a backend-for-frontend, or promote a public client’s tokens.
Every client gets the authorization code flow — response_type=code. There is
no implicit flow.
Many apps end up with two clients: a public one for the browser and a confidential one for their backend.
Tenant
A tenant is a group within the org — the team or workspace your users act
in. Tokens carry the active one as tnt: "tnt_…". A user who can enter several
picks one at sign-in, and can switch
later without signing in again.
Who may enter is the tenant’s mode:
| Mode | Who gets in |
|---|---|
public | Anyone who signs in |
domain | Users whose email domain is on the tenant’s list |
workspace | Users whose provider account belongs to an allowed workspace — a Google Workspace domain, for instance |
closed | Only users added or invited |
Inside a tenant, members hold a role (owner, admin, member, or invited)
and can carry labels — named groups your app can gate on, returned by
/users/me.
User
A user is a person who has signed in, with an id usr_… — the sub of
their tokens. A user belongs to one org: the same person signing in to two orgs
is two separate users. Within the org, they can be a member of many tenants.
The profile (email, name, picture) is not in the token; read it from
GET /users/me.
Page
A page is a hosted login page, at {slug}.loginwith.page or on one of your
custom domains. Each page signs users in to one
client, and chooses its sign-in methods: password, magic link, and any of the
SSO providers. It wears a kit — a set of branding (logo, colors, favicon)
that several pages can share.
How they fit together
flowchart TD Org[Org: acme<br/>https://acme.loginwith.dev/] SPA[Client: public SPA] Srv[Client: confidential backend] Page[Page: acme.loginwith.page] Default[Tenant: acme] EU[Tenant: acme-eu] U1((user)) U2((user)) Org --> SPA Org --> Srv Org --> Page Page -. signs in to .-> SPA Org --> Default Org --> EU Default --> U1 EU --> U1 EU --> U2
A user token answers four questions at once: which org (iss), for which
client (aud), in which tenant (tnt), as which user (sub). See
Tokens for the rest.