---
title: Refresh tokens
description: Refresh tokens (RFC 6749) let an OAuth 2.0 client get a new access token with identical or narrower scopes than the original and without involving the resource owner. Advanced Identity Cloud can issue refresh tokens for all OAuth 2.0/OpenID Connect grant flows except the implicit and client credentials flows.
component: pingoneaic
page_id: pingoneaic:am-oauth2:oauth2-refresh-tokens
canonical_url: https://docs.pingidentity.com/pingoneaic/am-oauth2/oauth2-refresh-tokens.html
keywords: ["OAuth 2.0", "OpenID Connect (OIDC)", "Grant Flow"]
page_aliases: ["oauth2-guide:oauth2-refresh-tokens.adoc"]
section_ids:
  about_refresh_tokens: About refresh tokens
  settings_for_refresh_tokens: Settings for refresh tokens
  demonstrate_refresh_tokens: Demonstrate refresh tokens
  refresh-token-oauth2-client: OAuth 2.0 client
  refresh-token-resource-owner: Resource owner
  refresh-token-access-token: Get an access token
  exchange-refresh-token: Refresh an access token
---

# Refresh tokens

Refresh tokens ([RFC 6749](https://www.rfc-editor.org/info/rfc6749)) let an OAuth 2.0 client get a new access token with identical or narrower scopes than the original and without involving the resource owner. Advanced Identity Cloud can issue refresh tokens for all OAuth 2.0/OpenID Connect grant flows except the implicit and client credentials flows.

## About refresh tokens

Access tokens have short lifetimes because they grant *any bearer* access to a protected resource.

Refresh tokens give an OAuth 2.0 client something to exchange for a new access token. The exchange does not involve resource owner interaction. Refresh tokens are useful when an OAuth 2.0 client needs:

* Long term access to a protected resource.

* Access when the resource owner is unavailable.

* Multiple operations to access the same protected resources, and the resource owner should only have to grant consent once.

Refresh tokens are safer than long-lived access tokens. To exchange a refresh token for an access token, the OAuth 2.0 client must *authenticate*. A malicious user with a compromised access token has access to the protected resource. A user with a refresh token must *also* have the client ID and client secret to obtain an access token.

## Settings for refresh tokens

Refresh tokens configuration settings include:

* Token issuance

  By default, Advanced Identity Cloud issues a refresh token whenever it issues an access token. When Advanced Identity Cloud issues a new refresh token, it expires the old refresh token.

  You can disable refresh token issuance in the OAuth 2.0 provider configuration under Native Consoles > Access Management > Realms > *Realm Name* > Services > OAuth2 Provider > Core:

  * Issue Refresh Tokens

    Whether to issue refresh tokens with access tokens.

  * Issue Refresh Tokens on Refreshing Access Tokens

    Whether to issue new refresh tokens when exchanging a refresh token for an access token.

* Token lifetime

  Refresh tokens are long-lived by default.

  You set the lifetime of refresh tokens in the OAuth 2.0 provider settings or for individual OAuth 2.0 clients. By default, Advanced Identity Cloud relies on the OAuth 2.0 provider configuration.

  When Advanced Identity Cloud issues a new refresh token, it calculates the expiry from the time of issuance using the configured refresh token lifetime. The previous token's remaining lifetime doesn't carry over.

  In the Advanced Identity Cloud admin console, you can change the setting per client under Applications > *Client ID* > Sign On > Advanced settings > Token Lifetimes.

  For details, refer to the [OAuth2 provider](../am-reference/services-configuration.html#realm-oauth-oidc) reference.

* Grace period

  The *grace period* specifies how long an OAuth 2.0 client can replay requests to exchange a refresh token for an access token if there's a network problem or other transient issue.

  For details, refer to the [OAuth2.0 provider](../am-reference/services-configuration.html#refresh-token-grace-period-provider) reference.

Clients can revoke refresh tokens using the [/oauth2/token/revoke](oauth2-token-revoke-endpoint.html) endpoint. The next time the client requires access to protected resources, it must involve the resource owner.

## Demonstrate refresh tokens

Demonstrate using refresh tokens with the following steps:

* [Create an OAuth 2.0 client](#refresh-token-oauth2-client).

* [Create a resource owner account](#refresh-token-resource-owner).

* [Get an access token and the accompanying refresh token](#refresh-token-access-token).

* [Refresh the access token](#exchange-refresh-token).

### OAuth 2.0 client

1. Create a confidential OAuth 2.0 client account.

   In the Advanced Identity Cloud admin console, select Applications > + Add Application, and create a new Web client with the following credentials:

   * Client ID

     `myClient`

   * Client Secret

     `mySecret`

2. Under Sign On > General Settings > Sign-in URLs, add `https://www.example.com:443/callback` and save your work.

### Resource owner

An OAuth 2.0 client requests the access token on behalf of a resource owner. Create the OAuth 2.0 resource owner account:

1. [Create a user profile](../identities/manage-identities.html#create_a_user_profile).

2. Record the username and password.

### Get an access token

1. Authenticate as the resource owner:

   ```bash
   curl \
   --request POST \
   --header 'Content-Type: application/json' \
   --header 'X-OpenAM-Username: <resource-owner-username>' \
   --header 'X-OpenAM-Password: <resource-owner-password>' \
   --header 'Accept-API-Version: resource=2.0, protocol=1.0' \
   'https://<tenant-env-fqdn>/am/json/realms/root/realms/alpha/authenticate'
   {
     "tokenId": "<resource-owner-tokenId>",
     "successUrl": "/enduser/?realm=/alpha",
     "realm": "/alpha"
   }
   ```

2. Request the authorization code as the client:

   ```bash
   curl \
   --dump-header - \
   --request POST \
   --cookie '<session-cookie-name>=<resource-owner-tokenId>' \
   --data 'scope=openid' \
   --data 'response_type=code' \
   --data 'client_id=myClient' \
   --data 'csrf=<resource-owner-tokenId>' \
   --data 'redirect_uri=https://www.example.com:443/callback' \
   --data 'state=abc123' \
   --data 'decision=allow' \
   'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize'
   ...
   location: https://www.example.com:443/callback?code=<authorization-code>&iss=https%3A%2F%2F...
   ...
   ```

3. Exchange the authorization code for an access token as the client:

   ```bash
   curl \
   --request POST \
   --user 'myClient:forgerock' \
   --data 'grant_type=authorization_code' \
   --data 'code=<authorization-code>' \
   --data 'redirect_uri=https://www.example.com:443/callback' \
   'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token'
   {
     "access_token": "<access-token>",
     "refresh_token": "<refresh-token>",
     "scope": "openid",
     "id_token": "<id-token>",
     "token_type": "Bearer",
     "expires_in": 3599
   }
   ```

### Refresh an access token

Exchange the refresh token for a new access token:

```bash
$ curl \
--request POST \
--data "grant_type=refresh_token" \
--data "refresh_token=<refresh-token>" \
--data "client_id=myClient" \
--data "client_secret=forgerock" \
--data "scope=openid" \
"https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token"
{
  "access_token": "<new-access-token>",
  "refresh_token": "<new-refresh-token>",
  "scope": "openid",
  "id_token": "<id-token>",
  "token_type": "Bearer",
  "expires_in": 3599
}
```

|   |                                                                                                                                                                                                                                                    |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | * The `scope` parameter is optional. By default, Advanced Identity Cloud issues an access token with the same scopes as the original token.

* Advanced Identity Cloud has issued a new refresh token; the original refresh token is now inactive. |
