Auth Data Model
Data Models
Section titled “Data Models”Seamless Auth is built on a relational model that keeps users, sessions, passkeys, organizations, events, and configuration explicit and inspectable.
This page focuses on the core entities in seamless-auth-api and how they relate.
Mental Model
Section titled “Mental Model”User -> has many -> SessionsUser -> has many -> CredentialsUser -> has many -> Auth EventsUser -> has many -> Magic Link TokensUser -> has many -> OAuth IdentitiesUser -> has many -> TOTP CredentialsUser -> has many -> Organization Memberships
Organization -> has many -> Organization MembershipsSession -> may point to -> Active Organization
System -> configured by -> System ConfigBootstrap -> handled by -> Bootstrap InvitesUsers represent authenticated identities.
| Field | Type | Description |
|---|---|---|
id | uuid | Unique user ID |
email | string | Unique email |
phone | string | Unique phone |
roles | string[] | Global roles assigned to the user |
revoked | boolean | Whether auth is disabled |
emailVerificationToken | string | null | In-progress email verification token |
phoneVerificationToken | string | null | In-progress phone verification token |
emailVerified | boolean | Email verification state |
phoneVerified | boolean | Phone verification state |
verified | boolean | Fully verified state |
challenge | string | null | In-progress auth challenge |
challengeContext | json | null | Context for an in-progress challenge |
lastLogin | timestamp | null | Last successful login |
Users have child records for passkeys, sessions, OAuth identities, organization memberships, TOTP credentials, and auth events.
Sessions
Section titled “Sessions”Sessions are first-class records, not just opaque browser state.
| Field | Type | Description |
|---|---|---|
id | uuid | Session ID |
userId | uuid | Owning user |
infraId | string | null | Infra/session context identifier |
organizationId | uuid | null | Active organization context for the session |
mode | 'server' | Session mode currently stored by the auth API |
refreshTokenHash | string | Stored refresh token hash |
refreshTokenLookup | string | null | Indexed refresh-token lookup fingerprint |
lastUsedAt | timestamp | Last activity timestamp |
expiresAt | timestamp | Absolute expiration |
idleExpiresAt | timestamp | Idle expiration |
stepUpVerifiedAt | timestamp | null | Time of last fresh step-up verification |
stepUpMethod | string | null | Step-up method, such as webauthn or totp |
deviceName | string | null | Friendly device label |
userAgent | string | null | Request device/browser info |
ipAddress | string | null | Request origin |
replacedBySessionId | uuid | null | Rotation link |
revokedAt | timestamp | null | Revocation time |
revokedReason | string | null | Revocation reason |
Refresh tokens are stored as hashes and lookup fingerprints, not as raw refresh tokens.
Credentials
Section titled “Credentials”Credentials store passkeys and related metadata.
| Field | Type | Description |
|---|---|---|
id | string | Credential ID |
userId | uuid | Owning user |
publicKey | binary | WebAuthn public key |
counter | number | Replay-protection counter |
transports | json | Transport hints |
deviceType | string | null | Credential device type |
backedup | boolean | Whether the credential is backed up |
prfCapable | boolean | Whether registration reported PRF support |
friendlyName | string | null | User-friendly label |
lastUsedAt | timestamp | null | Last usage |
platform | string | null | Platform classification |
browser | string | null | Browser classification |
deviceInfo | string | null | Device description |
PRF output is not stored in credential records. Only PRF capability metadata is stored.
Organizations
Section titled “Organizations”Organizations group users for tenant-style access and active-session context.
| Field | Type | Description |
|---|---|---|
id | uuid | Organization ID |
name | string | Display name |
slug | string | Unique slug |
createdByUserId | uuid | null | User who created the organization |
metadata | json | null | Caller-defined metadata |
Organization Memberships
Section titled “Organization Memberships”Memberships connect users to organizations.
| Field | Type | Description |
|---|---|---|
id | uuid | Membership ID |
organizationId | uuid | Owning organization |
userId | uuid | Member user |
roles | string[] | Roles inside the organization |
scopes | string[] | Organization-scoped permissions |
The database enforces one membership per (organizationId, userId) pair.
OAuth Identities
Section titled “OAuth Identities”OAuth identities link external provider accounts to local users.
| Field | Type | Description |
|---|---|---|
id | uuid | OAuth identity ID |
userId | uuid | Local user |
providerId | string | Provider config ID, such as google |
providerSubject | string | Provider subject/user ID |
email | string | Email from provider profile |
profile | jsonb | null | Redacted provider profile fields |
The auth API enforces uniqueness on (providerId, providerSubject).
TOTP Credentials
Section titled “TOTP Credentials”TOTP credentials store encrypted authenticator-app secrets.
| Field | Type | Description |
|---|---|---|
id | uuid | TOTP credential ID |
userId | uuid | Owning user |
secretCiphertext | text | Encrypted TOTP secret |
secretIv | string | Encryption IV |
secretTag | string | Encryption authentication tag |
issuer | string | TOTP issuer |
accountName | string | TOTP account label |
enabled | boolean | Whether the credential can be used |
verifiedAt | timestamp | null | Enrollment verification time |
lastUsedAt | timestamp | null | Last successful use |
lastUsedCounter | number | null | Replay prevention counter |
Production deployments should provide TOTP_SECRET_ENCRYPTION_KEY.
Magic Link Tokens
Section titled “Magic Link Tokens”Magic links are stored as explicit records with request-context hashes.
| Field | Type | Description |
|---|---|---|
id | uuid | Token ID |
user_id | uuid | Associated user |
token_hash | string | Hashed magic link token |
redirect_url | string | null | Post-verification target |
ip_hash | string | null | Request IP hash |
user_agent_hash | string | null | Request user-agent hash |
expires_at | timestamp | Expiration |
used_at | timestamp | null | Usage marker |
Auth Events
Section titled “Auth Events”Auth events are the audit trail for the authentication system.
| Field | Type | Description |
|---|---|---|
id | uuid | Event ID |
user_id | uuid | null | Associated user |
type | string | Event type |
ip_address | string | null | Origin IP |
user_agent | string | null | Device info |
metadata | jsonb | null | Redacted event context |
Events cover registration, login, OTP, magic links, WebAuthn, OAuth, TOTP, admin actions, suspicious requests, and recovery flows.
System Config
Section titled “System Config”System config controls auth behavior such as:
default_rolesavailable_roleslogin_methodspasskey_login_fallback_enabledoauth_providerslockout_policyaccess_token_ttlrefresh_token_ttlrate_limitdelay_afterrpidorigins
Raw secrets should stay in environment variables or a secret manager, not in system_config.
Bootstrap Invites
Section titled “Bootstrap Invites”Bootstrap invites are used for the first admin flow.
| Field | Type | Description |
|---|---|---|
id | uuid | Invite ID |
email | string | Target email |
role | 'admin' | Assigned bootstrap role |
tokenHash | string | Invite token hash |
expiresAt | timestamp | Expiration |
consumedAt | timestamp | null | Usage marker |
createdBy | string | Creation source |
createdIp | string | null | Creation request IP |
createdUserAgent | text | null | Creation request user agent |
lastSentAt | timestamp | null | Last invite send |
attemptCount | number | Invite attempts |
Key Relationships
Section titled “Key Relationships”users.id -> sessions.userIdusers.id -> credentials.userIdusers.id -> auth_events.user_idusers.id -> magic_link_tokens.user_idusers.id -> oauth_identities.user_idusers.id -> totp_credentials.user_idusers.id -> organization_memberships.user_id
organizations.id -> organization_memberships.organization_idsessions.organizationId -> organizations.idWhy This Model Matters
Section titled “Why This Model Matters”- users carry global roles directly, which keeps baseline authorization explicit
- organization memberships add tenant-level roles and scopes without hiding the global user model
- sessions are durable records, which makes revocation, active organization context, and step-up freshness inspectable
- credentials are first-class objects, which supports passkey management and PRF capability metadata
- auth events provide an audit trail and feed dashboard metrics
- system config is explicit instead of hidden inside code
Next Step
Section titled “Next Step”Continue to Sessions.