Session Management

UniAuth uses server-side session management backed by secure HTTP-only cookies. Every authenticated action is tied to a session record that tracks the device, location, and activity of each sign-in. This page explains how sessions work, how to manage them, and how they interact with OAuth tokens.

Overview

When a user signs in, UniAuth creates a session record in the database and issues a signed JWT stored in a secure, HTTP-only, SameSite cookie named auth_token. The JWT contains the user's ID, email, name, avatar, and role. The cookie has a 7-day expiration, but the session itself is subject to additional server-side controls described below.

Each session is also signed with an ML-DSA-44 (FIPS 204) post-quantum digital signature, providing forward security against future quantum computing threats.

Session Lifecycle

A session moves through three states:

  1. Created — On successful login (including 2FA verification if enabled), a new session row is inserted with the user's IP address, User-Agent, and a device fingerprint hash.
  2. Active — The session remains active as long as the user makes requests within the inactivity window. Each request updates the last_activity_at timestamp.
  3. Terminated — The session ends when the user logs out, the session is revoked (by the user or an admin), the inactivity timeout is exceeded, or the user changes their password.

Concurrent Session Limits

Each user can have a maximum of 10 concurrent active sessions (configurable by administrators). This allows users to stay signed in across multiple devices (laptop, phone, tablet) without accumulating stale sessions.

When a new login would exceed the limit, the oldest session is automatically revoked to make room. This happens transparently and does not prevent the new sign-in.

Tip: If you are frequently hitting the session limit, review your active sessions at Account → Sessions and revoke any you no longer need.

Inactivity Timeout

Sessions expire after 24 hours of inactivity (configurable by administrators). Every authenticated request refreshes the timer by updating the session's last_activity_at timestamp. If no request is made within 24 hours, the session is considered expired and the user must sign in again.

This means that an active user who uses the application daily will never be unexpectedly signed out, while abandoned sessions are automatically cleaned up.

// Session activity flow
// 1. User makes a request at 10:00 AM → last_activity_at = 10:00 AM
// 2. User makes another request at 2:00 PM → last_activity_at = 2:00 PM
// 3. User does not return until the next day at 3:00 PM (25h gap)
// 4. Session is expired → user is redirected to login

Viewing Active Sessions

You can view all of your active sessions from your account dashboard:

  1. Navigate to AccountSessions.
  2. Each session displays the device type, browser, IP address, and last activity time.
  3. Your current session is highlighted so you can distinguish it from other devices.

The sessions list is also available via the API:

GET /api/user/sessions

// Response:
{
  "sessions": [
    {
      "id": "session-uuid",
      "ipAddress": "192.168.1.100",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
      "lastActivityAt": "2025-01-15T14:30:00Z",
      "createdAt": "2025-01-15T09:00:00Z",
      "isCurrent": true
    },
    {
      "id": "session-uuid-2",
      "ipAddress": "10.0.0.50",
      "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)...",
      "lastActivityAt": "2025-01-15T12:15:00Z",
      "createdAt": "2025-01-14T20:00:00Z",
      "isCurrent": false
    }
  ]
}

Revoking Sessions

There are several ways to terminate sessions:

Revoke a Single Session

From the sessions page, click the revoke button next to any session. This is useful when you notice a session from an unrecognized device or location.

DELETE /api/user/sessions/:sessionId

// Response:
{
  "success": true,
  "message": "Session revoked"
}

Revoke All Other Sessions

If you suspect your account has been compromised, you can revoke all sessions except the one you are currently using:

POST /api/user/sessions/revoke-all

// Response:
{
  "success": true,
  "message": "All other sessions revoked",
  "revokedCount": 3
}

Automatic Revocation on Password Change

When you change your password, UniAuth automatically revokes all sessions except your current one. This ensures that if someone else had access to your account, they are immediately signed out across all devices.

Session Security

UniAuth applies multiple layers of security to each session:

Device Fingerprinting

Every session is fingerprinted using a SHA-256 hash of the client's IP address and User-Agent string. The fingerprint is stored in the fingerprint_hash column. If a subsequent request arrives with a different fingerprint than what was recorded at login, the system flags a potential session hijacking attempt.

Post-Quantum Signatures

Each session includes an ML-DSA-44 (FIPS 204) post-quantum digital signature. This signature proves the session was issued by this UniAuth instance and has not been tampered with. The signing keypair is generated at server startup and stored encrypted in the database.

Secure Cookie Attributes

The session cookie is configured with security best practices:

  • HttpOnly — Not accessible to client-side JavaScript, preventing XSS theft
  • Secure — Only sent over HTTPS in production
  • SameSite=Lax — Prevents the cookie from being sent in cross-site requests
  • Path=/ — Available across all routes

For Developers (OAuth Token Lifecycles)

If you are integrating with UniAuth as an OAuth client, it is important to understand how OAuth token lifecycles differ from browser sessions:

Token TypeLifetimeStorageRenewal
Access Token1 hourStateless (JWT, HS256)Exchange refresh token for a new access token
Refresh Token30 daysServer-side (SHA-256 hash)Rotated on each use; old token is invalidated
ID Token1 hourStateless (JWT, RS256)Re-issued with new access token
Session Cookie7 days (24h inactivity)Server-side + cookieRefreshed on each request

Refresh Token Rotation

UniAuth uses refresh token rotation with family-based replay detection. Every time you exchange a refresh token for a new access token, the old refresh token is invalidated and a new one is issued. If a previously used refresh token is presented again, UniAuth treats it as a potential token theft and revokes the entire token family.

POST /api/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=CURRENT_REFRESH_TOKEN
&client_id=your-client-id
&client_secret=your-client-secret

// Response includes a NEW refresh token:
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "NEW_REFRESH_TOKEN",
  "id_token": "eyJhbGciOiJSUzI1NiIs..."
}

Important: Always store the new refresh token returned in the response. Using an old refresh token after rotation will invalidate the entire token family as a security measure.

Admin Session Management

Administrators can view and manage sessions across all users from the Admin Panel → Sessions page. This provides a system-wide view of all active sessions with the ability to revoke any session.

Common admin scenarios include:

  • Revoking sessions for a compromised account
  • Investigating suspicious login activity from unusual IP addresses
  • Force-signing out a user during an incident response
  • Monitoring concurrent session counts across the platform

API Reference

MethodEndpointDescription
GET/api/user/sessionsList all active sessions for the current user
DELETE/api/user/sessions/:idRevoke a specific session by ID
POST/api/user/sessions/revoke-allRevoke all sessions except the current one

For complete API details including request and response schemas, see the API Reference.