---
title: PingOne Advanced Identity Cloud Proxy Connect
description: Configure PingGateway to use PingOne Advanced Identity Cloud Proxy Connect by decorating API requests with a security header for OAuth 2.0 token introspection
component: pinggateway
version: 2026
page_id: pinggateway:aic:proxy-connect
canonical_url: https://docs.pingidentity.com/pinggateway/2026/aic/proxy-connect.html
revdate: 2025-04-01T17:53:34Z
keywords: ["Security", "OAuth 2.0"]
page_aliases: ["identity-cloud-guide:proxy-connect.adoc"]
section_ids:
  goals: Goals
  prerequisites: Prerequisites
  tasks: Tasks
  task_1_configure_an_oauth_2_0_profile: "Task 1: Configure an OAuth 2.0 profile"
  proxy-connect-gateway: "Task 2: Configure PingGateway"
  proxy-connect-pre-validation: "Task 3: Pre-validation"
  proxy-connect-security-header: "Task 4: Set a Proxy Connect rule"
  validation: Validation
---

# PingOne Advanced Identity Cloud Proxy Connect

With [Proxy Connect](https://docs.pingidentity.com/pingoneaic/tenants/proxy-connect.html), PingOne Advanced Identity Cloud provides a way to secure traffic to your tenant environments in seamless compliance with the security controls you apply to your company's other network resources.

You use Proxy Connect rules to restrict access to a PingOne Advanced Identity Cloud tenant environment based on an IP address range or a required security header. If the request matches any of the rules, Proxy Connect lets the request through. If not, PingOne Advanced Identity Cloud responds with HTTP 404 Not Found. This affects the PingOne Advanced Identity Cloud UIs, too, as Proxy Connect prevents browser requests that don't follow the rules.

For externally facing applications, Proxy Connect works well with a web application firewall (WAF). A WAF protects against distributed denial-of-service, cross-site scripting, and injection attacks. The WAF isn't application-specific and so doesn't make application-specific decisions.

Requests from PingGateway can go through the WAF, but they don't always need to.

*When PingGateway redirects the browser to an end-user UI page, such as the sign-on page, target the WAF.* There's nothing special to do in PingGateway other than redirect to the WAF instead of the tenant. This includes the following use cases, where you let the WAF add the required security header to the browser and PingGateway requests:

* SSO and CDSSO

* SAML v2.0

* OpenID Connect

* Step-up and transactional authorization where a policy can return advices

*When PingGateway uses PingOne Advanced Identity Cloud APIs directly without redirecting the browser, you can skip the WAF.* This includes headless interactions that involve direct REST requests, not redirects, where you let PingGateway decorate requests with the required security header:

* PingGateway as an OAuth 2.0 resource server

* Using a [SessionInfoFilter](../reference/SessionInfoFilter.html)

* Using a [PolicyEnforcementFilter](../reference/PolicyEnforcementFilter.html) in an SDK-based client application

* Using a [UserProfileFilter](../reference/UserProfileFilter.html)

## Goals

The following example builds on the [OAuth 2.0 and PingOne Advanced Identity Cloud](oauthrs.html) use case.

It shows how to decorate requests to PingOne Advanced Identity Cloud with a security header for Proxy Connect.

## Prerequisites

* Get access as an administrator to a PingOne Advanced Identity Cloud tenant with the Proxy Connect add-on feature.

  Wait to add Proxy Connect rules until you have [added a route to PingGateway](#proxy-connect-gateway) and [verified the route works without restrictions](#proxy-connect-pre-validation).

* Complete the [example installation](preface.html#preface-examples) steps to use PingGateway with PingOne Advanced Identity Cloud.

  You don't need the sample application for this example.

## Tasks

### Task 1: Configure an OAuth 2.0 profile

Configure an OAuth 2.0 client profile for PingGateway as a resource server:

1. Sign on to the Advanced Identity Cloud admin UI as an administrator.

2. Go to Applications > + Custom Application > OIDC - OpenId Connect > Web and add a web application with the following settings:

   * Name

     `oauth2-client`

   * Owners

     `demo user`

   * Client Secret

     `password`

   * Sign On > Grant Types

     Add `Resource Owner Password Credentials`

   * Sign On > Scopes

     Add `mail`

### Task 2: Configure PingGateway

1. [Configure PingGateway for HTTPS](../installation-guide/securing-connections.html#server-side-tls).

2. Set an environment variable for the base64-encoded PingGateway agent password.

   The following command sets the variable to a base64-encoding of the string `password`.

   ```console
   $ export AGENT_SECRET_ID='cGFzc3dvcmQ='
   ```

   A `SystemAndEnvSecretStore` in the route that follows reads the base64-encoded password.

3. Restart PingGateway to reload `admin.json` and access the agent password.

4. Add a route for token introspection that decorates requests with the security header.

   * Linux

     `$HOME/.openig/config/routes/proxy-connect.json`

   * Windows

     `%appdata%\OpenIG\config\routes\proxy-connect.json`

   > **Collapse: Show route**
   >
   > ```json
   > {
   >   "name": "proxy-connect",
   >   "condition": "${find(request.uri.path, '^/proxy-connect')}",
   >   "properties": {
   >     "gatewayUsername": "ig_agent",
   >     "gatewayPasswordSecretId": "agent.secret.id",
   >     "amServiceUrl": "https://myTenant.forgeblocks.com/am"
   >   },
   >   "heap": [
   >     {
   >       "name": "SystemAndEnvSecretStore-1",
   >       "type": "SystemAndEnvSecretStore"
   >     },
   >     {
   >       "name": "SecurityHeaderFilter",
   >       "type": "HeaderFilter",
   >       "config": {
   >         "messageType": "REQUEST",
   >         "add": {
   >           "X-Security-Header": [
   >             "f1drybngmzqj5loposddd5p98z886jp9"
   >           ]
   >         },
   >         "_comment": "The Proxy Connect rule you configure matches this header."
   >       },
   >       "capture": "filtered_request"
   >     },
   >     {
   >       "name": "AmService-1",
   >       "type": "AmService",
   >       "config": {
   >         "url": "&{amServiceUrl}",
   >         "realm": "/alpha",
   >         "agent": {
   >           "username": "&{gatewayUsername}",
   >           "passwordSecretId": "&{gatewayPasswordSecretId}"
   >         },
   >         "secretsProvider": "SystemAndEnvSecretStore-1",
   >         "amHandler": {
   >           "type": "Chain",
   >           "config": {
   >             "filters": [
   >               "SecurityHeaderFilter"
   >             ],
   >             "handler": "ForgeRockClientHandler"
   >           }
   >         },
   >         "notifications": {
   >           "_comment": "Avoid UpgradeRejectedException: WebSocket upgrade failure: 404",
   >           "enabled": false
   >         }
   >       }
   >     }
   >   ],
   >   "handler": {
   >     "type": "Chain",
   >     "config": {
   >       "filters": [
   >         {
   >           "name": "OAuth2ResourceServerFilter-1",
   >           "type": "OAuth2ResourceServerFilter",
   >           "config": {
   >             "scopes": [
   >               "mail"
   >             ],
   >             "requireHttps": false,
   >             "accessTokenResolver": {
   >               "name": "TokenIntrospectionAccessTokenResolver-1",
   >               "type": "TokenIntrospectionAccessTokenResolver",
   >               "config": {
   >                 "amService": "AmService-1",
   >                 "providerHandler": {
   >                   "type": "Chain",
   >                   "config": {
   >                     "filters": [
   >                       "SecurityHeaderFilter",
   >                       {
   >                         "type": "HttpBasicAuthenticationClientFilter",
   >                         "config": {
   >                           "username": "&{gatewayUsername}",
   >                           "passwordSecretId": "&{gatewayPasswordSecretId}",
   >                           "secretsProvider": "SystemAndEnvSecretStore-1"
   >                         }
   >                       }
   >                     ],
   >                     "handler": "ForgeRockClientHandler"
   >                   }
   >                 }
   >               }
   >             }
   >           }
   >         }
   >       ],
   >       "handler": {
   >         "type": "StaticResponseHandler",
   >         "config": {
   >           "status": 200,
   >           "headers": {
   >             "Content-Type": [
   >               "text/html; charset=UTF-8"
   >             ]
   >           },
   >           "entity": "<html><body><h2>Decoded access_token: ${contexts.oauth2.accessToken.info}</h2></body></html>"
   >         }
   >       }
   >     }
   >   }
   > }
   > ```

   Source: [proxy-connect.json](../_attachments/config/routes/proxy-connect.json).

   The Proxy Connect route:

   * Matches requests whose path starts with `proxy-connect`.

   * Defines a [HeaderFilter](../reference/HeaderFilter.html) to add the security header.

     The header name and value must match the Proxy Connect header rule you configure. This route uses `f1drybngmzqj5loposddd5p98z886jp9` to match the header rule set in [Task 4: Set a Proxy Connect rule](#proxy-connect-security-header).

   * Configures an [AmService](../reference/AmService.html) whose requests PingGateway decorates with the security header.

     As the service can't decorate websocket requests for notifications, the configuration disables notifications.

   * Uses a [OAuth2ResourceServerFilter](../reference/OAuth2ResourceServerFilter.html) with a [TokenIntrospectionAccessTokenResolver](../reference/TokenIntrospectionAccessTokenResolver.html) to introspect access tokens.

   * Adds a [StaticResponseHandler](../reference/StaticResponseHandler.html) to display the results of introspection.

5. Update the route's `amServiceUrl` setting to target the PingOne Advanced Identity Cloud tenant and save your work.

   PingGateway loads the route.

### Task 3: Pre-validation

Before you add Proxy Connect rules to restrict access, verify the route works *without* restrictions.

1. Get an access token using the resource owner password credentials flow:

   ```console
   $ export ACCESS_TOKEN=$(curl \
   --request POST 'https://myTenant.forgeblocks.com/am/oauth2/realms/alpha/access_token' \
   --user 'oauth2-client:password' \
   --data 'grant_type=password' \
   --data 'username=demo' \
   --data 'password=Ch4ng3!t' \
   --data 'scope=mail' \
   --silent | jq -r ".access_token")
   ```

   You don't need the security header until you configure a Proxy Connect header rule.

2. Use the route to introspect the access token:

   ```console
   $ curl \
   --request GET 'https://ig.example.com:8443/proxy-connect' \
   --insecure \
   --header "Authorization: Bearer ${ACCESS_TOKEN}"
   ```

   Output

   ```none
   <html><body><h2>Decoded access_token:
   {active=true,
   scope=mail,
   realm=/alpha,
   client_id=oauth2-client,
   user_id=<uuid>,
   username=<uuid>,
   token_type=Bearer,
   exp=<seconds>,
   sub=<uuid>,
   iss=https://myTenant.forgeblocks.com:443/am/oauth2/realms/root/realms/alpha,
   subname=<uuid>,
   auth_level=0,
   authGrantId=<id>,
   auditTrackingId=<uuid>,
   expires_in=<seconds>}</h2></body></html>
   ```

### Task 4: Set a Proxy Connect rule

Learn about this in the [Proxy Connect](https://docs.pingidentity.com/pingoneaic/tenants/proxy-connect-api.html) documentation. Once you understand the steps:

1. Configure a Proxy Connect rule to require the following security header, which is the same one set in the Proxy Connect route configuration:

   ```none
   'X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9'
   ```

   When you first update the header rules, the change is pending (`"requestStatus": "PENDING"`). PingOne Advanced Identity Cloud doesn't check for the security header when the update is still pending.

2. Poll the Proxy Connection configuration in PingOne Advanced Identity Cloud until the request has `"requestStatus": "SUCCESS"`.

   |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | Once the request is successful, you can't use the Advanced Identity Cloud admin UI. Your browser doesn't add the security header by default.If you must use the Advanced Identity Cloud admin UI again, either reset the header rules to `{"enabled": false, "headers": []}` or [configure your browser to add the security header](https://docs.pingidentity.com/pingoneaic/tenants/proxy-connect-api.html#prerequisite-actions-for-accessing-a-tenant-when-rulesets-are-configured). |

## Validation

1. Get an access token using the resource owner password credentials flow:

   ```console
   $ export ACCESS_TOKEN=$(curl \
   --request POST 'https://myTenant.forgeblocks.com/am/oauth2/realms/alpha/access_token' \
   --user 'oauth2-client:password' \
   --data 'grant_type=password' \
   --data 'username=demo' \
   --data 'password=Ch4ng3!t' \
   --data 'scope=mail' \
   --header 'X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9' \
   --silent | jq -r ".access_token")
   ```

2. Use the route to introspect the access token:

   ```console
   $ curl \
   --request GET 'https://ig.example.com:8443/proxy-connect' \
   --insecure \
   --header "Authorization: Bearer ${ACCESS_TOKEN}"
   ```

   Output

   ```none
   <html><body><h2>Decoded access_token:
   {active=true,
   scope=mail,
   realm=/alpha,
   client_id=oauth2-client,
   user_id=<uuid>,
   username=<uuid>,
   token_type=Bearer,
   exp=<seconds>,
   sub=<uuid>,
   iss=https://myTenant.forgeblocks.com:443/am/oauth2/realms/root/realms/alpha,
   subname=<uuid>,
   auth_level=0,
   authGrantId=<id>,
   auditTrackingId=<uuid>,
   expires_in=<seconds>}</h2></body></html>
   ```

3. In the PingGateway log, notice the filtered requests have the security header:

   ```none
   [CONTINUED]--- (filtered-request) exchangeId:<uuid> - transactionId:<uuid> --->

   [CONTINUED]POST https://myTenant.forgeblocks.com/am/oauth2/realms/root/realms/alpha/introspect HTTP/1.1
   [CONTINUED]Accept: application/json
   [CONTINUED]Content-Length: 918
   [CONTINUED]Content-Type: application/x-www-form-urlencoded
   [CONTINUED]X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9

   [CONTINUED]token=<token>&token_type_hint=access_token
   ```

   Change `"capture"` to `"_capture"` in the Proxy Connect route to avoid flooding the PingGateway logs.

You've successfully shown how to use PingGateway with Proxy Connect.
