---
title: PingOne Authorize integration
description: Configure PingGateway with PingOne Authorize to protect APIs and web applications using authorization decisions based on group membership
component: pinggateway
version: 2024.11
page_id: pinggateway:pingone:aam
canonical_url: https://docs.pingidentity.com/pinggateway/2026/pingone/aam.html
llms_txt: https://docs.pingidentity.com/pinggateway/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2026-06-02T09:47:34Z
keywords: ["Configuration", "Authorization"]
superseded_by: https://docs.pingidentity.com/pinggateway/2026/pingone/aam.html
section_ids:
  before_you_begin: Before you begin
  add_an_oidc_client: Add an OIDC client
  enable_pingone_authorize: Enable PingOne Authorize
  add_an_api_gateway: Add an API gateway
  add_an_api_service: Add an API service
  update_the_automatically_created_resource: Update the automatically created resource
  configure_pinggateway: Configure PingGateway
  validation: Validation
  troubleshooting: Troubleshooting
  user_experience: User experience
---

# PingOne Authorize integration

Use [PingOne Authorize](https://docs.pingidentity.com/pingone/authorization_using_pingone_authorize/p1az_overview.html) with PingGateway to protect APIs and web applications. When you add a [PingOneApiAccessManagementFilter](../reference/PingOneApiAccessManagementFilter.html) to a route, PingGateway requests an authorization decision from PingOne Authorize based on the request and associated access token.

This example uses PingOne as an OIDC provider issuing an ID token with an access token. PingGateway enforces authorization decisions from PingOne Authorize. In this example, the decision to authorize access to a protected application depends on an access token scope.

## Before you begin

If you haven't already done so:

* Install PingGateway.

* Install the sample application.

* Prepare a PingOne test environment and a test user.

Learn more in the [overview page for these examples](preface.html).

## Add an OIDC client

Follow these steps to [create a PingOne OIDC web application](https://docs.pingidentity.com/pingone/applications/p1_mfa_creating_a_web_application.html):

1. In the test environment, create a web application with the following values:

   * Application Name: `oidc_client`

   * Description: `OIDC client`

   * Application Type: OIDC Web App

2. On the Overview tab of the details panel, click Protocol OpenID Connect.

3. In the Redirect URIs field, enter `https://ig.example.com:8443/home/sso/callback`. Click Save.

4. At the top-right of the application's profile, click the toggle to enable the application.

5. On the Configuration tab, make a note of the following values in the URLs list:

   * OIDC Discovery Endpoint

   * Client ID

   * Client Secret

   You need the values to set up PingGateway.

## Enable PingOne Authorize

[Add PingOne Authorize to the test environment](https://docs.pingidentity.com/pingone/authorization_using_pingone_authorize/p1az_getting_started.html).

## Add an API gateway

PingGateway uses a PingOne API gateway account to authenticate to PingOne Authorize:

1. In the test environment, go to Authorization > API Gateways and click +.

2. Enter PingGateway as the Name. Click Save.

3. Next to Credentials, click + and copy the API gateway credential.

   You need the credential value to set up PingGateway.

## Add an API service

In this example, PingOne Authorize uses a PingOne API service definition to reach authorization decisions.

The API service holds references to the following:

* The base URL for PingGateway, which is the base URL for what a user sees in their browser.

* The base URLs for the protected sample application, which is the object of an authorization decision.

* The resource to protect, which is the PingGateway URL proxying for the sample application.

* The scope required for access in this example.

  1. In the test environment, go to Authorization > API Services and click +.

  2. On the New API Service panel, add the following settings, then click Save. Accept the default values for the settings not listed here:

     | Setting                | Value                                                                                                       |
     | ---------------------- | ----------------------------------------------------------------------------------------------------------- |
     | Name                   | `PingGateway`                                                                                               |
     | Base URLs              | `https://app.example.com:8444` (for the sample application) `https://ig.example.com:8443` (for PingGateway) |
     | Enable Custom Policies | Select this.                                                                                                |

  3. Click Deploy so you can use the new API service.

## Update the automatically created resource

When you added the PingGateway API service, PingOne automatically created a corresponding resource by default. Update the resource so its audience (the `aud` in access tokens) reflects the PingGateway URL and so that it requires a `read` scope to get it:

1. In the test environment, go to Applications > Resources and click the PingGateway resource.

2. On the Overview tab, click the Pencil icon, and, in the Audience field, enter `https://ig.example.com:8443`. Click Save.

3. On the Scopes tab, click Add Scope, and in the Scope Name field, enter `read`. Click Save.

   This adds the `read` scope to the PingGateway service.

4. Go to Applications > Applications and click oidc_client.

5. On the Resources tab, edit Allowed Scopes, and select the read scope checkbox. Click Save.

## Configure PingGateway

1. Prepare the secrets PingGateway needs to act as an OIDC RP and an API gateway when making requests to PingOne.

   Base64-encode the API gateway's credential and the OIDC application's client secret and set both values as environment variables:

   ```console
   $ export GATEWAY_SECRET_ID='<base64-encoded-api-gateway-credential>'
   $ export OIDC_SECRET_ID='<base64-encoded-client-secret>'
   ```

2. Restart PingGateway to read the environment variables.

3. Add the following route to PingGateway, replacing the property values to match those from the test environment:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/oidc-ping.json
   ```

   ```
   %appdata%\OpenIG\config\routes\oidc-ping.json
   ```

   ```json
   {
     "name": "pingone-aam",
     "condition": "${find(request.uri.path, '^/home/sso')}",
     "baseURI": "https://app.example.com:8444",
     "properties": {
       "gatewayServiceUrl": "https://http-access-api.pingone.eu/v1/environments/test-environment-id",
       "oidcClientId": "oidc-client-id",
       "oidcWellKnownEndpoint": "https://auth.pingone.eu/test-environment-id/as/.well-known/openid-configuration"
     },
     "heap": [
       {
         "name": "BlindTrustReverseProxyHandler",
         "type": "ReverseProxyHandler",
         "comment": "For evaluation and testing only",
         "config": {
           "tls": {
             "type": "ClientTlsOptions",
             "config": {
               "trustManager": {
                 "type": "TrustAllManager"
               },
               "hostnameVerifier": "ALLOW_ALL"
             }
           }
         }
       },
       {
         "name": "SystemAndEnvSecretStore-1",
         "type": "SystemAndEnvSecretStore"
       },
       {
         "name": "AuthenticatedRegistrationHandler-1",
         "type": "Chain",
         "config": {
           "filters": [
             {
               "name": "ClientSecretBasicAuthenticationFilter-1",
               "type": "ClientSecretBasicAuthenticationFilter",
               "config": {
                 "clientId": "&{oidcClientId}",
                 "clientSecretId": "oidc.secret.id",
                 "secretsProvider": "SystemAndEnvSecretStore-1"
               }
             }
           ],
           "handler": "ForgeRockClientHandler"
         }
       }
     ],
     "handler": {
       "type": "Chain",
       "config": {
         "filters": [
           {
             "type": "AuthorizationCodeOAuth2ClientFilter",
             "config": {
               "clientEndpoint": "/home/sso",
               "failureHandler": {
                 "type": "StaticResponseHandler",
                 "config": {
                   "status": 500,
                   "headers": {
                     "Content-Type": [
                       "text/plain"
                     ]
                   },
                   "entity": "Error: ${contexts.oauth2Failure.error}\nDescription: ${contexts.oauth2Failure.description}"
                 }
               },
               "registrations": [
                 {
                   "type": "ClientRegistration",
                   "config": {
                     "clientId": "&{oidcClientId}",
                     "issuer": {
                       "type": "Issuer",
                       "config": {
                         "wellKnownEndpoint": "&{oidcWellKnownEndpoint}"
                       }
                     },
                     "scopes": [
                       "openid",
                       "read"
                     ],
                     "authenticatedRegistrationHandler": "AuthenticatedRegistrationHandler-1"
                   }
                 }
               ]
             }
           },
           {
             "type": "PingOneApiAccessManagementFilter",
             "config": {
               "gatewayServiceUri": "&{gatewayServiceUrl}",
               "secretsProvider": "SystemAndEnvSecretStore-1",
               "gatewayCredentialSecretId": "gateway.secret.id",
               "accessToken": "${attributes.openid.access_token}",
               "_sidebandHandler": {
                 "_comment": "s/_sidebandHandler/sidebandHandler/ to troubleshoot AAM decisions",
                 "type": "ClientHandler",
                 "capture": "all"
               }
             }
           }
         ],
         "handler": "BlindTrustReverseProxyHandler"
       }
     }
   }
   ```

   Notice the following features of the route:

   * The route properties use the settings you collected from the PingOne environment.

   * The heap has:

     * A handler to trust the self-signed sample application certificate for HTTPS blindly.

       |   |                                                                              |
       | - | ---------------------------------------------------------------------------- |
       |   | In production deployments, use certificates you don't have to trust blindly. |

     * A `SystemAndEnvSecretStore` to read get the base64-encoded secrets from the environment variables.

     * A handler to get an ID token as the OIDC client.

   * The `AuthorizationCodeOAuth2ClientFilter` gets the ID token with the `read` scope.

   * The `PingOneApiAccessManagementFilter` makes the authorization decision request to PingOne Authorize. It sends the access token from the OIDC ID token.

   * On success, the `BlindTrustReverseProxyHandler` gets the resource from the sample application.

## Validation

1. In your browser's privacy or incognito mode, go to <https://ig.example.com:8443/home/sso>.

   PingOne displays the sign-on page.

2. Sign on to PingOne as the test user.

   PingGateway displays the sample application home page:

   ![sample application home page](_images/aam-home-page.png)

## Troubleshooting

If you get unexpected errors, try these debugging options:

* Update the `PingOneApiAccessManagementFilter` configuration to enable the capture decorator.

  Change `"_sidebandHandler"` to `"sidebandHandler"` and save your work to let PingGateway reload the route.

* In the test environment, go to Authorization > Recent Decisions, select the PingGateway decision endpoint, and select a decision to visualize.

  PingOne shows you how PingOne Authorize arrived at the authorization decision.

  On the Request and Response tabs, you find detailed traces of the parameters for each.

## User experience

When PingOne Authorize denies access or the example route fails to get an access token, the browser displays text, which isn't user-friendly.

Consider using a [StaticResponseHandler](../reference/StaticResponseHandler.html) to show a more friendly page to the user.
