PingOne Advanced Identity Cloud

Configure a DCR onboarding flow

To streamline the onboarding of OAuth 2.0 clients, Advanced Identity Cloud supports Dynamic Client Registration (DCR), which allows for the automated creation and configuration of dynamic clients without manual intervention.

What is Dynamic Client Registration (DCR)?

Dynamic Client Registration (DCR) is an OAuth 2.0 extension that allows dynamic clients to be programmatically registered with an authorization server at runtime without manual administrative intervention. Instead of a static setup, dynamic clients send their own metadata (including names and authorized redirect URLs) directly to a dedicated registration endpoint to obtain unique credentials. This process is essential for scaling high-velocity environments where numerous individual client instances require distinct identities for secure tracking and lifecycle management.

Task 1: Configure the OAuth 2.0 provider service

Configure the OAuth 2.0 provider service to support the grant types needed for the "on behalf of" authentication flow:

  1. In the Advanced Identity Cloud admin console, go to Native Consoles > Access Management > Services.

  2. Click the OAuth2 Provider service, then click the Advanced tab:

    1. In the Grant Types field, select the Client Credentials grant type, if it isn’t already selected.

    2. In the Client Registration Scope Allowlist field, select the scopes that AI-driven solutions can request when they use the DCR onboarding flow to onboard AI agents.

  3. Click the Client Dynamic Registration tab:

    • Select the Allow Open Dynamic Client Registration checkbox, if it isn’t already selected.

  4. Click Save Changes.

Task 2: Get OpenID Connect configuration

Get the OpenID Connect (OIDC) configuration for your tenant environment to find the DCR endpoint and available scopes:

$ curl \
--request GET 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/<realm>/.well-known/openid-configuration' \(1)(2)
Show request guidance
1 Replace <tenant-env-fqdn> with the FQDN of your tenant environment.
2 Replace <realm> with either alpha or bravo.
{
    "request_parameter_supported": true,
    ...
    "scopes_supported": [ (1)
        "address",
        "phone",
        "openid",
        "profile",
        "fr:idm:*",
        "am-introspect-all-tokens",
        "email",
        "data-read",
        "data-write"
    ],
    ...
    "registration_endpoint": "https://<tenant-env-fqdn>:443/am/oauth2/realms/root/realms/alpha/register" (2)
}
Show response guidance
1 The scopes_supported value should correspond to the scopes you set in the Client Registration Scope Allowlist field in task 1.
2 Note the registration_endpoint value. This is the endpoint you will use in the next task to onboard AI agents using DCR.

Task 3: Register a dynamic client

Use the DCR endpoint to register a dynamic client:

$ curl \
--request POST 'https://<tenant-env-fqdn>:443/am/oauth2/realms/root/realms/<realm>/register' \(1)(2)
--header 'Content-Type: application/json' \
--data '{(3)
    "grant_types": ["client_credentials"],
    "response_types": ["token"],
    "redirect_uris": <dynamic-client-redirect-uris>,(4)
    "scopes": <dynamic-client-scopes>,(5)
    "client_name": <dynamic-client-name>,(6)
    "token_endpoint_auth_method": "client_secret_post"(7)
}'
Show request guidance
1 Replace <tenant-env-fqdn> with the FQDN of your tenant environment.
2 Replace <realm> with either alpha or bravo.
3 The JSON payload contains the metadata needed to onboard a dynamic client.
4 Replace <dynamic-client-redirect-uris> with a JSON array of one or more absolute URLs for the dynamic client you want to onboard. For example, ["https://example.com/callback"]. The URLs you set in redirect_uris act as a secure allowlist, identifying the only authorized endpoints where the authorization server can send sensitive response data, such as authorization codes or tokens, upon successful end user interaction.
5 Replace <dynamic-client-scopes> with a JSON array of one or more scopes that the dynamic client can request. For example, ["data-read", "data-write"].
6 Replace <dynamic-client-name> with a human-readable name for the dynamic client you want to onboard. For example, Retail Chatbot or Workforce Assistant. This name is used to identify the dynamic client to end users on consent screens and to tenant administrators within the Advanced Identity Cloud admin console.
7 The token_endpoint_auth_method parameter defines how the dynamic client authenticates when requesting an access token. By setting this to client_secret_post, the client identifies as a confidential client that will provide its client_id and client_secret directly within the HTTP POST request body.
{
    ...
    "client_id": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c", (1)
    ...
    "client_secret": "zhYjm03cS9…​ayPVIwZsgQ", (1)
    ...
    "grant_types": [
        "client_credentials"
    ],
    ...
    "redirect_uris": [
        "https://example.com/callback"
    ],
    ...
    "scopes": [
        "data-read",
        "data-write"
    ],
    ...
    "response_types": [
        "token"
    ]
}
Show response guidance
1 Note the client_id and client_secret values. These are the credentials for the dynamic client you just onboarded. You’ll use these credentials in the next task to authenticate the dynamic client and obtain access tokens for it to access applications on behalf of end users.

Task 4: Get a dynamic client access token

  1. Get an access token for the dynamic client using the Client Credentials grant type:

    $ curl \
    --request POST 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token' \(1)
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=client_credentials' \(2)
    --data-urlencode 'client_id=<dynamic-client-client-id>' \(3)
    --data-urlencode 'client_secret=<dynamic-client-client-secret>' \(4)
    --data-urlencode 'scope=<dynamic-client-scopes>'(5)
    Show request guidance
    1 Replace <tenant-env-fqdn> with the FQDN of your tenant environment.
    2 The grant_type for this request is client_credentials, which represents the Client Credentials grant type.
    3 Replace <dynamic-client-client-id> with the client ID of the dynamic client you registered in task 3. For example, ab9da93d-e9ad-40ca-ba43-3be6eb63af3c.
    4 Replace <dynamic-client-client-secret> with the client secret of the dynamic client.
    5 Replace <dynamic-client-scopes> with some or all of the scopes you assigned to the dynamic client. For example, data-read.
    {
        "access_token": "eyJ0eXAiOi...l2Yz6xCHHu0", (1)
        "scope": "data-read",
        "token_type": "Bearer",
        "expires_in": 3599
    }
    Show response guidance
    1 The access_token value in the response is the dynamic client’s access token.
  2. Introspect the end user’s access token to verify that the sub claim represents the end user and the token contains the expected scopes:

    $ curl \
    --request POST 'https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/introspect' \(1)
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'token=<dynamic-client-access-token>' \(2)
    --data-urlencode 'client_id=<dynamic-client-client-id>' \(3)
    --data-urlencode 'client_secret=<dynamic-client-client-secret>' \(4)
    Show request guidance
    1 Replace <tenant-env-fqdn> with the FQDN of your tenant environment.
    2 Replace <dynamic-client-access-token> with the dynamic client’s access token from the response in step 2.
    3 Replace <dynamic-client-client-id> with client ID of the dynamic client. For example, ab9da93d-e9ad-40ca-ba43-3be6eb63af3c.
    4 Replace <dynamic-client-client-secret> with the client secret of the dynamic client.
    {
        "active": true,
        "scope": "data-read", (1)
        "realm": "/alpha",
        "client_id": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c",
        "user_id": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c",
        "username": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c",
        "token_type": "Bearer",
        "exp": 1776456596,
        "sub": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c",
        "iss": "https://<tenant-env-fqdn>:443/am/oauth2/realms/root/realms/alpha",
        "subname": "ab9da93d-e9ad-40ca-ba43-3be6eb63af3c",
        "authGrantId": "lggr9JyNOuls2AzqoZocHIA4qPI",
        "auditTrackingId": "448cbba7-ba1a-43e7-bbea-f3a707ba6dde-112434",
        "expires_in": 3273
    }
    Show response guidance
    1 The scope claim contains the scopes that the dynamic client can access.