core PK: id 9 required 1 unique

Description

Represents an active authenticated session for a user, tracking login method, device, and session lifetime. Sessions are created on successful authentication and invalidated on logout, token expiry, or forced revocation by an administrator. Provides the audit trail for login events.

15
Attributes
6
Indexes
8
Validation Rules
19
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Globally unique session identifier, generated server-side on session creation
PKrequiredunique
user_id uuid Foreign key referencing the users table; identifies which user owns this session
required
login_method enum The authentication method used to establish this session. Determines which identity provider was invoked and shapes token refresh behavior.
required
device_info json Structured metadata about the client device: platform (ios|android|web), OS version, app version, and a stable device fingerprint derived from hardware identifiers. Used for audit display and concurrent session management.
required
ip_address string IPv4 or IPv6 address of the client at session creation time. Stored for security audit purposes. Nullable for privacy-sensitive login flows.
-
user_agent string HTTP User-Agent string captured at session creation. Supplements device_info for audit trail completeness.
-
created_at datetime UTC timestamp of when this session was established via successful authentication. Immutable after creation.
required
expires_at datetime UTC timestamp after which this session is considered expired and must be rejected. Set at creation based on login_method: longer for biometric, shorter for email_password. Must be strictly greater than created_at.
required
last_active_at datetime UTC timestamp of the most recent API request authenticated by this session. Updated on every authenticated request via JWT middleware. Used to detect inactive sessions and for session sliding expiry policies.
-
invalidated_at datetime UTC timestamp when this session was explicitly invalidated (logout, admin revocation, password change, security event). NULL means session is still potentially active. Non-NULL means session is permanently rejected regardless of expires_at.
-
invalidation_reason enum The reason this session was terminated. Only populated when invalidated_at is non-NULL. Required when invalidated_at is set.
-
organization_id uuid The organization context active at the time of session creation. Matches the user's selected organization during onboarding or org-switch. Used for multi-tenancy scoping during session validation.
required
association_id uuid The specific local association context active when the session was created, if applicable. Nullable for global administrators who are not tied to a single association.
-
role_at_creation enum The user role resolved and embedded in the JWT at session creation time. Stored here for audit and to detect role changes that occurred during an active session.
required
biometric_enrolled boolean Whether the user enrolled biometric authentication (Face ID / fingerprint) during or after this session. Set to true when biometric setup completes. Drives whether biometric_auth_service may use this session's refresh token.
required

Database Indexes

idx_session_user_id
btree

Columns: user_id

idx_session_user_active
btree

Columns: user_id, invalidated_at

idx_session_expires_at
btree

Columns: expires_at

idx_session_created_at
btree

Columns: created_at

idx_session_login_method
btree

Columns: login_method

idx_session_organization_id
btree

Columns: organization_id

Validation Rules

user_id_must_reference_existing_user error

Validation failed

login_method_enum_strict error

Validation failed

device_info_json_schema error

Validation failed

invalidation_reason_required_with_invalidated_at error

Validation failed

ip_address_format error

Validation failed

organization_id_matches_user_membership error

Validation failed

association_id_consistent_with_organization error

Validation failed

role_at_creation_consistent_with_user_roles error

Validation failed

Business Rules

session_created_only_on_successful_auth
on_create

A Session record may only be inserted after the authentication provider (email/password, BankID, Vipps) has returned a verified success response. Failed login attempts must not produce session rows.

expires_at_must_be_future
on_create

expires_at must always be strictly after created_at. The expiry window depends on login_method: email_password (8 hours), bankid/vipps (24 hours), biometric (30 days sliding).

Enforced by: Auth Service
invalidated_at_is_terminal
always

Once invalidated_at is set on a session, no further authentication operations may succeed using tokens derived from that session. This state is permanent and cannot be reversed.

logout_invalidates_session
on_update

When a user explicitly logs out, the current session's invalidated_at must be set to now() and invalidation_reason set to 'logout'. All associated auth_token records must be revoked simultaneously within the same transaction.

admin_revocation_invalidates_all_user_sessions
on_update

When an Organization Administrator or Global Administrator deactivates a user, all active sessions for that user must be invalidated with reason 'admin_revocation'. This prevents deactivated users from continuing to use the app on an existing session.

biometric_requires_prior_full_auth_session
on_create

Biometric authentication (login_method: biometric) can only establish a new session if the user previously completed a full BankID, Vipps, or email/password session from which a refresh token was stored. Pure biometric-only initial login is prohibited.

role_change_invalidates_active_sessions
on_update

If a user's role assignment changes (e.g., promoted from peer_mentor to coordinator), all existing sessions where role_at_creation differs from the new role must be invalidated with reason 'security_event', forcing re-authentication to issue a new JWT with correct role claims.

last_active_at_updated_on_authenticated_request
always

Every authenticated API request that passes JWT validation must update last_active_at to the current UTC time. This provides an accurate activity signal for inactive session cleanup jobs.

max_concurrent_sessions_per_user
on_create

A user may not exceed 5 concurrent active sessions simultaneously (one per device/platform). If a new session creation would breach this limit, the oldest active session is invalidated with reason 'concurrent_session_limit'.

Enforced by: Auth Service

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_date
Retention
archive_after_1year

Entity Relationships

auth_token
outgoing one_to_many

A session may be associated with one or more token records (access + refresh pair)

optional cascade delete
user
incoming one_to_many

A user can have multiple active sessions across different devices

required cascade delete