> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Refresh Tokens with Actions

> Learn about managing Refresh Tokens with Actions

Using <Tooltip tip="Refresh Token: Token used to obtain a renewed Access Token without forcing users to log in again." cta="View Glossary" href="/docs/glossary?term=Refresh+tokens">Refresh tokens</Tooltip> with [Actions](/docs/customize/actions) allows you to configure post-authentication risk detection and response capabilities to protect your applications and users against compromised refresh tokens. You can also dynamically customize the [refresh token expirations](/docs/secure/tokens/refresh-tokens/configure-refresh-token-expiration).

To facilitate this, post-login Actions feature two key objects:

* **event.refresh\_token**: Provides relevant information for existing refresh\_tokens including `id`, `created_at`, `expires_at`, `idle_expires_at`, `clients_id`, `device` information, such as `ASN`, `IP`, and `User_agent`, and for browser-based flows, `session_id`. This object is populated by [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-token-rotation) flows.
* **api.refreshToken**: Allows you to manage existing refresh tokens by revoking sessions or changing expiry dates.

You can use the `event.refresh_token` object to review the `last_exchange_at` property and evaluate risks associated with the current transactions. You can also combine the `event.refresh_token` object with other event objects, such as the `event.authentication`.

You can then use the `api.refreshToken` object to either set refresh token expiry dates or revoke the refresh token.

To learn more about these objects, review:

* [Event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the refresh token Event object and properties.
* [API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the refresh token API object and methods.

## Revoke refresh tokens with Actions

The post-login **api.refreshToken.revoke(reason)** method allows you to react to risks associated with a transaction. Revoking the refresh token, invalidates the refresh token, returns a 403 HTTP status code to deny the current transaction, and logs a refresh token revoked event in the [tenant logs](/docs/deploy-monitor/logs/log-event-type-codes) (`srrt`).

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  If you want to use the `api.refreshToken.revoke(reason)` method, ensure that the event.refresh\_token object exists.
</Callout>

### Monitor revoke log events

The revoke operation adds the following log event in your [tenant logs](/docs/deploy-monitor/logs):

A `srrt` event code indicating a refresh token was revoked.

If the refresh token is bound to a previously authenticated session, the log will include a reference to the authenticated session in the `session_id` attribute.

## Change refresh tokens expiry dates with Actions

You can modify refresh tokens expiry dates with the following post-login methods:

* **api.refreshToken.setExpiresAt(absolute)** allows you to define a new absolute expiration date for a specified refresh token.
* **api.refreshToken.setIdleExpiresAt(idle)** allows you to set a new inactivity timeout expiration date for a specified refresh token.

You can use these methods to dynamically customize the refresh token lifetime and inactivity policies based on:

* A user’s organization
* A user’s Auth0 connection
* A specific user’s group membership or profile
* Risk assessment
* Any other dynamic criteria available during execution of the Action

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  The `api.refreshToken.setExpiresAt(absolute)` and `api.refreshToken.setIdleExpiresAt(idle)` methods allow to define the expiration of a refresh token, before its issuance, or modify an existing refresh token expiration during a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens) flow.

  The `api.refreshToken.setExpiresAt(absolute)` and the `api.refreshToken.setIdleExpiresAt(idle)` methods will convert non-expiring refresh tokens to expiring refresh tokens using the defaults [Refresh Token expirations](/docs/secure/tokens/refresh-tokens/configure-refresh-token-expiration) settings as maximum values.

  The `api.refreshToken.setIdleExpiresAt(idle)` method sets the inactivity timeout for refresh tokens. If the method is not called in every successful exchange, the inactivity timeout will be overwritten using the refresh token lifetime application settings.
</Callout>

## Limitations

* Refresh tokens issued on or after 21-09-2023 (22-02-2024 for tenants in the US-3 region) contain the session ID (`session_id`) property with the appropriate value. Refresh tokens issued before this date contain this property with a `null` value.

* Refresh tokens issued before the release of the post-login API method `api.refreshToken.revoke(reason)` will not contain `event.refresh_token.device` information.

* Non-expiring refresh tokens or refresh tokens that have not been exchanged will not contain the property `event.refresh_token.last_exchanged_at`.

* For security reasons, inactivity and absolute timeouts cannot be set above the application refresh token settings defined in the [refresh token expirations](/docs/secure/tokens/refresh-tokens/configure-refresh-token-expiration). If you attempt to set a date above the expiration settings, the API methods will update up to the [refresh token expirations](/docs/secure/tokens/refresh-tokens/configure-refresh-token-expiration) and log a warning event (`w`) in the tenant logs.

* Both `api.refreshToken.setExpiresAt()` and `api.refreshToken.setIdleExpiresAt()` can only shorten their respective lifetimes from the current values. They cannot extend or increase the lifetime.

## Use cases: Revoke a refresh token

You can use [Actions](/docs/customize/actions) to configure risk detections and revoke refresh tokens with the `api.refreshToken.revoke(reason)` method and the event objects.

### Revoke refresh tokens due to ImpossibleTravel

You can use the <Tooltip tip="Adaptive Multi-factor Authentication: Multi-factor authentication (MFA) that is only triggered for users when an attempted login is determined to be a low confidence login." cta="View Glossary" href="/docs/glossary?term=Adaptive+MFA">Adaptive MFA</Tooltip> [assessments](/docs/secure/multi-factor-authentication/adaptive-mfa/customize-adaptive-mfa#assessments-object) object to determine if a user is logging from a location that indicates ImpossibleTravel and revoke the current refresh token associated with the transaction.

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const { riskAssessment } = event.authentication ?? {};
  const ImpossibleTravel = riskAssessment?.assessments.ImpossibleTravel;

  // If this is an impossible travel and this is a refresh token exchange
  if (ImpossibleTravel?.code === "impossible_travel_from_last_login") {
    if (event.refresh_token) {
      api.refreshToken.revoke("Refresh token revoked due to impossible travel");
    }
  }
};
```

In this example, a check occurs at the start of the Action to verify that the `event.authentication.ImpossibleTravel.code` is equal to the `impossible_travel_from_last_login property`. If `true`, the Action calls the `api.refreshToken.revoke()` to:

* Deny the transaction
* Revoke the refresh token
* Return a 403 response access\_denied error
* Issue the error “Refresh token revoked due to impossible travel”

### Revoke refresh tokens due to IP binding

If you use the post-login object properties `event.refresh_token.device.initial_ip` and `event.request.ip` to ensure a refresh token transaction stays with the same IP address for its duration. In this scenario, any IP change is considered a risk, and a new refresh token is required.

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const refreshTokenInitialIp = event.refresh_token?.device?.initial_ip;
  const requestCurrentIp = event.request.ip;

  // if there is a refresh token and the IP changes
  if (
    refreshTokenInitialIp &&
    requestCurrentIp &&
    refreshTokenInitialIp != requestCurrentIp
  ) {
    api.refreshToken.revoke("Invalid IP change");
  }
};
```

In this example, a check occurs at the start of the Action to keep track of the IP addresses with the `event.refresh_token.device.initial_ip` and the `event.request.ip` properties. The Action determines if the transaction IP address has changed. If `true`, the Action calls the `api.refreshToken.revoke()` to:

* Deny the transaction
* Revoke the refresh token
* Return a `403` response `access_denied` error
* Issue the error “`Invalid IP change`”

Alternatively, for a less restrictive Action, you can keep track of the event.`request.asn` and `event.refresh_token.device.initial_asn` properties to monitor for ASN changes instead of IP changes.

## Use cases: Customize refresh token expiry dates

You can use [Actions](/docs/customize/actions) to customize the refresh token lifetime and inactivity dates. Specifically, you can configure the refresh token idle and absolute expiration dates for a particular transaction using the post-login `api.refreshToken.setExpiresAt(absolute)` and `api.refreshToken.setIdleExpiresAt(idle)` methods.

### Customize absolute refresh token expiration date based on Organization

You can use post login action to define a refresh token lifetime per Organization. The example below uses the `refresh_token_timeout` metadata from the Organization to set the expiration time of the refresh token.

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  // Refresh token timeout (in miliseconds) metadata configured in the Organizations
  const organization_refresh_token_lifetime =
    event.organization?.metadata?.refresh_token_timeout;

  if (organization_refresh_token_lifetime) {
    // Refresh token already exists
    if (event.refresh_token) {
      const created = Date.parse(event.refresh_token.created_at);

      const new_expiration_time =
        created + Number(organization_refresh_token_lifetime);
      api.refreshToken.setExpiresAt(new_expiration_time);
    } else {
      // Refresh token doesn't exist yet (e.g., token is being issued)
      const current_time = new Date().getTime();

      const new_expiration_time =
        current_time + Number(organization_refresh_token_lifetime);
      api.refreshToken.setExpiresAt(new_expiration_time);
    }
  }
};
```

In this example, If there is a specific absolute timeout defined for an Organization, the Action sets the refresh token absolute timeout to be equal to:

* Newly issued tokens: `current_time` plus `organization_refresh_token_lifetime`
* Existing Tokens: `event.refresh_token.created_at` plus `organization_refresh_token_lifetime`

### Customize refresh token inactivity timeout based on membership role

You can use post login action to define a refresh token idle timeout using [application](/docs/get-started/applications/configure-application-metadata) and [user metadata](/docs/manage-users/user-accounts/metadata). The example below uses the user metadata roles to define the user membership role and Application metadata to define the expected refresh token idle timeout.

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  // admins are configured with a shorter idle timeout for refresh tokens, in an application metadata
  const max_idle_lifetime =
    event.client.metadata?.admin_refresh_token_idle_timeout;

  // Check the user app metadata roles attribute to check if it is an admin user.
  const isAdmin = event.user?.app_metadata?.roles?.find(
    (role) => role === "admin",
  );

  // If the application has an specific idle timeout defined, set the timeout
  if (max_idle_lifetime && isAdmin) {
    const current_time = new Date().getTime();

    api.refreshToken.setIdleExpiresAt(current_time + Number(max_idle_lifetime));
  }
};
```

In this example, if there is a specific idle timeout defined for the Application and the user is an Admin, the Action sets the refresh token inactivity timeout to be equal to the `current_time` plus the `refresh_token_idle_timeout`. Note that we are changing the timeout for both newly issued tokens and existing ones during refresh token exchange.
