---
title: AI agent on behalf of an agent
description: This example describes how to configure AI agents where both the subject and the actor are machine agents, not end users.
component: pingam
version: 8.1
page_id: pingam:am-oauth2:ai-agents-agent
canonical_url: https://docs.pingidentity.com/pingam/8.1/am-oauth2/ai-agents-agent.html
section_ids:
  aiagent-agent-create-mayact: Create the may act script
  aiagent-agent-setup-subject-agent: Register the subject AI agent
  aiagent-agent-setup-actor-agent: Register the actor AI agent
  aiagent-user-token-exchange-flow: The token exchange flow
  example_token_exchange: Example token exchange
---

# AI agent on behalf of an agent

This example describes how to configure AI agents where both the subject and the actor are machine agents, not end users.

* Use case

  A risk orchestrator AI agent acts on behalf of a data-processing agent to call risk-scoring APIs, select the best result, and log an explanation.

* Prerequisites

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

* Steps

  * [Create the may act script](#aiagent-agent-create-mayact) for the risk operator agent to act on behalf of the data-processing agent.

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

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

## Create the may act script

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

   * Next-generation

   * Legacy

   ```javascript
   (function () {
       var mayAct = {
           "client_id": "risk-agent",
           "sub": "(age!risk-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', 'risk-agent');
       // the subject claim for the agent / OAuth 2.0 client application
       mayAct.put('sub', '(age!risk-agent)');
       token.setMayAct(mayAct);
   }());
   ```

2. Save your changes.

## Register the subject AI agent

Create an OAuth 2.0 AI agent to act as the data-processing agent that delegates tasks to the actor agent.

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

     `data-agent`

   * Client secret

     `mySecret`

   * Redirection URIs

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

   * Scope(s)

     `read` `write` `delete`

2. 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 actor AI agent

Create an OAuth 2.0 AI agent as the risk orchestrator that gets a delegation token to act on behalf of the data-processsing agent.

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

     `risk-agent`

   * Client secret

     `mySecret`

   * Redirection URIs

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

   * Scope(s)

     `read` `write` `delete`

## The token exchange flow

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

### Example token exchange

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

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

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

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

3. [Exchange the two access tokens](token-exchange-delegation.html) to allow the risk-orchestrating agent to act on behalf of the data processing agent, with scopes managed by AM:

   ```bash
   $ curl \
   --request POST \
   --data 'client_id=risk-agent' \
   --data 'client_secret=mySecret' \
   --data 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
   --data 'scope=read' \
   --data 'subject_token=data-agent-access-token' \
   --data 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
   --data 'actor_token=risk-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.
