Core concepts
SemAuth has five nested building blocks: organization → realm → application → client, plus users who belong to a realm. Understanding how they relate is the key to everything else in this documentation.
The hierarchy
Organization
The organization is the top-level tenant — usually your company. It owns everything below it and is the boundary of isolation: one organization can never see another's realms, users, or audit events.
- Each organization has a globally-unique slug (lowercase letters, digits, hyphens).
- The slug becomes a subdomain: your admin console lives at
{slug}.semauth.cc. - Every change is recorded against the organization as the tenant, which is what powers the Activity feed.
The system organization. SemAuth reserves one system organization,
operated by Kovilo, whose slug is self. It hosts the platform Admin API.
As a customer you never interact with it directly — self is simply a reserved slug, mentioned here
only so the term isn't a mystery if you encounter it (for example in the Admin API hostname).
Realm
A realm is an OIDC issuer — a self-contained login service with its own users, sign-in policy, signing keys, and OIDC endpoints. Think of a realm as one "login universe": users in realm A and realm B are completely separate identities even within the same organization.
- Each realm has a globally-unique, randomly generated issuer ID (a 12-character string
like
vctxj6g1egkv) — not your org slug. - By default the realm is served at
{issuer_id}.semauth.app. Theissclaim in every token, the JWKS URL, magic-link emails, and passkey binding all root at this host. - A realm can optionally be served at a custom domain like
idp.acme.com. - Each realm gets its own RSA signing key (RS256) generated automatically when it is created.
You typically create one realm per environment or product line — for example a production realm
for your live users and a staging realm for testing.
Admin realm. Every organization is itself authenticated by SemAuth (SemAuth "dog-foods" its own OIDC). When you sign up, SemAuth automatically creates a hidden admin realm that authenticates your human administrators into the admin console, and that hosts your Admin API credentials. You don't manage it day-to-day, but it's why you log in to the admin console with the same passwordless flow your own users get.
Application
An application is a grouping of clients inside a realm — it represents one product or service in your portfolio (e.g. "Acme Web", "Acme Mobile"). An application carries a name, an optional description, and optional Terms of Service / Privacy Policy URLs. It does not itself authenticate; it is a container that holds one or more clients.
Client
A client is the actual OIDC relying party — the concrete piece of software
that performs the login flow and receives tokens. Each client belongs to exactly one application. A client has a
client_id, an authentication method, allowed grant types, allowed scopes, redirect URIs, and
(optionally) the API audiences it may request.
Clients come in two shapes:
| Type | Auth method | Use for |
|---|---|---|
| Public | none (PKCE-protected) | Single-page apps, mobile apps, CLIs — software that can't keep a secret. |
| Confidential | client_secret or private_key_jwt | Backend / server-side apps that can safely hold a credential. |
See Applications & clients for the full registration walkthrough.
User
A user is an end-user identity scoped to a single realm. Users are identified by email and authenticate passwordlessly — via a magic link, a passkey, or a federated provider. The same email in two different realms is two different users. A user can be deactivated (which immediately revokes their sessions and tokens) and reactivated later.
How a login actually flows
When one of your apps sends a user to SemAuth to sign in, the request is routed by hostname to the right realm, the user authenticates, and SemAuth redirects back to your app with an authorization code that your app exchanges for tokens:
The URL scheme
Everything in SemAuth is addressed by hostname. SemAuth uses two domains —
semauth.cc for the admin console and semauth.app for realm (issuer) endpoints:
| Host | What lives there |
|---|---|
semauth.cc | The public sign-up page. |
{org-slug}.semauth.cc | Your organization's admin console. |
api.self.semauth.cc | The Admin API (self is the reserved system-organization slug). |
{issuer_id}.semauth.app | A realm's OIDC endpoints (issuer, authorize, token, JWKS…). |
idp.acme.com (example) | A realm's custom domain, if configured. |