Skip to content

Sessions

Rack Gateway uses database-backed sessions to maintain authentication state after OAuth login. Sessions are designed for security, auditability, and revocability.

PropertyWeb SessionsCLI Sessions
StorageHTTP-only cookieConfig file
Default Lifetime5 minutes idle90 days idle
Expiration TypeSliding (activity-based)Sliding (activity-based)
CSRF RequiredYesNo
MFA SupportFullFull

Sessions are created after successful OAuth authentication:

  1. Generate token

    32 bytes of cryptographically secure random data, base64url encoded

  2. Hash for storage

    Token is SHA-256 hashed before database storage

  3. Record metadata

    • Channel (web or cli)
    • IP address
    • User agent
    • Device name (CLI)
    • MFA status
  4. Set expiration

    Based on configured timeout and channel type

Raw token: QnJ4R2pKM... (43 characters, base64url)
Stored hash: a4b2c8d9... (64 characters, hex SHA-256)

The raw token is never stored. Even with database access, sessions cannot be hijacked.

Every authenticated request validates the session:

CheckDescriptionAction on Failure
Token existsSession found in database401 Unauthorized
Not revokedrevoked_at is null401 Unauthorized
Not expiredexpires_at > now401 + auto-revoke
Not idlelast_seen_at + TTL > now401 + auto-revoke
User existsAssociated user found401 + auto-revoke
User not lockedlocked_at is null401 + auto-revoke

Web sessions use sliding expiration based on activity:

Session Created: 10:00 AM
Last Activity: 10:03 AM
Timeout: 5 minutes
Expires: 10:08 AM (not 10:05!)

Each request refreshes the expiration, allowing continuous use without re-authentication.

CLI sessions last 90 days from their last use, so a CLI used at least every 90 days stays signed in. Every command still needs MFA for anything above read access (see Step-Up Authentication), so a copied CLI session token alone can only read.

Terminal window
# Set idle timeout to 15 minutes
RGW_SETTING_SESSION_TIMEOUT_MINUTES=15

The timeout is stored with each session, so existing sessions keep their original timeout when settings change.

Sessions can be revoked through multiple mechanisms:

Logout in the web UI’s sidebar revokes the web session. rack-gateway logout revokes the CLI session (POST /api/v1/auth/cli/logout with the session token), then removes the rack and its token from the CLI’s config. Both are audited before the session is revoked, and refused if the audit log can’t record them.

Users and administrators can revoke sessions from a user’s page (Users → the user), which lists their active sessions: Revoke for one, or Revoke All. Users can revoke their own; revoking anyone else’s needs gateway:user:update (admins). Either way it needs MFA on the request.

Sessions stop working when:

  • The session expires (idle timeout)
  • The user is locked (locking revokes every session)
  • The user is deleted

Each session stores metadata for security and auditing:

FieldDescription
user_idAssociated user
token_hashSHA-256 of session token
channelweb or cli
device_idDevice identifier sent by the CLI
device_nameDevice name sent by the CLI (the host name)
ip_addressLast seen IP address
user_agentLast seen user agent
created_atSession creation time
last_seen_atLast activity timestamp
expires_atExpiration timestamp
revoked_atRevocation timestamp (null if active)
mfa_verified_atMFA verification timestamp
recent_step_up_atRecent step-up auth timestamp

Sessions record the IP address and user agent of their last request, and CLI sessions the device that logged in, so users can recognize their sessions. Users see their active sessions on their own page (Users → their name).

When MFA is required, sessions track verification status:

Session FieldPurpose
mfa_verified_atTimestamp of initial MFA verification
trusted_device_idReference to trusted device (if remembered)
recent_step_up_atTimestamp of recent step-up verification

For sensitive actions, users may need to re-verify MFA even within an active session:

  • Configurable step-up window (mfa_step_up_window_minutes, default 10 minutes)
  • Verifying a factor (TOTP, WebAuthn, YubiKey OTP or a backup code) sets recent_step_up_at and opens the window
  • Subsequent step-up actions within the window don’t require re-verification
  • Only a verified factor opens the window. A login that needs no MFA challenge, or that a trusted device lets skip it, opens none, and trusting a device doesn’t restart it
  • Adding an MFA method needs no step-up for a user’s first factor, and a step-up once they have one
  • Some actions need MFA on every request, even within the window (see MFA Requirements)

The CLI sends its MFA proof (a TOTP code or WebAuthn assertion) with every request of a command. Each proof verifies only once: TOTP codes can’t be replayed and WebAuthn challenges are single-use. The first request that needs MFA verifies the proof and starts the session’s step-up window, so the command’s later requests within the window need no further proof.

WebAuthn challenges are stored server-side in webauthn_challenges, bound to the user and the session that started the ceremony, deleted when used and expired after 5 minutes. Clients only hold an opaque challenge ID. User verification (PIN or biometric) is required, and each credential’s signature counter must increase (authenticators that always report 0 are allowed); the compare and store is a single statement.

Web sessions require CSRF tokens:

CSRF Token = HMAC-SHA256(secret, "csrf|" + session_token)

The CSRF token is derived from the session token using HMAC, ensuring:

  • Each session has a unique CSRF token
  • Token cannot be guessed without knowing the session
  • Validation is fast (no database lookup)

Web requests include CSRF token in header:

X-CSRF-Token: <token>

API requests with bearer tokens don’t require CSRF (token-based auth is inherently CSRF-safe).

Expired and revoked sessions stay in the database with their revoked_at and expires_at, so they can be matched to audit entries later. They can’t be used again.

Use CaseRecommended Timeout
High-security production5 minutes
Standard production15 minutes
Internal/trusted network30 minutes
Development1 hour

Monitor for anomalies:

  • Multiple concurrent sessions from different IPs
  • Sessions from unusual geolocations
  • Rapid session creation/destruction

If a session is compromised:

  1. Revoke immediately

    Admin revokes the specific session or all user sessions

  2. Lock account (if needed)

    Lock the user account to prevent new sessions

  3. Review audit logs

    Check what actions were taken with the compromised session

  4. Rotate secrets (if needed)

    If actions accessed sensitive data, rotate affected credentials

  5. Unlock and notify

    After securing, unlock account and notify user