Validating Genesys Cloud Implicit Grant JWTs in React without a backend

We’ve been pushing hard to get our internal dashboard running on the Genesys Cloud implicit grant flow, but I’m hitting a wall when trying to validate the returned JWTs on the client side. The setup is pretty standard React with create-react-app, and we’re using the @genesys/cloud-auth library to handle the initial redirect and token exchange. The auth part works fine; I get the id_token and access_token in the URL hash after the user logs in.

The problem is that the React app needs to verify the token’s integrity before making any API calls to verify the user token. I can’t send the token to a backend for validation because this is a purely static site hosted on S3. I tried using the jwt-decode library, but it’s just parsing the JSON without checking the signature, which feels insecure.

I found the public keys at https://login.mypurecloud.com/keys, but the response is a JWK set, not a simple PEM string. I’ve been trying to convert the JWK to a usable format using jose or node-jose, but I keep running into issues with the alg header matching. The token has alg: RS256, and the JWK has kty: RSA.

Here’s the snippet I’m wrestling with:

import { importJWK, verify } from 'jose';

async function validateToken(token) {
 const [header, payload, signature] = token.split('.');
 const jwks = await fetch('https://login.mypurecloud.com/keys');
 const keys = await jwks.json();
 
 // This part is messy
 const key = keys.keys.find(k => k.kid === header.kid);
 const publicKey = await importJWK(key, 'RS256');
 
 // This throws "invalid signature"
 const { protectedHeader, payload: decodedPayload } = await verify(token, publicKey);
 return decodedPayload;
}

The verify call consistently fails with an “invalid signature” error, even though the token was just issued. I suspect I’m importing the JWK incorrectly or missing a step in the key conversion. Has anyone successfully validated Genesys JWTs in a browser-only environment? The docs are surprisingly silent on this specific client-side validation pattern.