Users & identities
Users are the end users who log in through your issuer — the people your applications authenticate. They are distinct from your team's members, who manage the team. When you register a client and someone signs in, the account created (or matched) is a user in that issuer's pool.
Per-issuer user pools
Each issuer has its own user pool. An account at acme.auth.is is not the same account as one at other.auth.is, even for the same email address — the pools are fully isolated. This is the tenancy boundary for identity: your users are yours, scoped to your issuer.
A user's subject identifier (sub, the stable id in every token you receive) is unique within the issuer. Build your app's user records keyed on (issuer, sub).
Credentials
A single user can hold more than one way to authenticate:
- Password — a username/password credential, hashed with argon2id (one-way, never reversible). This is the default when self-signup is enabled.
- Federated — a link to an upstream identity provider (Google, Microsoft/Entra, Kenni, or any OIDC provider) configured on the issuer. The user clicks "Continue with …" and the issuer records a
user_identitylink. See Identity providers. - Passkey — a WebAuthn credential, offered as a second factor and enrollment nudge on clients that enable it (
toggle_client_passkeys). The passkey's relying-party id is the issuer host, so passkeys are isolated per issuer.
How accounts are created and linked
- Self-signup creates a fresh password user — but only when both the client's
registration_enabledand the issuer'sregistrationMode: openallow it (see Clients). Otherwise the login page offers sign-in only. - Federated login matches an existing link by the pair
(issuer provider, upstream user id). If there is no link yet, the issuer links to a local account by email only when both the local email and the upstream claim are verified; otherwise it creates a new user.
An unverified upstream email is never auto-linked to an existing account. This prevents an attacker from claiming someone else's account by signing up at an upstream provider with an unverified copy of their email. A new, separate user is created instead.
What you receive about a user
After a successful login your app gets an ID token (and can call userinfo) carrying the claims the granted scopes allow:
| Scope | Claims |
|---|---|
openid | sub |
profile | name, given_name, family_name, preferred_username, picture, updated_at |
email | email, email_verified |
Identity claims are included directly in the ID token (not stripped to sub), so most libraries read the user off the ID token without a second round-trip to userinfo.