Session Management

Descope offers comprehensive session management capabilities. The video tutorial below covers various configurations and details on session management.


Descope implements the session management with two tokens to improve performance and security. - "Session Token" and "Refresh Token". These tokens are implemented as JWT (JSON Web Token), meaning that the information stored in the object is encrypted with the private key, and using the public key, any service can validate that the data was not tampered with by a malicious actor.

Your application server can validate the session token (short expiry time) without a connection to Descope service. If the application server finds the session token invalid, it calls the Descope service with the refresh token (longer expiry time) to get a new session token. If the refresh token is invalid for some reason, such as a logout call or expiry time, then the user is forced to re-login.

Note: Configurations for session management can be configured at a project level or tenant level. Please review the applicable guides for configuring session handling at a project or tenant level.

Descope Session JWT Structure

The Descope JWT contains standard and Descope specific claims:

  • amr: (Authentication Methods References): An array of the authentication methods used.
  • drn: (Descope Resource Name) References where the token is stored.
  • exp: (Expiration Time): Specifies the expiration time of the token, represented as a UNIX epoch timestamp.
  • iat: (Issued At): The time the JWT was issued, represented as a UNIX epoch timestamp.
  • iss: (Issuer): Identifies the principal that issued the JWT. Within Descope's JWT, this is the Descope project ID.
  • sub: (Subject): The principal that is the subject of the JWT. Within Descope's JWT, this is the User ID of the user within Descope.
  • tenants: A list of associated tenants (represented by unique IDs) associated with this JWT. -- For each tenant:
    • permissions: A list of permissions granted to the subject within the context of that tenant.
    • roles: Roles associated with the subject for that specific tenant.

Note: Other claims can be added to the JWT utilizing custom claims within Descope.

Below is an example of a Descope Session JWT with tenants associated to the user.

  "amr": [
  "drn": "DS",
  "exp": 1692304651,
  "iat": 1692304051,
  "iss": "P2RFvFexVaxxNFK6rhP0ePtaGfTK",
  "sub": "U2RG6grrbT3REKYqk5yC4SjkMqzA",
  "tenants": {
    "T2U7vUH1NPy4JzWHruoOVIGyzYlu": {
      "permissions": [
      "roles": [
        "Product Manager"
    "T2U7vVBqyZv6HdGtGLdnkgCbNxrC": {
      "permissions": [
      "roles": [

Refresh Token Storage - Client SDK (including Flows)

The refresh token expiry time should be decided based on the requirements of your application (tradeoff between higher security and user experience). A shorter expiration time means that the user will need to authenticate frequently.

If you are using Client SDK (including Flows), Descope manages the refresh token storage for your application client. Depending on the project configuration, the Descope service can return the refresh token in two different ways - "manage in cookies" and "manage in response body".

Manage in cookies (recommended for production)

Descope Client SDK automatically sets the refresh token as a cookie. For this option to work, you must also configure a CNAME record in your DNS and the custom domain setting in Descope console, which will securely restrict access to the stored refresh token.

Strict Cookies:

Descope utilizes strict cookies; this means that after successful authentication, Descope's response will set SameSite=Strict within the header of the cookie. The browser will only be able to send cookies to hosts with that custom domain (specified in the project settings) and subdomains of the set custom domain.

You should set the custom domain setting to something like, and the CNAME record in your DNS for (subdomain of custom domain) should point to (US) / (EU). This implementation will set the refresh token as a cookie on

See the Configuring CNAME and Managing Sessions in Cookies guide for a step by step guide for managing sessions within cookies.

Descope custom domain example.

Sample Custom Domain Setting

Descope custom cname example.

Sample CNAME Setting

Manage in response body

Descope Client SDK returns the refresh token in the body and stores it in browser local storage. This option does not require configuring a custom domain. You can chose to handle the refresh token as per your needs in your application client.

Handling session token in your application

Descope SDK (client and backend) offers the capability to validate and refresh session token, including communication with the Descope service. You do not need to address this in your code. The detailed handling of the tokens in your application along with code samples is covered in the Descope Session Validation Guide.

Mobile SDK Token Storage

Descope extends support to mobile application development by offering SDKs tailored for Swift, Kotlin, and more. These SDKs incorporate robust token storage methodologies, utilizing the secure environment of the each device locally.

With Descope's Mobile SDKs at your disposal, you can bypass the necessity of manually saving tokens on the device. The SDKs, designed to cater to the unique needs of each platform, handle token storage and retrieval in an unobtrusive and secure manner in the background.


For Swift-based applications, Descope SDK uses iOS's Keychain Services to store, retrieve and manage the session and refresh tokens. Keychain Services provide a secure, encrypted storage mechanism for sensitive user information, including Descope tokens.


Descope's Kotlin SDK employs Android's native EncryptedSharedPreferences to securely store session and refresh tokens locally. The EncryptedSharedPreferences provide a robust, encrypted storage environment to protect sensitive user information, such as Descope tokens.


Similarly, for Flutter applications, session and refresh tokens are stored using the native keychain on iOS and EncryptedSharedPreferences on Android, providing a secure storage solution.