core PK: id 11 required 3 unique

Description

Represents an authenticated user session, tracking the lifecycle of access and refresh tokens issued by the Authentication Module. Supports email/password, BankID, Vipps, biometric, and WebAuthn auth methods. Sessions are scoped per user and per device, enabling multi-device support, admin-initiated revocation, and forced expiry. The auth module owns only identity and session state — authorization logic lives in consuming products.

21
Attributes
6
Indexes
7
Validation Rules
20
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key — unique session identifier issued at session creation
PKrequiredunique
user_id uuid Foreign key to users. One user may have many concurrent sessions across devices and platforms.
required
organization_id uuid Tenant scoping for per-organization signing material isolation. Global Admins have null organization_id since they have no default org context.
-
auth_method enum Authentication method used to establish this session. Biometric sessions derive from an existing active session and do not create independent credential chains.
required
access_token_hash string SHA-256 hash of the issued JWT access token. Never stored in plaintext. Used for token lookup and invalidation checks.
requiredunique
refresh_token_hash string SHA-256 hash of the rotating refresh token. Rotated on every use — old hash is invalidated immediately on refresh.
requiredunique
status enum Lifecycle state of the session. Revoked and expired sessions are retained for audit purposes and not deleted.
required
revocation_reason enum Reason the session was terminated. Null for active sessions.
-
revoked_by_user_id uuid User ID of the admin or system actor who revoked this session. Null if the session expired naturally or the user logged out themselves.
-
client_type enum Which product client established this session. Determines token storage expectations: mobile uses secure platform store, admin portal uses HTTP-only cookies.
required
device_fingerprint string Non-identifying device identifier derived from device attributes. Used for session grouping in the Session Management UI and detecting suspicious multi-device activity.
-
device_name string Human-readable device label (e.g. 'iPhone 15', 'Chrome on macOS') shown in the Session Management UI so admins can identify sessions meaningfully.
-
ip_address string IP address at session creation time. Stored for audit and security dashboard display. IPv4 or IPv6.
-
user_agent string HTTP User-Agent header at session creation. Used for device type inference in the Session Management UI.
-
access_token_expires_at datetime Expiry timestamp for the short-lived access token. Typically 15–60 minutes from issuance. Client must refresh before this time using the refresh token.
required
refresh_token_expires_at datetime Expiry timestamp for the refresh token chain. When this passes the session is definitively over and the user must re-authenticate fully.
required
last_activity_at datetime Timestamp of the most recent successful API call made with this session's access token. Used by the Session Management UI for inactivity display.
-
revoked_at datetime Timestamp when the session was explicitly revoked. Null for active or naturally-expired sessions.
-
module_context json Snapshot of the enabled module set for this user's organization at session creation time. Embedded in access tokens as a claims bag so clients can render navigation without an extra API call.
-
created_at datetime Timestamp when the session was first established (initial sign-in).
required
updated_at datetime Timestamp of the most recent session record mutation (status change, token rotation).
required

Database Indexes

idx_sessions_user_id_status
btree

Columns: user_id, status

idx_sessions_access_token_hash
btree unique

Columns: access_token_hash

idx_sessions_refresh_token_hash
btree unique

Columns: refresh_token_hash

idx_sessions_organization_id_status
btree

Columns: organization_id, status

idx_sessions_refresh_token_expires_at
btree

Columns: refresh_token_expires_at

idx_sessions_created_at
btree

Columns: created_at

Validation Rules

access_token_hash_must_be_sha256 error

Validation failed

refresh_token_expires_after_access_token error

Validation failed

status_transition_must_be_forward_only error

Validation failed

revoked_session_requires_revocation_fields error

Validation failed

organization_id_must_match_user_membership error

Validation failed

ip_address_format_valid warning

Validation failed

client_type_consistent_with_auth_method error

Validation failed

Business Rules

refresh_token_rotation_on_use
on_update

Every time a refresh token is exchanged for a new access token, the old refresh_token_hash is immediately invalidated and a new one is issued. The session record is updated atomically. Reuse of a consumed refresh token triggers immediate session revocation and a security event.

refresh_token_reuse_terminates_session
on_update

If a previously consumed refresh_token_hash is presented again, the session is immediately revoked with reason 'refresh_token_reuse' and a security event is emitted. This defends against token theft scenarios where a stolen refresh token is used after the legitimate owner has already rotated it.

biometric_unlock_does_not_create_new_session
on_create

Biometric authentication (Face ID / fingerprint) unlocks access to an existing active session — it does not create a new credential chain. The auth_method is recorded as 'biometric_unlock' referencing the original session, which retains its own access_token_expires_at and refresh_token_expires_at.

global_admin_session_has_no_organization_context
on_create

Sessions created by Global Admins must have organization_id set to null. The auth module issues tokens with no org claims. Authorization for support access is time-bounded via organization_settings.support_access_until and is not embedded in the session record.

admin_revocation_logged_to_audit_trail
on_update

Any session revocation initiated by an org admin or global admin via the Session Management UI must produce an audit_logs entry for the organization whose user's session was revoked. Revoked_by_user_id and revocation_reason must both be set.

support_access_expiry_triggers_session_revocation
always

When a Global Admin's time-bounded support access expires (organization_settings.support_access_until passes), all active sessions for that global admin scoped to the org must be revoked immediately with reason 'support_access_expired'.

module_context_embedded_at_creation
on_create

At session creation the enabled module set for the user's organization is embedded in module_context and encoded into the access token claims bag. Clients read this on bootstrap to assemble navigation without an extra API call. The module context is refreshed on token rotation if the organization's module configuration has changed.

expired_sessions_retained_for_audit
always

Sessions are never hard-deleted on expiry. Expired sessions remain in the table with status='expired' to support the Audit Log and Security Dashboard. Archival (moving to cold storage) occurs after 1 year.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_date
Retention
archive_after_1year