Hi Matheus,
@Matheus Mendonca
I understand you're looking to understand how PKCE (Proof Key for Code Exchange) works in the context of Genesys Cloud. I'll try to explain it in simple terms.
PKCE is the recommended OAuth authentication method for browser-based and other public applications that integrate with Genesys Cloud. Instead of relying on a client secret, PKCE proves that the same application which started the login process is also the one exchanging the authorization code for an access token. This protects against authorization code interception and is the recommended approach for applications such as the Embeddable Framework.
There are two important terms to understand:
Code Verifier – A long, cryptographically random string generated by your application before the authentication process begins. This value is kept only by your application and is never sent in the initial authorization request.
Code Challenge – A hashed version of the code_verifier, calculated as:
BASE64URL-ENCODE(SHA256(code_verifier))
The code_challenge is sent to Genesys Cloud when the user is redirected to the authorization endpoint.
The authentication flow is straightforward:
-
Your application generates a random code_verifier.
-
It creates the corresponding code_challenge.
-
The user is redirected to the Genesys Cloud authorization endpoint along with the Client ID, Redirect URI, code_challenge, and other required OAuth parameters.
-
The user signs in to Genesys Cloud and grants access if required.
-
Genesys Cloud redirects the user back to the configured Redirect URI with an authorization code.
-
Your application sends this authorization code together with the original code_verifier to the Genesys Cloud token endpoint.
-
Genesys Cloud hashes the received code_verifier and compares it with the previously received code_challenge.
-
If they match, Genesys Cloud returns an access token. If they do not match, the token request is rejected.
To answer your specific questions:
Configuring the OAuth client
Create an OAuth client in Genesys Cloud and enable Authorization Code Grant (PKCE). Configure the Redirect URI that Genesys Cloud should redirect to after authentication. Your application only needs the Client ID; a Client Secret is not required for public clients using PKCE.
Handling the PKCE verifier/challenge flow
Generate a cryptographically random code_verifier, derive the code_challenge from it, and redirect the user to the Genesys Cloud authorization endpoint. After authentication, exchange the returned authorization code together with the original code_verifier for an access token.
Managing the callback
Once authentication is successful, Genesys Cloud redirects the user to the configured Redirect URI with the authorization code. Your application reads this code and exchanges it, along with the original code_verifier, for an access token. Your application should also handle any authentication errors returned in the callback.
Initializing the Embeddable Framework
Wait until authentication is complete and the access token has been received. Once the access token is available, initialize the Embeddable Framework so it can make authenticated API requests to Genesys Cloud on behalf of the signed-in user.
Handling the session and token lifecycle
Store the access token securely and monitor its expiration. For browser/public clients using PKCE, Genesys Cloud typically does not use refresh tokens. When the access token expires, simply start the PKCE authorization flow again to obtain a new access token. If the user still has an active Genesys Cloud session, the authorization usually completes without prompting the user to log in again. Finally, clear the access token when the user signs out, and never expose or log either the access token or the code_verifier.
I hope this helps clarify how PKCE works in Genesys Cloud. If you have any further queries please let me know.
Genesys PKCE implemention: https://developer.genesys.cloud/authorization/platform-auth/use-pkce
import os
import base64
import hashlib
import secrets
import urllib.parse
import requests
# -----------------------------
# Genesys Cloud Configuration
# -----------------------------
REGION = "us-east-1"
CLIENT_ID = "YOUR_CLIENT_ID"
REDIRECT_URI = "http://localhost:8080/callback"
AUTHORIZE_URL = f"https://login.{REGION}.pure.cloud/oauth/authorize"
TOKEN_URL = f"https://login.{REGION}.pure.cloud/oauth/token"
# -----------------------------
# Step 1: Generate Code Verifier
# -----------------------------
code_verifier = base64.urlsafe_b64encode(
secrets.token_bytes(32)
).decode().rstrip("=")
print("Code Verifier:")
print(code_verifier)
# -----------------------------
# Step 2: Generate Code Challenge
# -----------------------------
code_challenge = base64.urlsafe_b64encode(
hashlib.sha256(code_verifier.encode()).digest()
).decode().rstrip("=")
print("\nCode Challenge:")
print(code_challenge)
# -----------------------------
# Step 3: Build Authorization URL
# -----------------------------
params = {
"client_id": CLIENT_ID,
"response_type": "code",
"redirect_uri": REDIRECT_URI,
"code_challenge": code_challenge,
"code_challenge_method": "S256"
}
authorization_url = AUTHORIZE_URL + "?" + urllib.parse.urlencode(params)
print("\nOpen this URL in your browser:")
print(authorization_url)
# -----------------------------------------------------
# Step 4:
# User signs in and Genesys redirects to:
#
# http://localhost:8080/callback?code=AUTHORIZATION_CODE
#
# Copy the 'code' value below.
# -----------------------------------------------------
authorization_code = input("\nPaste the Authorization Code: ")
# -----------------------------
# Step 5: Exchange for Token
# -----------------------------
payload = {
"grant_type": "authorization_code",
"client_id": CLIENT_ID,
"code": authorization_code,
"redirect_uri": REDIRECT_URI,
"code_verifier": code_verifier
}
response = requests.post(TOKEN_URL, data=payload)
print("\nStatus:", response.status_code)
print(response.json())
------------------------------
Arjun Das T P
Engineer
Feebak Suite of products - Genesys Cloud
https://feebak.com/
arjun.das@fantacode.com
------------------------------