---
title: AI agent on behalf of a user
description: This example describes how to configure an AI agent to get a delegation token on behalf of a user using token exchange.
component: pingam
version: 8.1
page_id: pingam:am-oauth2:ai-agents-user
canonical_url: https://docs.pingidentity.com/pingam/8.1/am-oauth2/ai-agents-user.html
section_ids:
  aiagent-user-create-mayact: Create the may act script
  aiagent-user-oauth2client: Configure the OAuth 2.0 client
  aiagent-user-setup-agent: Register the AI agent
  the_token_exchange_flow: The token exchange flow
  example_token_exchange: Example token exchange
---

# AI agent on behalf of a user

This example describes how to configure an AI agent to get a delegation token on behalf of a user using token exchange.

* Use case

  An employee wants to use an HR digital assistant to update their health plan in a third-party HR system that's protected by AM.

* Prerequisites

  * [AI agents enabled](ai-agents.html#enable-ai-agents).

  * An employee user profile, for example, `bjensen`.

* Steps

  * [Create the may act script](#aiagent-user-create-mayact) for the HR agent to act on behalf of the employee.

  * [Configure the OAuth 2.0 client](#aiagent-user-oauth2client), for example, `hr-client`.

  * [Register the AI agent](#aiagent-user-setup-agent), for example, `hr-agent`.

## Create the may act script

1. Write a [may act script](token-exchange-delegation.html#delegation-script) that adds the AI agent, `hr-agent`, to the `may_act` claim in the subject token:

   * Next-generation

   * Legacy

   ```javascript
   (function () {
       var mayAct = {
           "client_id": "hr-agent",
           "sub": "(age!hr-agent)"
       };
       token.setMayAct(mayAct);
   }());
   ```

   ```javascript
   (function () {
       var frJava = JavaImporter(
           org.forgerock.json.JsonValue);

       var mayAct = frJava.JsonValue.json(frJava.JsonValue.object());
       // the client ID that can exchange the token
       mayAct.put('client_id', 'hr-agent');
       // the subject claim for the agent / OAuth 2.0 client application
       mayAct.put('sub', '(age!hr-agent)');
       token.setMayAct(mayAct);
   }());
   ```

2. Save your changes.

## Configure the OAuth 2.0 client

Create a client application that overrides the OAuth 2.0 provider settings. This is the client that the employee uses to log in and get an access token from.

1. In the AM admin UI, go to Realms > *realm name* > Applications > OAuth 2.0 > Clients and [register a confidential OAuth 2.0 client](oauth2-register-client.html) in the same realm as the provider and user journeys.

   Provide the following values and click Create:

   * Client ID

     `hr-client`

   * Client secret

     `mySecret`

   * Redirection URIs

     `https://www.example.com:443/callback`

   * Scope(s)

     `read` `write` `delete`

2. On the Advanced tab, verify the following settings:

   * Grant Types

     `Authorization Code`

   * Token Endpoint Authentication Method

     `client_secret_basic`

3. On the OAuth2 Provider Overrides tab, save these settings:

   * Enable OAuth2 Provider Overrides

     *enabled*

   * OAuth2 Access Token May Act Script

     may act script name

## Register the AI agent

Create an OAuth 2.0 AI agent to act as the HR agent that gets a delegation token to act on behalf of the employee.

1. In the AM admin UI, go to Realms > *realm name* > Applications > OAuth 2.0 > AI Agents and [register an AI agent](ai-agents.html#register-ai-agents-ui).

   Provide the following values and click Create:

   * Client ID

     `hr-agent`

   * Client secret

     `mySecret`

   * Redirection URIs

     `https://www.example.com:443/callback`

   * Scope(s)

     `read` `write` `delete`

## The token exchange flow

![aiagent on behalf user](_images/aiagent-on-behalf-user.svg)

### Example token exchange

1. [Authenticate](../am-authentication/authn-rest.html) as the employee, `bjensen`, for example:

   ```bash
   $ curl \
   --request POST \
   --header "X-OpenAM-Username: bjensen" \
   --header "X-OpenAM-Password: Ch4ng31t" \
   --header 'Accept-API-Version: resource=2.0, protocol=1.0' \
   'https://am.example.com:8443/am/json/realms/root/realms/alpha/authenticate'
   {
       "tokenId":"user-token",
       "successUrl":"/am/console",
       "realm":"/alpha"
   }
   ```

2. [Request an authorization code](oauth2-authorize-endpoint.html) with the user token:

   ```bash
   $ curl \
   --dump-header - \
   --request POST \
   --cookie 'iPlanetDirectoryPro=user-token' \
   --data 'scope=read' \
   --data 'response_type=code' \
   --data 'client_id=hr-client' \
   --data 'csrf=user-token' \
   --data 'redirect_uri=https://www.example.com:443/callback' \
   --data 'decision=allow' \
   'https://am.example.com:8443/am/oauth2/realms/root/realms/alpha/authorize'
   …​
   location: https://www.example.com:443/callback?code=authorization-code&iss=https%3A%2F%2F…​
   …​
   ```

3. [Get a user access token](oauth2-access_token-endpoint.html) with the authorization code:

   ```bash
   $ curl \
   --request POST \
   --data 'grant_type=authorization_code' \
   --data 'client_id=hr-client' \
   --data 'client_secret=mySecret' \
   --data 'code=authorization-code' \
   --data 'redirect_uri=https://www.example.com:443/callback' \
   --data 'scope=read' \
   'https://am.example.com:8443/am/oauth2/realms/root/realms/alpha/access_token'
   {
     "access_token": "user-access-token",
     "refresh_token": "refresh-token",
     "scope": "read",
     "token_type": "Bearer",
     "expires_in": 3599
   }
   ```

4. [Get an agent access token](oauth2-client-cred-grant.html) for `hr-agent` using the client credentials flow:

   ```bash
   $ curl \
   --request POST \
   --data 'grant_type=client_credentials' \
   --data 'client_id=hr-agent' \
   --data 'client_secret=mySecret' \
   --data 'scope=read' \
   'https://am.example.com:8443/am/oauth2/realms/root/realms/alpha/access_token'
   {
     "access_token":"agent-access-token",
     "scope":"read",
     "token_type":"Bearer",
     "expires_in":3599
   }
   ```

5. [Exchange the two access tokens](token-exchange-delegation.html) to allow the HR agent to act on behalf of `bjensen`, with scopes managed by AM:

   ```bash
   $ curl \
   --request POST \
   --data 'client_id=hr-agent' \
   --data 'client_secret=mySecret' \
   --data 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
   --data 'scope=read write delete' \
   --data 'subject_token=user-access-token' \
   --data 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
   --data 'actor_token=agent-access-token' \
   --data 'actor_token_type=urn:ietf:params:oauth:token-type:access_token' \
   'https://am.example.com:8443/am/oauth2/realms/root/realms/alpha/access_token'
   {
     "access_token": "exchanged-id-token",
     "refresh_token": "new-refresh-token,"
     "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
     "scope": "read write delete",
     "token_type": "Bearer",
     "expires_in": 3599
   }
   ```

   The `issued_token_type` shows this is an exchanged token.
