I IntelliAuth Docs

An identity is one user inside one tenant. Whatever your product calls them — customer, member, account, user — that's the identity layer.

This page walks the shape of an identity and where each part comes from.

The basics — what's always there

Every identity has:

  • sub — the identity's id, a string like usr_01HZX.... Stable forever; never reuse this across identities.

  • email — primary email. May or may not be verified (see email_verified).

  • email_verified — boolean. True if the user clicked the verification link.

  • created_at — when the identity was first created in this tenant.

  • updated_at — last profile change.

These come back on the user object when you call useIntelliAuth().user or the OIDC /userinfo endpoint.

Standard OIDC claims — what comes back when you ask

If your application requests the profile scope at sign-in, the identity object also carries:

  • name — display name.

  • given_name / family_name — split parts if available.

  • picture — URL to a profile picture (when set).

  • locale — BCP-47 locale string, e.g. en-US, fr-CA.

If your application requests email, you additionally get email + email_verified (mentioned above).

The full list is per the OIDC specification's standard claims. Your tenant may surface additional standard claims depending on configuration (phone number, address, gender, etc. — though these are rare).

Custom attributes — what your tenant defines

Beyond the OIDC standard claims, your tenant can define custom attributes specific to your product. Examples:

  • subscription_tier: "pro" — the user's plan.

  • business_unit_id: "banking-prod" — which of your internal business units / sub-products they belong to (useful when one tenant serves multiple products with shared identities, rare).

  • feature_flags: ["beta-search", "early-mfa"] — per-user flags.

Custom attributes live on the identity object (alongside email, name, etc.) and flow through to the ID token + access token claims when configured to do so by the tenant admin.

How to set them:

  • At sign-up. The registration flow can collect custom attributes via custom form fields.

  • From your backend. The Node SDK's management client exposes mgmt.users.update(id, { custom_attributes: { ... } }).

  • Via SCIM. If your tenant has SCIM enabled, your identity provider syncs them automatically.

Reading them on the client:

ts
const { user } = useIntelliAuth()
const tier = user?.custom_attributes?.subscription_tier

Reading them on the backend:

ts
// After requireSession middleware:
const tier = req.user.custom_attributes?.subscription_tier

Federated identities — same user, multiple sources

If your tenant has social login or SAML federation enabled, a single identity can have multiple federation links — Google, GitHub, Okta, etc. The identity has one sub (the IntelliAuth-issued id), but the federation links record which external accounts have been associated.

From your code's perspective, this is mostly transparent — useIntelliAuth().user returns the same identity regardless of which federation route they used to sign in. The connection claim names the route (google-oauth2, okta-saml, email-password, etc.) if you need it.

The identity model is "one identity per email per tenant" — if a user signs in with Google using alice@example.com and later signs in with GitHub using the same email, the tenant's link-by-email policy determines whether they become the same identity or two separate ones.

What an identity is NOT

Three things often confused with identities:

  • Identity is not the same as session. Sessions are temporary; identities are durable. One identity can have many sessions (one per device, say). See Sessions and tokens.

  • Identity is not the same as account-in-your-app. Your application probably has its own database row representing the user (orders, preferences, etc.) keyed by sub. The identity is IntelliAuth's view; your row is yours.

  • Identity is not the same as MFA enrolment. A user can have MFA enrolled or not; that's per-identity state, but the identity exists independently of MFA configuration. MFA enrolments are listed under useIntelliAuth().listMfaEnrollments().

See also