Skip to main content

Before you start

Ensure you have:
  • A Custom Domain configured Auth0 tenant configured for your application
  • Auth0 CLI installed and authenticated.
  • A post-login Action
  • An Auth0 tenant session using the non-persistent sessions policy
  • (Optional) Configure session’s Idle and absolute session timeout values
The Keep Me Signed In experience provides users the option to stay logged-in on a trusted device.
Login image
  • If the Keep Me Signed In checkbox is selected, it sets a persistent session which survives browser restarts.
  • If the Keep Me Signed In checkbox is not selected, it sets a non-persistent session which expires when the browser closes.
Using non-persistent (ephemeral) sessions with Actions, the server securely handles this logic without exposing refresh tokens to the frontend. Using Custom Prompts, Auth0 CLI, and ephemeral sessions via Actions, you can implement a secure and modern “Keep Me Signed In” flow with no refresh tokens, no client-side session hacks, and full backend control. This solution is ideal for customers prioritizing:
  • Zero-trust browser session handling
  • Minimal session persistence
  • Trusted device overrides

1. Configure a Universal Login page and Add a custom prompt

To gather the user’s Keep Me Signed In preference, you need to customize Universal Login by configuring a page template and adding a custom prompt using Auth0 CLI.

Optional: Enable the Universal Login page template

This step is only required if your tenant does not have a Universal Login template configured.
Use the following command to create or update the page template:
auth0 universal-login templates update
The customization editor opens the login page template. You can use any HTML structure that fits your brand. Here is a minimal example template with a background and wrapped widget:
<!DOCTYPE html>
<html lang="{{locale}}">
  <head>
    {%- auth0:head -%}
    <style>
      body {
        background-image: url("https://images.unsplash.com/photo-1643916861364-02e63ce3e52f");
        background-size: cover;
        background-position: center;
      }
      .prompt-wrapper {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.3);
      }
    </style>
    <title>{{ prompt.screen.texts.pageTitle }}</title>
  </head>
  <body class="_widget-auto-layout">
    {% if prompt.name == "login" or prompt.name == "signup" %}
      <div class="prompt-wrapper">
        {%- auth0:widget -%}
      </div>
    {% else %}
      {%- auth0:widget -%}
    {% endif %}
  </body>
</html>
Save and close the editor, the Auth0 CLI prompts you to confirm:
Do you want to save the template? Yes

 Successfully updated the template for the New Universal Login Experience!

2. Add a Keep Me Signed In checkbox using Auth0 CLI

To add a checkbox into the Universal Login screen, follow these steps:

Launch the customization editor

  1. Open the customization editor for the login-id or login prompt depending on your tenant configuration:
auth0 universal-login customize -p login-id
  1. Select standard for rendering mode
Rendering Mode: standard
The customization editor launches at a local address:
http://localhost:52649
If you are unsure whether your tenant uses login or login-id, refer to Auth0’s prompt customization.

Configure the checkbox

Open the Partials option in the customization editor:
  1. Set Prompt to: login-id (or login)
  2. Set Screen to: login-id (or login)
  3. Set Partial to: form-footer-end
Auth0 CLI partials
Add the following HTML snippet:
<div class="ulp-field">
  <input type="checkbox" name="ulp-remember-me" id="remember-me">
  <label for="remember-me">Stay signed in on this device?</label>
</div>
This renders the checkbox underneath the login form.

Deploy your changes

Select Deploy Changes in the top-right corner to save and apply the customization.

Checkpoint

Log in using Universal Login. The login screen includes a Keep Me Signed In checkbox.
Login image

3. Create a Post-Login Action using Auth0 CLI

Create a new file called set-session-persistence.js for use with Auth0 CLI and add the following code:
exports.onExecutePostLogin = async (event, api) => {

  // Apply the change only when the parameter is available
  if (event.request.body['ulp-remember-me']) {
    api.session.setCookieMode('persistent');
  } 
};
Use Auth0 CLI to create or update your post-login Action using the set-session-persistence.js file:
auth0 actions create --name kmsi --trigger post-login --code "$(cat set-session-persistence.js)"
Auth0 CLI returns the Action Id:
ID             f54c4aae-431f-4290-a7e0-cfc6a3f28386
NAME           kmsi
TYPE           post-login
STATUS         pending
DEPLOYED
LAST DEPLOYED
LAST UPDATED   0 seconds ago
CREATED        0 seconds ago
CODE           exports.onExecutePostLogin = async (event, api) => {
                   if (event.request.body['ulp-remember-me']) {
                     api.session.setCookieMode("persistent");
                   } else {
                     api.session.setCookieMode("non-persistent");
                   }
                 };
Deploy your Action using its id:
auth0 actions deploy <id>
Navigate to the Auth0 Dashboard > Actions > Triggers > Post-Login to add the new action to the current flow and select Apply.
Dashboard Actions Triggers Post Login

Optional - Set session duration for trusted devices

You can use api.session.setExpiresAt() or api.session.setIdleExpiresAt() methods to further customize session lifetimes.
exports.onExecutePostLogin = async (event, api) => {
  if (event.request.body['ulp-remember-me']) {
    api.session.setCookieMode("persistent");

    const now = Date.now();
    api.session.setExpiresAt(now + 7 * 24 * 60 * 60 * 1000); // 7 days
  } else {
    api.session.setCookieMode("nonpersistent");
  }
};

4. Test implementation

To verify the session behavior, you can: Log in using Universal Login, and select the Keep Me Signed In checkbox.
  • In the tenant logs, search for (event types s or ssa)
    • cookie: { mode: "non-persistent" }
    • cookie: { mode: "persistent" }
  • Search for event.session.cookie.mode in your Actions
I