Users
Learn how Users work in AuthPI, including authentication, profiles, sessions, and lifecycle management.
Last updated 2026-07-11
A User represents a person who can authenticate with your application through AuthPI. Users have identities, profiles, authentication methods, sessions, and can belong to organizations.
Each User exists within a single Issuer. This means your production and staging environments have completely separate user pools—a user in your Production Issuer is distinct from a user in your Staging Issuer, even if they share the same email address.
User Identity
Username
Every user has a username that uniquely identifies them within their Issuer. The username is what users enter when logging in, and it must be unique across all users in that Issuer.
AuthPI supports three username types:
Email (most common): Users are identified by their email address. This is the default and works well for most applications—email addresses are globally unique, users remember them, and you can use them to communicate with users (password resets, notifications, etc.).
Phone: Users are identified by their phone number in E.164 format (e.g., +14155551234). This is useful for mobile-first applications or in regions where phone numbers are more commonly used than email addresses.
Unique text: Users choose their own username (like a forum handle or gamertag). This works for applications where email privacy is important or where usernames are part of the user experience (social platforms, gaming, communities).
The username type is set at the Issuer level, so all users within an Issuer use the same type. Choose based on how you need to communicate with users and what identifier makes sense for your application.
User ID
Every user also has a permanent, system-generated ID (format: usr_ followed by a UUID). Unlike usernames, user IDs never change—even if a user changes their email address. Use user IDs when storing references to users in your own systems.
User Profile
Users have profile data that describes who they are. This information is available to your application (based on requested scopes) and appears in OIDC claims.
Basic Profile Fields
Name fields: first_name, last_name, middle_name, and display_name. The display name is what you’d typically show in your UI—if not set, you might fall back to combining first and last name.
Photo: A URL pointing to the user’s avatar or profile picture. Useful for displaying user images in your application without hosting them yourself.
Birthdate: Date of birth in YYYY-MM-DD format. Useful for age verification or personalization.
Nationalities: An array of country codes (ISO 3166-1) representing the user’s citizenships. Useful for compliance or localization purposes.
Address: A structured address object with street, city, postal code, region, and country. Useful if your application needs shipping addresses or location-based features.
Email Addresses and Phone Numbers
Users can have multiple email addresses and phone numbers (up to 5 of each). Each one has:
- Address/Number: The actual email or phone (E.164 format)
- Primary flag: Which one is the main contact method
- Verified flag: Whether the user has proven they control this email/phone
The primary email or phone is typically what’s used for communications like password resets. Verification status matters for security—unverified email addresses shouldn’t be trusted for sensitive operations.
When users have multiple emails: This is common when users have both personal and work email addresses. They might sign up with their personal email and later add their work email, or vice versa. Your application can let users choose which email to use for different purposes.
Custom Fields vs. Metadata vs. Claims
AuthPI provides three ways to store additional data on users:
Custom fields (up to 100 fields): Key-value pairs that can store strings, numbers, booleans, or null. These are visible to users and included in profile responses. Use custom fields for user-facing data that doesn’t fit the standard profile fields—things like “department”, “employee_id”, or “preferred_currency”.
Metadata (admin-only): Arbitrary data that’s never returned to users or client applications. Use metadata for internal information you need to track but shouldn’t expose—things like “internal_notes”, “sales_rep_id”, or “migration_source”.
Claims (up to 25): Data that appears in OIDC tokens and userinfo responses. Use claims when you need information available in ID tokens for authorization decisions—things like “role”, “tier”, or “feature_flags”.
The distinction matters:
- Custom fields are for user-visible profile extensions
- Metadata is for admin-only internal data
- Claims are for data your application needs in tokens
Authentication Methods (Verifiers)
Users authenticate using verifiers—the authentication factors they’ve registered. A user might have a password, a connected Google account, and a TOTP authenticator app, all as separate verifiers.
Password
The most common authentication method. AuthPI stores passwords using Argon2 hashing (the current industry standard for password hashing).
Password options:
- Expiration: You can set passwords to expire after a certain period, forcing password rotation.
- Must change flag: Force users to change their password on next login (useful after admin resets).
- Temporary passwords: Admin-created passwords that automatically expire, useful for initial setup or recovery.
When to use: Passwords are familiar to users and work everywhere. They’re a good default for most applications, especially combined with MFA.
Trade-offs: Users choose weak passwords, reuse them across sites, and fall for phishing. If you rely solely on passwords, consider enforcing strong password policies and encouraging (or requiring) MFA.
Passkeys (WebAuthn)
Passkeys are cryptographic credentials tied to a user’s device—fingerprint readers, Face ID, or hardware security keys. They’re phishing-resistant and more secure than passwords.
Users can register up to 5 passkeys. Each passkey stores:
- A credential ID and public key
- The device type (platform authenticator, security key, etc.)
- Optional device name for the user’s reference
When to use: Passkeys are excellent for security-conscious applications. They’re also increasingly user-friendly—synced passkeys work across devices via iCloud Keychain or Google Password Manager.
Trade-offs: Not all users have devices that support passkeys, and the experience can confuse users unfamiliar with the technology. Consider offering passkeys alongside passwords rather than requiring them.
OAuth Providers (Social Login)
Users can link accounts from external providers like Google, GitHub, Microsoft, or Apple. When linked, users can authenticate by signing into that provider.
Users can connect multiple OAuth providers (up to 5). Each connection stores:
- The provider name
- The user’s ID at that provider
- The email address from the provider (if available)
When to use: Social login reduces friction—users don’t need another password. It’s especially valuable for consumer applications and developer tools.
Trade-offs: You depend on third-party availability. If a user only has Google login and Google is down, they can’t sign in. Encourage users to add backup authentication methods.
TOTP (Authenticator Apps)
Time-based one-time passwords generated by apps like Google Authenticator, Authy, or 1Password. TOTP is typically used as a second factor, not primary authentication.
Each user can have one TOTP verifier storing:
- The shared secret (Base32 encoded)
- Algorithm settings (typically SHA1, 6 digits, 30-second period)
When to use: TOTP is the most widely supported MFA method. If you need two-factor authentication that works on virtually any device, TOTP is a safe choice.
Trade-offs: Users need to set up an authenticator app, which adds friction. Codes expire every 30 seconds, which can frustrate slow typists. If users lose their phone, they need backup codes to recover.
Backup Codes
One-time recovery codes that users store somewhere safe. Each code can only be used once. Users can have up to 20 backup codes.
When to use: Always offer backup codes when you enable MFA. They’re the last resort when users lose access to their other authentication methods.
Best practice: Generate backup codes when users enable MFA, and strongly encourage them to save the codes somewhere secure (password manager, printed copy in a safe). Display remaining code count so users know when they’re running low.
Email and SMS OTP
One-time passwords sent via email or SMS. These are typically used for passwordless login or as a second factor.
Email OTP: A numeric code sent to the user’s verified email address. The user enters the code to complete authentication.
Email Link (Magic Link): A clickable link sent to the user’s verified email. Clicking the link completes authentication—no code entry needed.
SMS OTP: A numeric code sent via SMS to the user’s verified phone number.
When to use: Email-based OTP works well for infrequent logins where users might forget passwords. SMS OTP is useful when you have users’ phone numbers and want a familiar experience.
Trade-offs: Email delivery can be slow or unreliable (spam filters). SMS has known security weaknesses (SIM swapping attacks). Neither is as secure as passkeys or TOTP, but both are better than passwords alone.
Combining Authentication Methods
Most production applications combine multiple verifiers. Common patterns:
Password + optional MFA:
- Primary: Password
- Optional second factor: TOTP or Passkey
- Recovery: Backup codes
This is familiar to users while allowing security-conscious users to add MFA.
Social login + password fallback:
- Primary: Google/GitHub OAuth (user’s choice)
- Fallback: Password (for when OAuth providers are down)
- Optional MFA: TOTP
This minimizes friction while providing backup options.
Passwordless:
- Primary: Passkey or Email link
- Recovery: Backup codes + Email OTP
This eliminates passwords entirely, which can improve security if your users are comfortable with passwordless flows.
User Lifecycle
Creation
Users can be created in several ways:
Self-registration: Users sign up through your application, subject to your Issuer’s signup policy (email verification, domain restrictions, etc.).
Admin creation: You create users through the Core API. Placement follows the API caller’s geography by default, or you can require a supported region or the EU jurisdiction for compliance-sensitive provisioning.
OAuth linking: A user authenticates with an OAuth provider (like Google) and AuthPI creates a new user account linked to that provider.
Invitation: An organization invites a user by email. The user completes registration when accepting the invite.
When a user is created, they start in active status with default scopes (typically openid and profile).
Verification
Email and phone verification are separate from authentication. A user might have a password but an unverified email address.
Why verification matters: Verified contact information is trusted for sensitive operations like password reset. If a user hasn’t verified their email, sending a password reset to that email is risky—someone else might control that inbox.
Verification flow: The user requests verification, receives an OTP code via email or SMS, and enters that code to prove they control the address. Codes expire after 15 minutes.
Status Changes
Users can be in one of five states:
Active: Normal operational state. The user can authenticate and use your application.
Suspended: A reversible administrative action. Suspended users cannot authenticate, but the suspension is meant to be temporary—pending review, policy violation investigation, etc.
When a suspended user tries to log in, they receive an informative error explaining they’re suspended (and optionally why). This helps legitimate users understand what happened and how to resolve it.
When to suspend: Use suspension for situations that might be resolved—a user reported for abuse that needs investigation, an account flagged for unusual activity that needs verification, or a user who violated terms but might be reinstated after review.
Blocked: A permanent security restriction. Blocked users cannot authenticate, and the system returns generic errors (not revealing that the account exists or is blocked).
When to block: Use blocking for confirmed security threats—fraud, confirmed abuse, or compromised accounts. Blocking is more severe than suspension and doesn’t provide information to potential attackers.
Pending Deletion: The user deletion process has started but hasn’t completed yet. Users in this state cannot authenticate and cannot be modified. They won’t appear in list results unless you explicitly filter by status=pending_deletion. See Deletion for details on the async deletion workflow.
Deleted: The user has been removed from the system. Deletion is permanent and cascades to all associated data (verifiers, sessions, organization memberships, personal tokens).
Account Lockout
AuthPI automatically locks accounts after repeated failed authentication attempts. By default:
- 5 failed attempts within a 15-minute window triggers lockout
- Lockout lasts 15 minutes and then automatically expires
- Lockout applies to password attempts (not all authentication methods)
This protects against brute-force attacks without permanently blocking legitimate users who forgot their password.
What happens during lockout: The user receives an error indicating they’re temporarily locked out. After the lockout period, they can try again. Successful authentication resets the failure counter.
Deletion
User deletion is asynchronous. When you call DELETE /users/{user_id}, AuthPI returns 202 Accepted and starts a background workflow that reliably cleans up all user data.
Deletion workflow:
- User marked as
pending_deletion— The user immediately cannot authenticate or be modified - Sessions revoked — All active sessions are terminated, which fires the same side effects as an explicit revoke: an OIDC backchannel logout for any session whose client has a
backchannel_logout_uri, and asession.terminatedwebhook event per session (withreason: "other"andreason_details: "user_deleted") - Personal tokens revoked — All API tokens for the user are invalidated
- Data cleaned up — Verifiers, organization memberships, and other user data are removed
- User removed — The user record is permanently deleted
Tracking deletion progress:
- Use
GET /users/{user_id}to check status - While deletion is in progress, status will be
pending_deletion - Once complete, the endpoint returns
404 Not Found
During pending deletion:
- The user cannot authenticate (all verification methods are blocked)
- The user data cannot be modified
- The user won’t appear in
GET /usersresults (unless you filter bystatus=pending_deletion)
What gets deleted:
- All verifiers (passwords, passkeys, TOTP secrets, OAuth links, etc.)
- All active sessions and their tokens
- All personal tokens (API tokens for scripts/integrations)
- All organization memberships
- All pending OTP operations
- Audit events are retained separately for compliance
Idempotency: Calling delete on a user already pending deletion is safe and returns 202 Accepted.
GDPR compliance: The async workflow satisfies “right to erasure” requirements. Deletion typically completes within seconds, but the workflow ensures reliability even if individual cleanup steps need to retry.
Hard delete: AuthPI performs hard deletes—user data is actually removed, not just marked as deleted. If you need to retain user records for compliance, export the data before initiating deletion.
Sessions
When a user authenticates, AuthPI creates a session. Sessions track the user’s logged-in state and are tied to the tokens issued to your application.
Session Lifecycle
- Creation: A session is created when the OAuth authorization flow begins, initially in
inactivestate. - Activation: After successful token issuance, the session becomes
active. - Active use: The session remains active while the user’s tokens are valid. Refresh token usage extends the session.
- Expiration or revocation: Sessions end when they expire (based on Issuer settings) or are explicitly revoked.
Session States
Inactive: Created but not yet used. This is the brief state between authorization and token issuance.
Active: Normal state. Tokens are valid, and refresh is allowed.
Expired: The session’s maximum lifetime was reached. The user needs to re-authenticate.
Revoked: The session was explicitly ended (user logout or admin action). All associated tokens are invalidated.
Suspended: Temporarily disabled. Tokens won’t work, but the session can be reactivated without full re-authentication.
Multiple Sessions
Users can have multiple active sessions—one for each device or browser where they’re logged in. This is normal and expected for users who access your application from their phone, laptop, and work computer.
Your application can:
- List a user’s active sessions (showing device info, last activity, location)
- Allow users to revoke individual sessions (log out a specific device)
- Revoke all sessions (log out everywhere)
This is valuable for security—if a user suspects their account was compromised, they can see all active sessions and revoke suspicious ones.
Tokens
Sessions are linked to the tokens your application uses:
ID Token
An OIDC token containing user identity information. ID tokens are short-lived (typically 5-15 minutes) and include:
- User ID (
subclaim) - Issuer ID (
issclaim) - Your client ID (
audclaim) - User profile claims (name, email, etc., based on requested scopes)
Your application validates the ID token to confirm user identity and extract profile information.
Access Token
An OAuth2 token used to access protected resources. Access tokens are also short-lived (typically 15-60 minutes) and include:
- User ID and session ID
- Granted scopes
- Expiration time
Your backend validates access tokens to authorize API requests.
Refresh Token
A longer-lived token (days to weeks) used to obtain new access tokens without requiring the user to re-authenticate. Refresh tokens are:
- Single-use (each use issues a new refresh token)
- Tied to a specific session
- Validated with strong consistency (replay attacks are detected)
If a refresh token is used twice (indicating it was stolen and replayed), AuthPI invalidates the entire session for security.
Organization Membership
Users can belong to multiple Organizations within their Issuer. Each membership includes:
Status: Whether the membership is active, pending (invited but not confirmed), or inactive.
Scopes: The user’s permissions within that organization. These are separate from the user’s global scopes—a user might have read-only access in one organization and admin access in another.
Title: An optional role title like “Manager”, “Developer”, or “Viewer”. This is for display purposes; actual permissions come from scopes.
Membership metadata: Admin-only data specific to this membership (not the user generally).
User Scopes vs. Membership Scopes
Users have two levels of scopes:
User scopes: Global permissions that apply regardless of organization context. These typically include OIDC scopes like openid, profile, and email, plus any application-specific global permissions.
Membership scopes: Organization-specific permissions that apply when the user is acting within that organization. These might include org:admin, org:member, billing:read, etc.
When your application needs to check permissions, consider whether the action is global (user scopes) or organization-specific (membership scopes).
Compliance and Preferences
Compliance Data
AuthPI tracks compliance-related information:
Country: The user’s country of residence, which may affect which regulations apply (GDPR, CCPA, etc.).
Policy acceptances: Records of when users accepted your terms of service, privacy policy, cookie policy, etc. Each acceptance includes the policy version and timestamp.
Age verification: A timestamp indicating when (and whether) the user’s age was verified, if your application requires age-gating.
This data helps you demonstrate compliance with various regulations and track which policy versions users have agreed to.
Preferences
Users can set preferences for their experience:
Language: Their preferred language (ISO 639-1 code like en or en-US). Use this for localization.
Timezone: Their timezone (IANA format like America/New_York). Use this for displaying dates and times.
Communication preferences:
- Security alerts (password changes, new logins from unknown devices)
- Product updates (new features, changes)
- Newsletters (marketing communications)
Respecting these preferences—especially for marketing communications—is important for user trust and regulatory compliance.
Managing Users
API Operations
Users are managed through the Core API:
| Operation | Endpoint | Response |
|---|---|---|
| Create user | POST /accounts/{account_id}/issuers/{issuer_id}/users | 201 Created |
| Get user | GET /accounts/{account_id}/issuers/{issuer_id}/users/{user_id} | 200 OK |
| List users | GET /accounts/{account_id}/issuers/{issuer_id}/users | 200 OK |
| Update user | PATCH /accounts/{account_id}/issuers/{issuer_id}/users/{user_id} | 200 OK |
| Delete user | DELETE /accounts/{account_id}/issuers/{issuer_id}/users/{user_id} | 202 Accepted |
Verifiers (authentication methods) have their own endpoints:
| Operation | Endpoint |
|---|---|
| List verifiers | GET .../users/{user_id}/verifiers |
| Add verifier | POST .../users/{user_id}/verifiers |
| Update verifier | PATCH .../users/{user_id}/verifiers/{verifier_id} |
| Delete verifier | DELETE .../users/{user_id}/verifiers/{verifier_id} |
Filtering and Pagination
When listing users, you can filter by:
- Status (
active,suspended,blocked,pending_deletion) - Username (exact match or prefix)
- Country
- Creation date range
By default, users with pending_deletion status are excluded from list results. To include them, explicitly filter by status=pending_deletion.
Results are paginated using cursor-based pagination—use limit and cursor parameters for large user bases.
Bulk Operations
For large-scale operations (importing users, mass updates), consider:
- Using the API with appropriate rate limiting
- Batching requests to avoid overwhelming the system
- Handling partial failures gracefully
AuthPI doesn’t currently have dedicated bulk endpoints, so large imports should be done with individual create requests, potentially parallelized.
Security Considerations
Protecting User Data
User data is sensitive. When working with AuthPI:
- Never log tokens or credentials. Access tokens and especially refresh tokens should never appear in logs.
- Use metadata for internal data. Metadata is never returned to clients, so sensitive internal notes belong there.
- Be careful with custom fields. Custom fields are returned in profile responses—don’t store sensitive data there unless you want users to see it.
Verifier Security
- Passwords are hashed. AuthPI stores Argon2 hashes, not plaintext passwords. You cannot retrieve a user’s password.
- OAuth tokens aren’t stored. AuthPI doesn’t store OAuth access tokens from providers—only the provider user ID for linking.
- TOTP secrets are sensitive. The TOTP secret is stored encrypted but should never be displayed to users after initial setup.
Session Security
- Sessions are bound to tokens. Revoking a session invalidates all associated tokens.
- Refresh token rotation detects theft. If a refresh token is used twice, the session is terminated.
- Device fingerprinting adds security. Optionally detect when sessions are used from unexpected devices.
Example Scenarios
E-commerce Application
User setup:
- Username type: Email
- Authentication: Password + Google OAuth
- Profile: Name, email, addresses (for shipping)
- Custom fields:
loyalty_tier,preferred_store
Session settings:
- Long sessions (30 days) for convenience
- No idle timeout (users browse intermittently)
- Refresh tokens enabled
Users can save addresses, track orders, and stay logged in across shopping sessions.
B2B SaaS Platform
User setup:
- Username type: Email (work emails)
- Authentication: Password + SAML/SSO (for enterprise customers) + TOTP (MFA)
- Profile: Name, email, phone
- Custom fields:
department,employee_id - Claims:
role,team
Organization usage:
- Each customer company is an Organization
- Users belong to their company’s Organization
- Membership scopes define role within company (
admin,member,viewer)
Session settings:
- Shorter sessions (14 days)
- Idle timeout (4 hours) for security
- Device fingerprinting enabled
Developer Platform
User setup:
- Username type: Email
- Authentication: GitHub OAuth + Password fallback + TOTP
- Profile: Name, email, display name
- Custom fields:
github_username,plan
Personal tokens:
- Enabled for API access from CLI tools and scripts
- Users can create up to 10 personal tokens
- Tokens have optional expiration and scope restrictions
- Personal tokens are signed JWTs, so they stop working after at most 21 days regardless of any longer expiration you request—even if the token record stores a later expiry, the token’s
expclaim is clamped to 21 days. See JWKS & key rotation for why.
Developers can authenticate to the API using personal tokens from their local development environment.
Next Steps
- Understand how users authenticate via Clients
- Learn about grouping users into Organizations
- See the Quick Start guide for implementing user authentication
- Explore Events to monitor user activity