Configuring SSO for Embedded Client Applications in Genesys Cloud
What This Guide Covers
This guide details the end-to-end configuration required to authenticate users via SAML 2.0 or OIDC and seamlessly inject them into Genesys Cloud Embedded Client components within an external application. When complete, your users will access PureEngage, PurePredict, or Conversational Messaging inside your custom interface without credential prompts, with fully synchronized session state and zero manual token handling on the client side.
Prerequisites, Roles & Licensing
- Licensing Tiers: Genesys Cloud CX 2 or higher for SAML 2.0/OIDC SSO. CX 1 or higher for Embedded Client components. WEM Analytics add-on is required only if embedding workforce management dashboards.
- Platform Permissions:
User Management > Single Sign-On > EditUser Management > OAuth 2.0 Clients > EditTelephony > Trusted Domains > EditIntegration > Embedded Client > Configure
- OAuth 2.0 Scopes:
client:read,user:read,embedded-client:configure,telephony:read,conversation:read,organization:read - External Dependencies: Identity Provider supporting SAML 2.0 or OIDC (Okta, Azure AD, Ping Identity, Auth0), reverse proxy or application server capable of handling OAuth token exchange, external application hosting the iframe with controlled CSP headers.
The Implementation Deep-Dive
1. Identity Provider and OAuth Client Provisioning
Genesys Cloud does not consume raw SAML assertions or OIDC ID tokens directly within the Embedded Client SDK. The platform requires a hybrid authentication model. Your identity provider authenticates the user, but the embedded component requires a Genesys-specific OAuth 2.0 access token to fetch user context, establish WebSocket media channels, and render queue states. You must provision a dedicated OAuth client in Genesys Cloud and configure your IdP to trigger an authorization code flow that resolves to a Genesys access token.
Begin by creating the OAuth client in the Genesys Cloud Admin console. Navigate to User Management > OAuth 2.0 Clients and select Add OAuth 2.0 Client. Set the application type to Confidential if your token exchange occurs server-side, or Public if you are implementing PKCE in a single-page application. Assign the exact scopes listed in the prerequisites. Generate the client secret immediately and store it in a vault. Do not hardcode it in frontend bundles.
Configure your identity provider to use the Genesys Cloud authorization endpoint:
https://login.mypurecloud.com/oauth/authorize
Set the token endpoint to:
https://api.mypurecloud.com/api/v2/oauth/token
The Trap: Assigning the embedded-client:configure scope but omitting telephony:read and conversation:read. The Embedded Client SDK will initialize successfully, but media channels will fail to bind. The UI will render a silent white screen or throw a MediaSessionError: 403 Forbidden when attempting to establish SIP or WebRTC connections. Genesys evaluates scope boundaries at the WebSocket handshake level, not during iframe load. We require the telephony and conversation scopes to allow the client to poll queue positions, fetch active interactions, and route media streams.
After client creation, configure the SSO provider in User Management > Single Sign-On. Select SAML 2.0 or OIDC. Input your IdP metadata URL or manual configuration values. Map the email or username claim to the Genesys email attribute. Enable Allow user self-registration only if your provisioning strategy relies on JIT provisioning. For enterprise deployments, disable self-registration and enforce SCIM 2.0 provisioning to maintain strict role synchronization.
2. Trusted Domain Registration and CORS Alignment
The Embedded Client operates inside an iframe hosted on your domain. Genesys Cloud enforces strict origin validation to prevent token injection and cross-site request forgery. You must register your embedding domain in the Trusted Domains registry and align your application server CORS policies with Genesys expectations.
Navigate to Telephony > Trusted Domains and add your production and staging domains. Use exact hostnames. Do not use bare wildcards like *.example.com. Genesys validates the Origin header against the registered domain string. If you operate multiple environments, register each subdomain explicitly: portal.example.com, staging-portal.example.com, dev-portal.example.com.
Configure your application server to handle preflight requests from Genesys endpoints. The Embedded Client SDK makes cross-origin requests to:
https://api.mypurecloud.comhttps://media.mypurecloud.comhttps://login.mypurecloud.com
The Trap: Blocking Access-Control-Allow-Origin responses or over-restricting Access-Control-Allow-Headers. The Embedded Client SDK sends custom headers including X-Genesys-Embed-Client-Version and Genesys-User-Agent. If your reverse proxy strips these headers or returns 403 Forbidden on preflight, the SDK fails to fetch the initial bootstrap payload. The iframe will load, but the console will display FetchError: Network request failed. We align CORS policies to allow POST, GET, and OPTIONS methods with the required custom headers. Never set Access-Control-Allow-Origin to * in production. Specify the exact Genesys domains to maintain security posture.
Verify domain registration by executing a dry-run request from your application server:
OPTIONS /api/v2/oauth/token HTTP/1.1
Host: api.mypurecloud.com
Origin: https://portal.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Genesys-Embed-Client-Version, Genesys-User-Agent, Authorization
A successful configuration returns 200 OK with Access-Control-Allow-Origin: https://portal.example.com and Access-Control-Allow-Methods: POST, GET, OPTIONS.
3. Embedded Client Initialization and Token Exchange Flow
With authentication and domain trust established, you must implement the token exchange and SDK initialization sequence. The External application handles the IdP authentication, redirects the user back with an authorization code, exchanges it for a Genesys OAuth access token, and passes that token to the Embedded Client SDK.
Install the official SDK in your application:
npm install @genesyscloud/embedded-client
Implement the token exchange on your backend. The frontend must never handle the client secret. Use the Authorization Code flow with PKCE:
POST /api/v2/oauth/token HTTP/1.1
Host: api.mypurecloud.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code={AUTH_CODE}&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&redirect_uri=https://portal.example.com/callback&code_verifier={CODE_VERIFIER}
The response payload:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"scope": "client:read user:read embedded-client:configure telephony:read conversation:read organization:read"
}
Pass the access_token to the SDK initialization. Do not embed the token in the iframe src URL. The SDK uses a secure postMessage channel to inject credentials:
import { EmbeddedClient } from '@genesyscloud/embedded-client';
const client = new EmbeddedClient({
environment: 'mypurecloud.com',
clientId: '{CLIENT_ID}',
accessToken: '{ACCESS_TOKEN_FROM_BACKEND}',
refreshToken: '{REFRESH_TOKEN_FROM_BACKEND}',
embeddedClientSettings: {
showQueuePosition: true,
showCallControls: true,
allowTransfer: true,
allowPark: false,
allowConference: true
}
});
client.initialize()
.then(() => {
console.log('Embedded Client initialized successfully');
})
.catch((error) => {
console.error('Initialization failed:', error);
});
The Trap: Passing an expired or revoked access token during initialization. Genesys validates the token signature and expiration timestamp at initialization. If the token is stale, the SDK throws AuthenticationError: 401 Unauthorized. We implement a silent refresh mechanism using the refresh_token before initialization. Your backend must call the token endpoint with grant_type=refresh_token immediately before injecting the token into the SDK. This prevents race conditions where the token expires during the 2-3 second SDK bootstrap sequence.
4. Session Propagation and postMessage Handshake
The Embedded Client SDK communicates with the parent application via the browser postMessage API. Genesys uses a structured protocol to transmit media state changes, queue position updates, and interaction events. You must implement a message listener to handle session propagation and UI synchronization.
Register the listener after SDK initialization:
window.addEventListener('message', (event) => {
// Validate origin strictly
if (event.origin !== 'https://api.mypurecloud.com' &&
event.origin !== 'https://media.mypurecloud.com') {
return;
}
const payload = event.data;
if (payload.type === 'genesys-cloud-embed:session-start') {
console.log('Session started for user:', payload.userId);
// Update external UI to reflect active state
} else if (payload.type === 'genesys-cloud-embed:queue-position') {
console.log('Queue position:', payload.position, 'of', payload.total);
// Update waiting timer in external dashboard
} else if (payload.type === 'genesys-cloud-embed:interaction-end') {
console.log('Interaction ended:', payload.interactionId);
// Trigger post-call workflow or routing to CRM
}
});
The Trap: Implementing a blanket event.origin check or ignoring origin validation entirely. Modern browsers enforce same-origin policy, but malicious scripts can inject spoofed postMessage events if your listener does not verify event.origin. We validate against the exact Genesys domains registered in your environment. Failure to validate results in potential session hijacking or UI state corruption when third-party scripts inject fake interaction events.
Configure the SDK to emit events to your parent application by setting the allowedOrigins array during initialization:
const client = new EmbeddedClient({
// ... previous config
allowedOrigins: ['https://portal.example.com']
});
This whitelist ensures Genesys only sends state updates to your verified domain. The handshake completes when the SDK receives an ack from the parent application. Implement an acknowledgment sender:
window.addEventListener('message', (event) => {
if (event.data.type === 'genesys-cloud-embed:ready') {
event.source.postMessage({ type: 'ack', status: 'received' }, event.origin);
}
});
Validation, Edge Cases & Troubleshooting
Edge Case 1: Token Expiry Mid-Session
The failure condition: Users experience sudden disconnections or silent media drops after 60-120 minutes of continuous operation. The Embedded Client UI freezes, and subsequent API calls return 401 Unauthorized.
The root cause: Genesys Cloud OAuth access tokens have a fixed 120-minute lifetime. The Embedded Client SDK attempts automatic refresh using the stored refresh_token. If the identity provider session has expired, or if the refresh token was rotated by a concurrent session, the silent refresh fails. The SDK does not automatically prompt for re-authentication because the embedded context assumes the parent application manages identity lifecycle.
The solution: Implement explicit refresh token rotation and session monitoring in your parent application. Subscribe to the genesys-cloud-embed:token-expiring event and trigger a backend refresh sequence before the access token expires. Configure your IdP to issue long-lived refresh tokens with absolute expiration matching your security policy. If the refresh fails, gracefully degrade the embedded client by emitting a custom event to your UI, redirecting the user to a full login flow, and reinitializing the SDK with fresh credentials. Never allow the SDK to retry indefinitely. Implement an exponential backoff with a maximum of three attempts before failing open.
Edge Case 2: Cross-Origin Messaging Blocked by Browser Security Policies
The failure condition: The Embedded Client iframe loads, but no media controls render. Queue positions do not update. The browser console displays Blocked a frame with origin "https://api.mypurecloud.com" from accessing a cross-origin frame.
The root cause: Strict Content Security Policy (CSP) headers on your hosting domain block postMessage communication or restrict frame-src and connect-src directives. Modern browsers enforce CSP strictly. If your server returns frame-src 'self' without including Genesys domains, the iframe sandbox prevents the SDK from establishing the messaging channel. Similarly, connect-src restrictions block WebSocket connections to wss://media.mypurecloud.com.
The solution: Update your application server CSP headers to explicitly allow Genesys origins. The required directives:
Content-Security-Policy: frame-src 'self' https://*.mypurecloud.com https://*.pure.cloud; connect-src 'self' https://api.mypurecloud.com https://media.mypurecloud.com wss://media.mypurecloud.com; script-src 'self' https://*.mypurecloud.com; style-src 'self' https://*.mypurecloud.com;
Verify that your reverse proxy does not strip or override these headers. Test using browser developer tools CSP reporter. If you use a web application firewall, whitelist the Genesys domains to prevent false positive blocking of postMessage payloads. Cross-reference your WAF rules with the Embedded Client network requirements documented in the Developer Center.