core PK: id 8 required 1 unique

Description

Represents an authenticated user session in the Meander platform. Each login event creates one session record that anchors the entire token chain lifecycle. Short-lived JWTs carry the session ID as a claim; rotating refresh tokens (refresh_tokens child records) silently extend the session across access token expiry. Sessions terminate via user sign-out, idle timeout, hard expiry, or administrator-initiated revocation. The auth module owns session state exclusively — no product data, role semantics, or authorization logic is stored here.

16
Attributes
5
Indexes
6
Validation Rules
15
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key. Unique session identifier embedded in every access token as the `sid` claim, enabling per-session revocation checks without hitting the database on every request (checked only on token refresh).
PKrequiredunique
user_id uuid FK → users.id. The authenticated user who owns this session. All refresh tokens under this session inherit this ownership.
required
org_id uuid FK → organizations.id. Organization context resolved at login time from the user's primary membership. Null for global admins who have no org context. Included in access token claims for tenant-scoped API enforcement.
-
auth_method enum Authentication mechanism used to initiate this session. Biometric unlock is not listed here — it reuses an existing session rather than creating a new one.
required
platform enum Client platform that opened this session. Shown on the Active Sessions admin page and used for security anomaly detection.
required
device_id string Opaque device fingerprint supplied by the mobile client (Flutter platform channel). Null for web sessions. Used to correlate multiple sessions from the same physical device.
-
user_agent string HTTP User-Agent header captured at login. Displayed on the Active Sessions admin page so administrators can identify suspicious clients.
-
ip_address string Client IP address (IPv4 or IPv6, max 45 chars) at login time. Used by the Security Metrics Service for anomaly detection and geographic risk scoring.
-
is_revoked boolean Hard revocation flag. When true, all refresh_tokens rows with this session_id are also logically invalidated. Access tokens already in flight remain valid until their short TTL expires (no token blocklist required).
required
revoked_at datetime UTC timestamp of revocation. Null while session is active. Set atomically with is_revoked=true.
-
revoked_by_user_id uuid user_id of the administrator who force-revoked this session via the Active Sessions admin page. Null for user-initiated sign-out or system expiry.
-
revocation_reason enum Categorized reason for revocation. Written to the audit log on revocation events.
-
expires_at datetime Hard expiry for the entire session chain. After this datetime no refresh token belonging to this session may be exchanged, regardless of is_revoked state. Typically 90 days from creation for mobile, 24 hours for web.
required
last_active_at datetime Updated on every successful token refresh. Used to enforce an idle-session timeout policy (e.g. revoke if inactive for 30 days) via a background cleanup job.
required
module_set_snapshot json Snapshot of the tenant's enabled area/module IDs at login time (e.g. ["activity-registration", "expense-reimbursement"]). Embedded in access token claims so the mobile app can bootstrap navigation without a separate API call. Refreshed on the next token rotation if the org's module configuration changes.
-
created_at datetime UTC timestamp of the login event that created this session.
required

Database Indexes

idx_sessions_user_id
btree

Columns: user_id

idx_sessions_user_id_active
btree

Columns: user_id, is_revoked, expires_at

idx_sessions_org_id
btree

Columns: org_id

idx_sessions_expires_at
btree

Columns: expires_at

idx_sessions_last_active_at
btree

Columns: last_active_at

Validation Rules

expires_at_in_future error

Validation failed

revocation_fields_consistent error

Validation failed

auth_method_platform_compatibility error

Validation failed

user_id_references_active_user error

Validation failed

ip_address_format warning

Validation failed

module_set_snapshot_valid_json warning

Validation failed

Business Rules

single_active_session_per_device
on_create

When a new session is created from the same device_id as an existing active session, the old session is revoked with reason 'token_rotation_failure' before the new one is inserted. Prevents ghost sessions accumulating on re-installs.

Enforced by: Auth Service
session_inherits_org_context
on_create

org_id is resolved from the user's primary organization membership at login and is immutable for the lifetime of the session. If the user's membership changes, the change takes effect on next login, not mid-session.

cascade_revoke_refresh_tokens
on_update

When is_revoked is set to true on a session, all refresh_tokens rows where session_id = this session's id must be invalidated in the same transaction. No dangling active refresh tokens may exist under a revoked session.

admin_revocation_requires_audit
on_update

Any revocation where revoked_by_user_id is non-null (admin-forced) must produce an audit log entry via the Audit Service before the transaction commits.

module_set_refreshed_on_rotation
on_update

On each token refresh, auth-service compares the stored module_set_snapshot against the org's current module configuration. If different, the snapshot is updated and the new access token carries the updated module set.

hard_expiry_non_extendable
always

expires_at is set once at creation and is never extended, even for highly active sessions. Mobile sessions expire after 90 days; web sessions after 24 hours. Users must re-authenticate after expiry.

Enforced by: Auth Service
account_deactivation_triggers_revocation
on_update

When a user account is deactivated (via admin user management), all active sessions for that user_id are batch-revoked with reason 'account_deactivated'.

global_admin_no_org_context
on_create

Sessions created for users with the Global Admin role must have org_id = null. Any attempt to set an org_id for a Global Admin session is rejected.

Enforced by: Auth Service

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
archive_after_1year