Skip to main content

Session Management

In YorAuth, each session corresponds to a refresh token. When a user logs in, a refresh token is created and stored (hashed) in the database. Listing sessions, revoking sessions, and enforcing concurrent session limits all operate on these refresh token records.

All session management endpoints require a valid JWT access token and the authenticated user must own the {userId} in the path.

What a Session Contains

Each session record exposes:

FieldDescription
idUUID of the session (refresh token record). Use this to revoke a specific session.
device_infoObject containing ip_address and user_agent captured at login.
is_remember_meWhether the session was created with remember_me: true.
last_used_atWhen the refresh token was last used to obtain a new access token.
expires_atWhen the session expires. 7 days for standard, 30 days for remember me.
created_atWhen the user logged in and this session was created.

List Active Sessions

Retrieve all non-expired, non-revoked sessions for a user. Sessions are returned in reverse chronological order (newest first).

Endpoint: GET /api/v1/applications/{applicationId}/users/{userId}/sessions

Authentication: JWT Bearer token required.

bash
curl https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions \
  -H "Authorization: Bearer <access_token>"
javascript
const response = await fetch(
  `https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions`,
  {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);
const data = await response.json();

Response 200 OK

json
{
  "data": [
    {
      "id": "7f3c9b2a-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
      "device_info": {
        "ip_address": "203.0.113.45",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
      },
      "is_remember_me": false,
      "last_used_at": "2026-02-25T14:30:00Z",
      "expires_at": "2026-03-04T10:00:00Z",
      "created_at": "2026-02-25T10:00:00Z"
    },
    {
      "id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
      "device_info": {
        "ip_address": "198.51.100.22",
        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)"
      },
      "is_remember_me": true,
      "last_used_at": "2026-02-24T09:15:00Z",
      "expires_at": "2026-03-26T09:00:00Z",
      "created_at": "2026-02-24T09:00:00Z"
    }
  ]
}

Error Responses

HTTP StatusError CodeDescription
404USER_NOT_FOUNDUser does not exist in this application.

Revoke a Specific Session

Revoke a single active session by its ID. The user will be signed out on the device that session belongs to after their current access token expires (up to 15 minutes).

Endpoint: DELETE /api/v1/applications/{applicationId}/users/{userId}/sessions/{sessionId}

Authentication: JWT Bearer token required.

bash
curl -X DELETE https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions/1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
  -H "Authorization: Bearer <access_token>"
javascript
await fetch(
  `https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions/${sessionId}`,
  {
    method: 'DELETE',
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);

Response 204 No Content

No body is returned on success.

Error Responses

HTTP StatusError CodeDescription
404SESSION_NOT_FOUNDSession does not exist, does not belong to this user, or is already revoked.

Revoke All Sessions

Sign a user out of all devices by revoking every active session at once.

Endpoint: DELETE /api/v1/applications/{applicationId}/users/{userId}/sessions

Authentication: JWT Bearer token required.

bash
curl -X DELETE https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions \
  -H "Authorization: Bearer <access_token>"
javascript
const response = await fetch(
  `https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions`,
  {
    method: 'DELETE',
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);
const data = await response.json();

Response 200 OK

json
{
  "data": {
    "revoked_count": 3,
    "message": "Revoked 3 active session(s)."
  }
}

Error Responses

HTTP StatusError CodeDescription
404USER_NOT_FOUNDUser does not exist in this application.

Concurrent Session Limits

Your application can enforce a maximum number of concurrent sessions per user. This is configured on the application in the YorAuth dashboard.

When a new session is created and the user has already reached the limit, the oldest session (by last_used_at) is automatically revoked to make room. This ensures the limit is always respected without blocking new logins.

For example, with a limit of 3 concurrent sessions:

  • User has 3 active sessions on Desktop, Mobile, and Tablet.
  • User logs in on a second desktop.
  • The session last used (e.g. Tablet, used 5 days ago) is automatically revoked.
  • The new session is created. Active sessions: Desktop, Mobile, Second Desktop.

A limit of null or 0 means unlimited concurrent sessions.


Device Tracking

Session device information is captured at login time and on each token refresh. The device_info object contains:

json
{
  "ip_address": "203.0.113.45",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}

This information is stored as-is from the request. Your frontend or application can parse the user_agent string to display a human-readable device description.


Token Reuse Detection

YorAuth implements refresh token reuse detection. Each refresh token can only be used once — after use it is immediately rotated (revoked and replaced with a new token).

If a previously revoked refresh token is presented, it indicates a potential token theft scenario. YorAuth responds by revoking all active sessions for the affected user across the application. The user must log in again on all devices.

This is a security measure to contain compromise: if an attacker stole a refresh token, using it will terminate both the attacker's and the legitimate user's sessions, prompting the user to re-authenticate and change their password.

See Token Management for more on token rotation.


Session Revocation Scenarios

TriggerSessions RevokedNotes
POST /users/logoutSingle sessionOnly the submitted refresh token is revoked.
DELETE /users/{userId}/sessions/{sessionId}Single sessionUser-initiated revocation of a specific session.
DELETE /users/{userId}/sessionsAll user sessionsRevokes all active refresh tokens for the user.
Concurrent session limit exceededOldest sessionAutomatic, happens during new login.
Refresh token reuse detectedAll user sessionsSecurity response to potential token theft.
Account deletionAll user sessionsRevoked as part of soft delete.