Session Management
AuthGate provides server-side session management with refresh tokens, giving you long-lived sessions without sacrificing JWT security. Short-lived JWTs handle authorization while refresh tokens maintain the session across token expiry.
Overview
By default, AuthGate issues a short-lived JWT (5 minutes) alongside a long-lived refresh token (30 days) on every successful authentication. The JWT is used for API authorization while the refresh token is used to obtain new JWTs without requiring the user to re-authenticate.
Key characteristics:
- Short-lived JWTs — 5-minute expiry, used for API requests
- Long-lived refresh tokens — 30-day default, configurable per project
- Automatic refresh — the SDK handles token refresh transparently
- Server-side revocation — revoke individual sessions or all sessions for a user
- Backward-compatible — existing JWT-only clients continue working when MFA is off
When MFA policy is set to "off" (the default), the authentication response is fully backward-compatible. Existing clients that only read the token field from auth responses will continue working. The refresh_token field is simply an additional field in the response.
The dashboard Sessions page and Admin API session endpoints only track sessions created through AuthGate's built-in session management (refresh tokens). If you manage your own sessions — for example, by issuing custom JWTs or using your own session store without refresh tokens — AuthGate has no visibility into those sessions, and they will not appear in the dashboard or be available via the API.
Refresh tokens
A refresh token is returned alongside the JWT on every successful authentication (OAuth callback, email sign-in, SMS verify, MFA verify).
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "rt_a1b2c3d4e5f6...",
"user": {
"id": "user_abc123",
"email": "jane@example.com",
"name": "Jane Doe"
}
}
- Name
token- Type
- string
- Description
A short-lived JWT (5-minute expiry) for API authorization.
- Name
refresh_token- Type
- string
- Description
A long-lived opaque token (30-day default) for obtaining new JWTs. Prefixed with
rt_.
Refresh tokens are single-use. Each time you exchange a refresh token for a new JWT, you also receive a new refresh token. The old refresh token is invalidated immediately.
Token refresh
Exchange a valid refresh token for a new JWT and refresh token pair.
Request body
- Name
refresh_token- Type
- string
- Description
The refresh token from the most recent authentication or refresh response.
Response 200
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "rt_x9y8z7w6v5u4...",
"expires_in": 300
}
- Name
token- Type
- string
- Description
A new short-lived JWT.
- Name
refresh_token- Type
- string
- Description
A new refresh token. The previous refresh token is now invalid.
- Name
expires_in- Type
- integer
- Description
JWT lifetime in seconds. Always
300(5 minutes).
Error responses
| Status | Error |
|---|---|
400 | Missing refresh_token in request body |
401 | Invalid, expired, or already-used refresh token |
415 | Invalid Content-Type |
429 | Rate limited |
Example request
curl -X POST https://auth.example.com/api/proxy/token/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "rt_a1b2c3d4e5f6..."}'
Example response
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "rt_x9y8z7w6v5u4...",
"expires_in": 300
}
Session revocation
Revoke a session by invalidating its refresh token. Use this for logout flows.
Request body
- Name
refresh_token- Type
- string
- Description
The refresh token of the session to revoke.
Response 200
{
"success": true
}
Error responses
| Status | Error |
|---|---|
400 | Missing refresh_token in request body |
401 | Invalid or already-revoked refresh token |
415 | Invalid Content-Type |
Revoking a refresh token does not invalidate JWTs that were already issued. Since JWTs expire in 5 minutes, the maximum window of continued access after revocation is 5 minutes.
Admin API
The Admin API allows you to list and revoke sessions for any user in your project. These endpoints require your API key.
Authentication
Include your API key in the Authorization header:
Authorization: Bearer your_api_key_here
List sessions
Returns all active sessions for a user.
Query parameters
- Name
user_id- Type
- string
- Description
The AuthGate user ID to list sessions for.
Response 200
{
"data": [
{
"id": "sess_abc123",
"user_id": "user_abc123",
"created_at": "2025-01-10T08:30:00.000Z",
"last_used_at": "2025-01-15T10:00:00.000Z",
"expires_at": "2025-02-09T08:30:00.000Z",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0..."
}
]
}
Example request
curl https://auth.example.com/api/v1/sessions?user_id=user_abc123 \
-H "Authorization: Bearer your_api_key"
Example response
{
"data": [
{
"id": "sess_abc123",
"user_id": "user_abc123",
"created_at": "2025-01-10T08:30:00.000Z",
"last_used_at": "2025-01-15T10:00:00.000Z",
"expires_at": "2025-02-09T08:30:00.000Z",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0..."
}
]
}
Revoke a session
Revoke a specific session by its ID. The associated refresh token is invalidated immediately.
Response 200
{
"success": true
}
Error responses
| Status | Error |
|---|---|
401 | Missing or invalid API key |
404 | Session not found |
Configuration
Session duration is configurable per project in the AuthGate dashboard under Settings > Sessions.
- Name
session_duration- Type
- integer
- Description
Refresh token lifetime in days. Must be between 1 and 365. Defaults to 30 days.
Changing the session duration only affects new refresh tokens. Existing refresh tokens retain their original expiry.
SDK auto-handling
When using the @auth-gate/nextjs SDK, refresh tokens are managed automatically:
- The refresh token is stored in an httpOnly cookie (not accessible to client-side JavaScript)
- The SDK automatically refreshes the JWT before it expires
- On logout, the SDK revokes the refresh token and clears the cookie
- No client-side code is needed to handle token refresh
src/lib/auth.ts
import { createAuthGate } from "@auth-gate/nextjs";
// The SDK handles refresh tokens automatically.
// No additional configuration is needed beyond the standard setup.
const auth = createAuthGate({
apiKey: process.env.AUTHGATE_API_KEY!,
baseUrl: process.env.AUTHGATE_URL!,
appUrl: process.env.NEXT_PUBLIC_APP_URL!,
});
If you are not using the SDK and are managing tokens manually, store the refresh token securely (e.g., in an httpOnly cookie) and never expose it to client-side JavaScript.