Remote proxy setup
Follow these steps to configure a remote proxy between an originating tenant and a receiving tenant. This configuration allows the originating tenant to make API calls to the receiving tenant securely.
Task 1: Create an OAuth 2.0 client on the receiving tenant
On the receiving tenant, create an OAuth 2.0 client that the originating tenant uses to authenticate:
-
Get a service account token for the receiving tenant.
-
Create and sign a JSON Web Token (JWT) using your service account, then exchange it for an access token:
Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header "Accept-API-Version: resource=1.0" \ --request POST "https://<receiving-tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token" \ --data 'client_id=service-account' \ --data 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \ --data 'assertion=<signed-jwt-token>' \ --data 'scope=fr:am:* fr:idm:*'Response{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc…", "token_type": "Bearer", "expires_in": 3599 } -
Create the OAuth 2.0 client using the access token returned in step 2:
Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header 'Content-Type: application/json' \ --header 'Accept-API-Version: resource=1.0' \ --request PUT "https://<receiving-tenant-env-fqdn>/am/json/realms/root/realms/alpha/realm-config/agents/OAuth2Client/idmprovisioning" \ --data '{ "_id": "idmprovisioning", "coreOAuth2ClientConfig": { "clientType": "Confidential", "redirectionUris": [], "scopes": ["fr:idm:*"], "defaultScopes": ["fr:idm:*"], "clientName": { "en": "IDM Provisioning Client" }, "userpassword": "<client-secret>" }, "advancedOAuth2ClientConfig": { "tokenEndpointAuthMethod": "client_secret_post", "grantTypes": ["client_credentials"] } }'Consider the following:
-
tokenEndpointAuthMethod: Must beclient_secret_post -
grantTypes: Must includeclient_credentials -
scopes: Must includefr:idm:*
Response{ "_id": "idmprovisioning", "coreOAuth2ClientConfig": { "clientType": "Confidential", "scopes": [ "fr:idm:*" ] } } -
Task 2: Add a static user mapping on the receiving tenant
The OAuth 2.0 client needs permissions to access PingIDM endpoints. Configure a static user mapping:
-
Get the current authentication configuration:
Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<receiving-tenant-env-fqdn>/openidm/config/authentication"Response{ "_id": "authentication", "rsFilter": { "serverAuthContext": { "authModules": […] }, "staticUserMapping": [] } } -
Add the static user mapping:
You must add the new mapping to the existing configuration, not replace it. Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header "Content-type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --request PUT "https://<receiving-tenant-env-fqdn>/openidm/config/authentication" \ --data '{ "_id": "authentication", "rsFilter": { "serverAuthContext": { "authModules": [ … existing modules … ] }, "staticUserMapping": [ { "subject": "idmprovisioning", (1) "localUser": "internal/user/openidm-admin", "roles": [ "internal/role/openidm-authorized", "internal/role/openidm-admin", "internal/role/platform-provisioning" ], "userRoles": "authzRoles/*" } ] } }'1 The subjectmust match your OAuth 2.0 client ID.
Task 3: Create an external proxy on the originating tenant
On the originating tenant, create the external proxy configuration:
-
Get a service account token for the originating tenant:
Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header "Accept-API-Version: resource=1.0" \ --request POST "https://<originating-tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token" \ --data 'client_id=service-account' \ --data 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \ --data 'assertion=<signed-jwt-token>' \ --data 'scope=fr:idm:*' -
Create the external configuration:
Requestcurl \ --header "Authorization: Bearer <access-token>" \ --header "Content-type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --request PUT "https://<originating-tenant-env-fqdn>/openidm/config/external.idm/<receiving-tenant-name>" \(1) --data '{ "enabled": true, "authType": "bearer", "instanceUrl": "https://<receiving-tenant-env-fqdn>/openidm/", (2) "clientId": "idmprovisioning", "clientSecret": "&{esv.idmprovisioning.client.secret}", (3) "scope": ["fr:idm:*"], "tokenEndpoint": "https://<receiving-tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token", "tokenEndpointAuthMethod": "client_secret_post", "scopeDelimiter": " " }'1 This configuration defines the endpoint and is accessible at runtime using /openidm/external/idm/<receiving-tenant-name>.2 The instanceUrlmust end with a trailing slash.3 Use an ESV secret for clientSecretinstead of a plaintext value.After creating the ESV, restart Advanced Identity Cloud services so the placeholder resolves. Response{ "enabled": true, "authType": "bearer", "instanceUrl": "https://<receiving-tenant-env-fqdn>/openidm/" }
Task 4: Verify the proxy configuration
Test that the proxy works by querying users from the receiving tenant:
curl \
--header "Authorization: Bearer <access-token>" \
--header "Content-type: application/json" \
--header "Accept-API-Version: resource=1.0" \
--request GET "https://<originating-tenant-env-fqdn>/openidm/external/idm/<receiving-tenant-name>/managed/realm-name_user?_queryFilter=true&_pageSize=10"
{
"result": [
{
"_id": "95b2b43c-621e-4bca-8a97-efc768f17751",
"_rev": "00000000f20217df",
"userName": "bjensen",
"accountStatus": "active",
"givenName": "Barbara",
"sn": "Jensen",
"mail": "bjensen@example.com"
}
],
"resultCount": 1,
"pagedResultsCookie": null,
"totalPagedResults": -1
}
If you get an error, review the following:
-
401 Unauthorized: Check OAuth 2.0 client credentials.
-
403 Forbidden: Verify the static user mapping is configured.
-
404 Not Found: Verify the configuration name and realm name.
-
500 Server Error: Check logs on both originating and receiving tenants.