Session
Data Entity
Description
Represents an authenticated user session, tracking device context, authentication method, activity timestamps, and revocation state. Sessions are created at login and revoked at logout or by administrative action. Each session is tied to a JWT JTI claim enabling token blocklisting without database lookups on every request.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key. Uniquely identifies the session across all tenants. | PKrequiredunique |
user_id |
uuid |
Foreign key to the users table. Identifies which user this session belongs to. | required |
organization_id |
uuid |
Organization context at the time of session creation. Denormalized from the user record for fast tenant-scoped session queries without joining users. | required |
jti |
string |
JWT ID claim. Unique identifier embedded in the issued access token. Used by the token blocklist to revoke individual tokens without expiry waiting. Generated as a UUID at token issuance time. | requiredunique |
auth_method |
enum |
Authentication method used to create this session. Determines which flow produced the session and is surfaced in security dashboards. | required |
device_type |
enum |
The class of device from which this session was created. Used to scope revocation and display in session management UI. | required |
device_name |
string |
Human-readable device label (e.g. 'iPhone 15 Pro', 'Chrome on MacBook'). Sourced from the User-Agent string or device info at login. Displayed in session management screens. | - |
ip_address |
string |
IP address at session creation time. Stored for security audit and anomaly detection. IPv4 or IPv6 string representation. | - |
user_agent |
string |
Full User-Agent header string at session creation. Used for device name derivation and security audit trail. | - |
created_at |
datetime |
Timestamp when the session was created (login event). Stored in UTC. Used for session age calculations and audit reporting. | required |
last_active_at |
datetime |
Timestamp of the most recent authenticated API request on this session. Updated on token refresh. Used to detect idle sessions in the security dashboard. | required |
expires_at |
datetime |
Timestamp when the session (and its associated refresh token) expires. After this point, the session is treated as inactive regardless of revocation state. | required |
is_active |
boolean |
Whether the session is currently valid. Set to false on logout, admin revocation, or security-triggered invalidation. Used as a fast filter in session queries before checking expiry. | required |
revoked_at |
datetime |
Timestamp when the session was explicitly revoked. NULL if the session has not been revoked. Populated together with is_active = false. | - |
revocation_reason |
enum |
The reason a session was revoked. Displayed in audit logs and security dashboards to distinguish user-initiated logout from administrative or security actions. | - |
refresh_token_id |
uuid |
Foreign key to the refresh_tokens table. Links the session to its associated long-lived refresh token. NULL until the first token issuance completes. | unique |
Database Indexes
idx_session_user_id
Columns: user_id
idx_session_jti
Columns: jti
idx_session_organization_id_active
Columns: organization_id, is_active
idx_session_user_active
Columns: user_id, is_active
idx_session_expires_at
Columns: expires_at
idx_session_created_at
Columns: created_at
Validation Rules
user_id_must_reference_active_user
error
Validation failed
jti_must_be_unique
error
Validation failed
expires_at_must_be_future
error
Validation failed
auth_method_must_match_flow
error
Validation failed
revocation_reason_required_when_revoked
error
Validation failed
organization_id_matches_user
error
Validation failed
ip_address_format
warning
Validation failed
Business Rules
single_active_session_per_device
When a new session is created for a user on a device_type+device_name combination that already has an active session, the existing session is revoked with reason 'logout' before the new one is created. Prevents ghost sessions accumulating from repeated logins on the same device.
session_revoked_on_password_change
When a user changes their password, all active sessions except the one performing the change are revoked with reason 'password_change'. This prevents compromised credential sessions remaining valid after a password reset.
session_revoked_on_account_deactivation
When an admin deactivates a user account, all sessions for that user are immediately revoked with reason 'account_deactivated'. Active JTIs are also added to the token blocklist for the remaining access token lifetime.
jti_blocklisted_on_revocation
When a session is revoked while its access token has not yet expired, the JTI is written to the token blocklist with TTL equal to the token's remaining lifetime. This ensures the now-revoked access token cannot be used even before it expires.
admin_cannot_revoke_own_session
An administrator performing session revocation via the session management page cannot revoke their own current session through the bulk-revoke-all-for-user action. The UI and service layer both enforce this to prevent accidental self-lockout.
org_admin_scope_isolation
An Organization Admin querying sessions can only retrieve sessions belonging to users within their own organization. Global Admins may query across all organizations. This is enforced at the service layer using the organization_id column.
last_active_updated_on_token_refresh
Each time a refresh token is exchanged for a new access token, the session's last_active_at timestamp is updated. This keeps the security dashboard's idle session detection accurate.
expired_sessions_excluded_from_active_queries
All session list queries filter by both is_active = TRUE and expires_at > NOW(). Sessions that have expired but were not explicitly revoked are treated as inactive. A nightly cleanup job sets is_active = false on expired sessions.