---
title: Cross-domain single sign-on for PingAM
description: This page shows how to set up Cross-Domain Single Sign-On (CDSSO) for requests in a different domain:
component: pinggateway
version: 2026
page_id: pinggateway:gateway-guide:cdsso
canonical_url: https://docs.pingidentity.com/pinggateway/2026/gateway-guide/cdsso.html
revdate: 2025-10-15T18:45:22Z
---

# Cross-domain single sign-on for PingAM

This page shows how to set up Cross-Domain Single Sign-On (CDSSO) for requests in a different domain:

|   |                                                                                                                                                                                                                                                                                          |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | To require users to authenticate in the correct realm for security reasons, configure SSO or CDSSO with a PolicyEnforcementFilter that refers to an AM policy where the realm is enforced. You can find an example in [Requiring authentication to an PingAM realm](pep-sso-realm.html). |

The SSO mechanism depicted in the following diagram can be used when PingGateway and AM are running in the same domain. When PingGateway and AM are running in different domains, AM cookies aren't visible to PingGateway because of the same-origin policy.

CDSSO using the CrossDomainSingleSignOnFilter provides a mechanism to push tokens issued by AM to PingGateway running in a different domain.

The following sequence diagram shows the flow of information between PingGateway, AM, and the sample application during CDSSO. In this example, AM is running on `am.example.com`, and PingGateway is running on `ig.ext.com`.

![cdsso](https://kroki.io/plantuml/svg/eNqNVEFu2zAQvPMVi1xyqZXGBVoggAO4bmsYqNHCTnLyhZbWFhGJZEkqjp_Ub_RlHUqyYjlNmpMMcnZmd2ZpcXEuaGLs3qltHujPbxq-v_xEA3yGH-mn0luaZayDCnvAnDVOBmW0EHSTK0-pyZjwDYbWTJXnjPgxLSqvHrjYk9JAaM1prKGdCvkrlOTNJuykYzKOPLsHlbJPxMsVZDQ0zGbDzpOv0vyfDLG3greyoJpBsRe0yw3l8oHjETs0rTRQktZKZ1GtQKH2THLrmEuA_tN7Is4vhJBVMLoq1-yEsNIFlSorUXv22Zkd2jkj6an93QdE4qkMvJP7lVbbhB9DkpqyLphNn2PH85WWJWCytAV30PG8D13W1zS2FnBrn-OtFUK0HQ2uZ9MrWvCvin2IpskU7sHYhgT1YjSiy4RuNQbNowkpWs5o3dQTfFQOUeMI1U2btEESR_CY2mgkZtPBdSt7RRPH4IH72ugUX52RDwYhYns8OkDNSi9a8k6tk3jqfzx_6r-vKcbz5vq72YK1igRRxzXolW57mHxZLn-A-p6x4Zh2mND41VljGwZPR2ns1-1iFoeLWt1wKDe-WpcqRCvKiD_UftWZNVi8d81yHWnHbGo00pQlY0X7Ib2FdKXfwBpziIR3slDZqQGHy0nO6X0bDpTwoDcqiuYyYDmREh5VNGel4dSp8R2J0T64Co6lxtwrjjRBohYv6lS0M2_xgsutYw2TqJP6kHTRY0b8B2TNGmJti6PF69n4zRSF2XXW9VnfZM1Bctms6UxvTL1XMsuaUOrrDr6s1_opEKzi0pub-Bv-BLz6E-hxegBPMsCPkXjAcYx63k4Nh4fuQuU0zr2F-3zqbf_yLy-zGr8=?id=figure-cdsso-auth)

**1\.** The browser sends an unauthenticated request to access the sample app.

**2-3.** PingGateway intercepts the request, and redirects the browser to AM for authentication.

**4\.** AM authenticates the user and creates a CDSSO token.

**5\.** AM responds to a successful authentication with an HTML autosubmit form containing the issued token.

**6\.** The browser loads the HTML and autosubmit form parameters to the PingGateway callback URL for the redirect endpoint.

**7\.** When `verificationSecretId` in CrossDomainSingleSignOnFilter is configured, PingGateway uses it to verify signature of AM session tokens.

When `verificationSecretId` isn't configured, PingGateway discovers and uses the AM JWK set to verify the signature of AM session tokens.

If that fails, the CrossDomainSingleSignOnFilter fails to load.

**8\.** PingGateway checks the nonce found inside the CDSSO token to confirm that the callback comes from an authentication initiated by PingGateway.

**9\.** PingGateway constructs a cookie, and fulfills it with a cookie name, path, and domain, using the CrossDomainSingleSignOnFilter property `authCookie`. The domain must match that set in the AM PingGateway agent.

**10-11.** PingGateway redirects the request back to the original URI, with the cookie, and the browser follows the redirect back to PingGateway.

**12\.** PingGateway validates the SSO token inside the CDSSO token

**13-15.** PingGateway adds the AM session info to the request, and stores the SSO token and CDSSO token in the contexts for use by downstream filters and handlers.

**16-18.** PingGateway forwards the request to the sample application, and the sample application returns the requested resource to the browser.

Before you begin, prepare AM, PingGateway, and the sample application. Learn more in the [example installation for this guide](preface.html#preface-examples).

1. Set up AM:

   1. Register a PingGateway agent with the following values, as described in [Register a PingGateway agent in AM](preface.html#register-agent-am):

      * Agent ID: `ig_agent_cdsso`

      * Password: `password`

      * Redirect URL for CDSSO: `https://ig.ext.com:8443/home/cdsso/redirect`

        |   |                                                                                                                   |
        | - | ----------------------------------------------------------------------------------------------------------------- |
        |   | Use secure passwords in a production environment. Consider using a password manager to generate secure passwords. |

   2. Select Services > Add a Service, and add a Validation Service with the following Valid goto URL Resources:

      * `https://ig.ext.com:8443/*`

      * `https://ig.ext.com:8443/*?*`

   3. Select Configure > Global Services > Platform, and add `example.com` as an AM cookie domain.

      By default, AM sets host-based cookies. After authentication with AM, requests can be redirected to AM instead of to the resource.

2. Set up PingGateway:

   1. Set up PingGateway for HTTPS, as described in [Configure PingGateway for TLS (server-side)](../installation-guide/securing-connections.html#server-side-tls).

   2. Make sure PingGateway connects to the sample application over HTTPS with a route to access static resources.

      Learn more in [Using the sample application](../getting-started/start-sampleapp.html).

   3. Add the following `session` configuration to `admin.json`.

      This ensures the browser passes the session cookie in the form-POST to the redirect endpoint (step 6 of [Information flow during CDSSO](#figure-cdsso-auth)):

      ```
      {
        "connectors": […​],
        "session": {
          "type": "InMemorySessionManager",
          "config": {
            "cookie": {
              "sameSite": "none",
              "secure": true
            }
          }
        },
        "heap": […​]
      }
      ```

      This step is required for the following reasons:

      * When `sameSite` is `strict` or `lax`, the browser doesn't send the session cookie, which contains the nonce used in validation. If PingGateway doesn't find the nonce, it assumes that the authentication failed.

      * When `secure` is `false`, the browser is likely to reject the session cookie.

        Learn more in [AdminHttpApplication (`admin.json`)](../reference/AdminHttpApplication.html).

   4. Set an environment variable for the PingGateway agent password, and then restart PingGateway:

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

      The password is retrieved by a SystemAndEnvSecretStore, and must be base64-encoded.

   5. Add the following route to PingGateway:

      * Linux

        `$HOME/.openig/config/routes/cdsso.json`

      * Windows

        `%appdata%\OpenIG\config\routes\cdsso.json`

      ```json
      {
        "name": "cdsso",
        "baseURI": "https://app.example.com:8444",
        "condition": "${find(request.uri.path, '^/home/cdsso')}",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          },
          {
            "name": "AmService-1",
            "type": "AmService",
            "config": {
              "url": "http://am.example.com:8088/openam",
              "realm": "/",
              "agent": {
                "username": "ig_agent_cdsso",
                "passwordSecretId": "agent.secret.id"
              },
              "secretsProvider": "SystemAndEnvSecretStore-1",
              "sessionCache": {
                "enabled": false
              }
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "name": "CrossDomainSingleSignOnFilter-1",
                "type": "CrossDomainSingleSignOnFilter",
                "config": {
                  "redirectEndpoint": "/home/cdsso/redirect",
                  "authCookie": {
                    "path": "/home",
                    "name": "ig-token-cookie"
                  },
                  "amService": "AmService-1"
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }
      ```

      Source: [cdsso.json](../_attachments/config/routes/cdsso.json)

      Notice the following features of the route:

      * The route matches requests to `/home/cdsso`.

      * The agent password for AmService is provided by a SystemAndEnvSecretStore in the heap.

      * Because the CrossDomainSingleSignOnFilter's `verificationSecretId` isn't configured, PingGateway discovers and uses the AM JWK set to verify the signature of AM session tokens. If that fails, the CrossDomainSingleSignOnFilter fails to load.

3. Test the setup:

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

      The CrossDomainSingleSignOnFilter redirects the request to AM for authentication.

   2. Sign on to AM as user `demo`, password `Ch4ng31t`.

      When you have authenticated, AM calls `/home/cdsso/redirect`, and includes the CDSSO token. The CrossDomainSingleSignOnFilter passes the request to sample app, which returns the home page.
