---
title: Access token modification
description: Use this extension point to modify the key-value pairs in an OAuth 2.0 access token. For example, you could make a REST call to an external service and add or change a key-value pair in the access token based on the response before issuing the token to the OAuth 2.0 client.
component: pingam
version: 8.1
page_id: pingam:am-oauth2:modifying-access-tokens-scripts
canonical_url: https://docs.pingidentity.com/pingam/8.1/am-oauth2/modifying-access-tokens-scripts.html
keywords: ["OAuth 2.0", "Customization", "Scripting", "Java", "Plugins"]
page_aliases: ["oauth2-guide:modifying-access-tokens-scripts.adoc"]
section_ids:
  about_modifying_access_tokens: About modifying access tokens
  modifying-access-tokens-scripts-prepare: Examples
  example-atm-legacy: Add profile data to access token (legacy script)
  update-profile-data: Update the user profile
  prepare-atm-legacy: Prepare the script
  configure-atm-legacy: Configure AM to use the script
  try-atm-legacy: Try the script
  example-atm-nextgen: Add external data to access token (next-generation script)
  prepare-atm-nextgen: Create the script
  configure-atm-nextgen: Configure AM to use the script
  try-atm-nextgen: Try the script
---

# Access token modification

Use this extension point to modify the key-value pairs in an OAuth 2.0 access token. For example, you could make a REST call to an external service and add or change a key-value pair in the access token based on the response before issuing the token to the OAuth 2.0 client.

* Sample scripts

  * [OAuth2 Access Token Modification Script](../am-scripting/sample-scripts.html#oauth2-access-token-modification-js) (Legacy JavaScript)

  * [OAuth2 Access Token Modification Script](../am-scripting/sample-scripts.html#oauth2-access-token-modification-groovy) (Groovy)

* Script bindings

  * [Common bindings](../am-scripting/script-bindings.html)

  * [Access token modification scripting API](../am-scripting/access-token-modification-api.html)

* Java interface

  `org.forgerock.oauth2.core.plugins.AccessTokenModifier`

  > **Collapse: Sample Java code**
  >
  > ```java
  > /*
  >  * Copyright 2021-2025 Ping Identity Corporation. All Rights Reserved
  >  *
  >  * This code is to be used exclusively in connection with Ping Identity
  >  * Corporation software or services. Ping Identity Corporation only offers
  >  * such software or services to legal entities who have entered into a
  >  * binding license agreement with Ping Identity Corporation.
  >  */
  >
  > package org.forgerock.openam.examples;
  >
  > import org.forgerock.oauth2.core.AccessToken;
  > import org.forgerock.oauth2.core.OAuth2Request;
  > import org.forgerock.oauth2.core.plugins.AccessTokenModifier;
  >
  > /**
  >  * Custom implementation of the Access Token Modifier
  >  * plugin interface {@link org.forgerock.oauth2.core.plugins.AccessTokenModifier}
  >  *
  >  * <li>
  >  * In this example the {@code modifyAccessToken} method adds an additional field to the token.
  >  * </li>
  >  *
  >  */
  > public class CustomAccessTokenModifier implements AccessTokenModifier {
  >
  >     @Override
  >     public void modifyAccessToken(AccessToken accessToken, OAuth2Request request) {
  >         //Field to always include in token
  >         accessToken.setField("additional", "field");
  >     }
  > }
  > ```

## About modifying access tokens

You can modify both [client-side](stateless-stateful-tokens.html#client-side-tokens) and [server-side](stateless-stateful-tokens.html#server-side-tokens) access tokens. Modifications are stored permanently in the issued JWT for client-side tokens or in the CTS for server-side access tokens. You can also modify [macaroons](oauth2-macaroons.html) used in place of regular tokens. In this case, you implement the plugin to modify the key pairs in the token and, optionally, to add caveats. Learn more in [MacaroonToken](../_attachments/apidocs/org/forgerock/openam/oauth2/token/macaroon/MacaroonToken.html) interface.

When issuing modified access tokens, consider the following important points:

* Removing or changing native properties could render the access token unusable.

  AM requires that certain native properties are present in the access token to consider it valid. Removing or modifying these properties could cause the OAuth 2.0 flows to break.

  |   |                                                                                                                                                                                      |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  |   | The [AccessToken API documentation](../_attachments/apidocs/org/forgerock/oauth2/core/AccessToken.html) indicates the native properties and warns against changing or removing them. |

* Modifying access tokens affects the size of the client-side token or server-side entry.

  Changing OAuth 2.0 access tokens directly affects the size of server-side tokens or JSON web tokens (JWTs) if client-side tokens are enabled.

  Make sure the token size remains within your client or user-agent size limits.

  Learn more in [Token storage location](stateless-stateful-tokens.html).

## Examples

The following examples use a script to modify the access token.

* [Add profile data to access token (legacy script)](#example-atm-legacy)

* [Add external data to access token (next-generation script)](#example-atm-nextgen)

|   |                                                                                                                                                                                                |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Learn more about configuring AM to use an access token modification Java plugin in [Configure AM to use a Java OAuth 2.0 plugin](customizing-oauth2-scopes.html#configure-java-oauth2-plugin). |

### Add profile data to access token (legacy script)

Complete the following steps to implement a custom access token modification script to set additional properties in the access token:

1. [Update the user profile](#update-profile-data)

2. [Prepare the script](#prepare-atm-legacy)

3. [Configure AM to use the script](#configure-atm-legacy)

4. [Try the script](#try-atm-legacy)

This example uses a legacy script in Groovy.

#### Update the user profile

The script requires that the authenticated user of the access token has an email address and telephone number in their profile. The script adds the values of these fields to the access token.

1. Log in as an AM administrator, for example, `amAdmin`.

2. Add an email address and telephone number value to a test user's profile, for example, `bjensen`.

   1. Select Realms > *realm name* > Identities.

   2. On the Identities tab, select `bjensen`.

   3. In Email Address, enter a valid address. For example, `bjensen@example.com`.

   4. In Telephone Number, enter a value. For example, `44 117 496 0228`.

   5. Save your changes.

#### Prepare the script

Modify the default legacy access token modification script to set additional fields:

1. Go to Realms > *realm name* > Scripts, and click OAuth2 Access Token Modification Script.

2. In the Script field:

   * Uncomment the following line, by surrounding with a pair of `*/` and `/*` strings:

     ```groovy
     /* ... */
     accessToken.setField("hello", "world")
     /* ... */
     ```

   * Similarly, uncomment these lines:

     ```groovy
     /* ... */
     def attributes = identity.getAttributes(["mail", "telephoneNumber"].toSet())
     accessToken.setField("mail", attributes["mail"])
     accessToken.setField("phone", attributes["telephoneNumber"])
     /* ... */
     ```

     |   |                                                                                                                                                            |
     | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
     |   | Find information about the available script bindings in the [Access token modification scripting API](../am-scripting/access-token-modification-api.html). |

     |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
     | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
     |   | To include additional data in the [/oauth2/access\_token](oauth2-access_token-endpoint.html) response, edit your script to call the `addExtraData` method. For example:```groovy
     accessToken.addExtraData("hello", "world")
     ```This returns the data as part of the response body in the following way:```json
     {
       "access_token":"sbQZuveFumUDV5R1vVBl6QAGNB8",
       "hello":"world",
       "scope":"write",
       "token_type":"Bearer",
       "expires_in":3599
     }
     ``` |

3. Save your changes.

#### Configure AM to use the script

Perform this task to set up an OAuth 2.0 provider that uses the modified default access token modification script.

1. [Configure the provider](customizing-oauth2-scopes.html#configure-scripted-oauth2-plugin) and make sure the following properties are set:

   * Access Token Modification Plugin Type to `SCRIPTED`.

   * Access Token Modification Plugin Script to `OAuth2 Access Token Modification Script`.

   By default, a new OAuth 2.0 provider uses the default access token modification script.

2. Save your changes.

#### Try the script

To verify that the script modifies the access token as expected, run an OAuth 2.0 authorization code flow as follows:

1. [Create an OAuth 2.0 client](oauth2-register-client.html) with the following values:

   * **Client ID**: `myClient`

   * **Client secret**: `mySecret`

   * **Redirection URIs**: `https://www.example.com:443/callback`

   * **Scope(s)**: `access|Access to your data`

2. [Get an authorization code](oauth2-authz-grant.html#proc-auth-code-browser) using the values configured for `myClient` and the login credentials for `bjensen`.

3. [Exchange the authorization code for an access token](oauth2-authz-grant.html#proc-auth-code-token) providing the authorization code and the values for `myClient`.

4. Finally, call [/oauth2/introspect](oauth2-introspect-endpoint.html) to verify that the access token includes the modified values:

   * The resource owner's telephone number and email address.

   * A `hello:world` key-value pair.

### Add external data to access token (next-generation script)

Complete the following steps to implement a custom access token modification script to set additional properties in the access token:

1. [Create the script](#prepare-atm-nextgen)

2. [Configure AM to use the script](#configure-atm-nextgen)

3. [Try the script](#try-atm-nextgen)

This example uses a next-generation script.

#### Create the script

Write a next-generation access token modification script to manipulate profile data.

1. [Create a script](../am-scripting/manage-scripts-console.html) of type OAuth2 Access Token Modification Script. Make sure you select Next-Generation as the evaluator version and click Create.

2. In the Script field, paste the following code:

   ```java
   // use httpclient to call external API
   var options = {
     method: "GET",
     headers: {
       "Content-Type": "application/json; charset=UTF-8"
     }
   };
   var response = httpClient.send("https://dummyjson.com/ip", options).get();
   if (response.status === 200) {
   	var ipInfo = response.json();
     // add values to the token
     accessToken.setField("browser", ipInfo.userAgent);
     accessToken.setField('ip', ipInfo.ip);

   } else {
     logger.error("Error getting IP and browser info: " + response.statusText);
   }
   // use utils binding to get random values
   var uids = [0,0,0];
   utils.crypto.getRandomValues(uids);

   // add values to be returned in the JSON response
   accessToken.addExtraJsonData('uids', uids);

   // set a shorter expiry time
   var newExpiry = Date.now() + 300000;
   accessToken.setExpiryTime(newExpiry);
   ```

   |   |                                                                                                                                                                                                                                                                                                                                                                |
   | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | You can find information about the next-generation common bindings such as `httpClient` and `utils` in [Common bindings](../am-scripting/script-bindings.html).You can find information about the bindings specific to access token modification scripts in the [Access token modification scripting API](../am-scripting/access-token-modification-api.html). |

3. Save your changes.

#### Configure AM to use the script

Set up an OAuth 2.0 provider to use the custom access token modification script.

1. [Configure the provider](customizing-oauth2-scopes.html#configure-scripted-oauth2-plugin) and make sure the following properties are set:

   * Access Token Modification Plugin Type to `SCRIPTED`.

   * Access Token Modification Plugin Script to the name of your custom access token modification script.

2. Save your changes.

#### Try the script

To verify that the script modifies the access token as expected, run an OAuth 2.0 authorization code flow as follows:

1. [Create an OAuth 2.0 client](oauth2-register-client.html) with the following values:

   * **Client ID**: `myClient`

   * **Client secret**: `mySecret`

   * **Redirection URIs**: `https://www.example.com:443/callback`

   * **Scope(s)**: `access|Access to your data`

2. [Get an authorization code](oauth2-authz-grant.html#proc-auth-code-browser) using the values configured for `myClient` and the login credentials for `bjensen`.

3. [Exchange the authorization code for an access token](oauth2-authz-grant.html#proc-auth-code-token) providing the authorization code and the values for `myClient`.

   The response includes the JSON data (`uuids`) added by the script and the updated expiry time:

   ```json
   {
       "access_token": "anmKKgqxNkTMMGVRF2aOR3D2cCc",
       "uids": [
             841804401,
             732387389,
             290315868
         ],
       "scope": "access",
       "token_type": "Bearer",
       "expires_in": 299
       ]
   }
   ```

4. Finally, call [/oauth2/introspect](oauth2-introspect-endpoint.html) to verify that the access token includes the modified values for `browser`, `ip`, and `exp`. For example:

   ```json
   {
       {
           "active": true,
           "scope": "access",
           "realm": "/alpha",
           "client_id": "myClient",
           "user_id": "bjensen",
           ...
           "exp": 1755108160,
           "browser": "Apache-HttpAsyncClient/4.1.4 (Java/17.0.10)",
           "ip": "1.240.195.84"
       }
   ```
