HelloJohn / docs
Sessions

Session Timeouts

Configure session duration, idle timeouts, and access token lifetimes in HelloJohn.

Session Timeouts

HelloJohn provides fine-grained control over session and token lifetimes. Configure these to balance security and user experience.


Timeout Settings

SettingDefaultDescription
session_duration30dHow long the refresh token is valid (full session lifetime)
access_token_ttl1hHow long each access token is valid
idle_timeoutNoneRevoke session after this period of inactivity
max_sessions_per_userUnlimitedCap concurrent sessions per user

Session Duration

The session_duration controls how long a user stays signed in without re-authenticating. It is the lifetime of the refresh token.

Examples:

  • 30d — 30 days (default, standard web app)
  • 7d — 7 days (higher security apps)
  • 1y — 1 year (trusted devices)
  • 24h — 24 hours (banking, healthcare)

After session_duration, the refresh token expires and the user must sign in again.


Access Token TTL

The access_token_ttl controls how often a new access token is issued. Shorter values improve security at the cost of more refresh calls.

ValueUse Case
1hDefault — good balance
15mHigh-security apps needing faster revocation
5mCritical systems (token introspection still recommended)
24hSimple apps with low-security requirements

Revoking a session does not immediately invalidate outstanding access tokens. A revoked session will reject refresh attempts, but existing access tokens remain valid until their exp claim. For instant revocation, use API-based token verification rather than local JWT verification.


Idle Timeout

The idle timeout revokes sessions that haven't been active for a specified period. HelloJohn tracks activity via refresh token usage.

curl -X PATCH "https://api.hellojohn.dev/v1/admin/config" \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "X-Tenant-ID: tnt_01HABCDEF654321" \
  -H "Content-Type: application/json" \
  -d '{"idle_timeout": "7d"}'

When idle timeout is configured:

  • Each time the access token is refreshed, last_active_at is updated
  • Sessions where last_active_at is older than idle_timeout are revoked
  • The next refresh attempt returns session_expired

Configuring Timeouts

Via Dashboard

Go to Tenant Settings → Authentication → Session Settings.

Via Admin API

curl -X PATCH "https://api.hellojohn.dev/v1/admin/config" \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "X-Tenant-ID: tnt_01HABCDEF654321" \
  -H "Content-Type: application/json" \
  -d '{
    "session_duration": "14d",
    "access_token_ttl": "15m",
    "idle_timeout": "7d",
    "max_sessions_per_user": 5
  }'

Standard Web App

{
  "session_duration": "30d",
  "access_token_ttl": "1h",
  "idle_timeout": null
}

High-Security App (Banking, Healthcare)

{
  "session_duration": "24h",
  "access_token_ttl": "15m",
  "idle_timeout": "1h",
  "max_sessions_per_user": 3
}

Enterprise / Compliance

{
  "session_duration": "8h",
  "access_token_ttl": "5m",
  "idle_timeout": "30m",
  "max_sessions_per_user": 2
}

Remember Me

Implement "remember me" by issuing different session durations based on user choice:

const sessionDuration = rememberMe ? "30d" : "24h";

const session = await hj.auth.signIn({
  email,
  password,
  sessionOptions: { duration: sessionDuration },
});

Handling Expired Sessions in Your App

When an access token cannot be refreshed (session expired), redirect the user to sign in:

async function apiRequest(endpoint: string) {
  let response = await fetch(endpoint, {
    headers: { Authorization: `Bearer ${getAccessToken()}` },
  });

  if (response.status === 401) {
    // Try to refresh
    try {
      await refreshTokens();
      response = await fetch(endpoint, {
        headers: { Authorization: `Bearer ${getAccessToken()}` },
      });
    } catch {
      // Refresh failed — session expired
      redirectToSignIn();
      return;
    }
  }

  return response.json();
}

On this page