{% callout type="info" %}
OAuth responses default to JWT format. Contact us to request a change to JWS or JWE (using your own keys)
{% /callout %}

This guide explains how to integrate with our OIDC UserInfo encryption and signatures, including how to create and provide a JSON Web Key (JWK) for encrypting responses to your application

### 1\. Decide your delivery format

*   JSON (default): Plain JSON payload. No keys required.

*   JWS (RS256): Signed JWT. No client key required. Contact us to enable.

*   JWS then JWE: Signed then encrypted JWT. Requires your RSA public JWK so we can encrypt to you.

Work with your account team to set `userinfo_delivery` to your desired value. For JWE, you must provide a JWK as described below.

{% callout type="info" %}
If choosing JSON or JWS, you may stop here. If you wish to use JWS with JWE, keep reading.
{% /callout %}

### 2\. Generate an RSA keypair

You can use OpenSSL locally. We recommend 2048-bit RSA for production.

\# Generate a private key (unencrypted PEM) openssl genrsa \-out rp-private.pem 2048 \# Extract the public key (PEM) openssl rsa \-in rp-private.pem \-pubout \-out rp-public.pem

Keep `rp-private.pem` secret. You will only share the PUBLIC components via a JWK.

### 3\. Create a JWK from your public key

A minimal RSA public JWK requires the base64url-encoded modulus `n` and exponent `e`.

*   Extract raw RSA parameters:

\# Print the public key details openssl rsa \-in rp-private.pem \-pubout | openssl pkey \-pubin \-text \-noout

Alternatively, you can use libraries to produce JWK directly (recommended in code). Below is the required structure we accept for encryption:

```json
{
  "kty": "RSA",
  "use": "enc",
  "alg": "RSA-OAEP-256",
  "kid": "<your-key-id>",
  "n": "<base64url-modulus>",
  "e": "<base64url-exponent>"
}
```

Notes:

*   kty: must be "RSA"

*   use: set to "enc" (used for encryption)

*   alg: set to "RSA-OAEP-256" (what we use for JWE key management)

*   kid: a stable identifier you choose; must be URL-safe. We use this to pick the correct key when you rotate keys.

*   n/e: base64url-encoded (no padding) big-endian unsigned integers. Ensure you strip any leading 0x00 byte before encoding.

#### Example JWK

```json
{
  "kty": "RSA",
  "use": "enc",
  "alg": "RSA-OAEP-256",
  "kid": "my-key-2025-08-01",
  "n": "s7w4V4...",
  "e": "AQAB"
}
```

### 4\. Provide your JWK to us

You have two options:

*   Host a JWKS endpoint we can fetch, containing your public keys:

```json
{
  "keys": [
    {
      "kty": "RSA",
      "use": "enc",
      "alg": "RSA-OAEP-256",
      "kid": "my-key-2025-08-01",
      "n": "...",
      "e": "AQAB"
    }
  ]
}
```

Provide the HTTPS URL to your account team.

*   Or send the single public JWK to us via a secure channel. We will provision it for your client.

### 5\. Request encrypted UserInfo

*   Ensure your client configuration has `userinfo_delivery` set to `jws_then_jwe`.

*   Call the UserInfo endpoint as normal with your access token.

*   We will:

*   Build a signed JWT (RS256)

*   Encrypt it to your JWK using RSA-OAEP-256 + A256GCM

*   Return a compact JWE string with content-type `application/jwe`

### 6\. Decrypting the response

Use a JOSE/JWT library that supports JWE (RSA-OAEP-256 / A256GCM). Configure it with your private key (`rp-private.pem`). After decryption, you’ll receive a nested JWS (RS256) which you can optionally verify against our public signing keys.

### 7\. Key rotation

*   Publish a new JWK with a new `kid`.

*   Notify us (or update your JWKS) before rotating out the old key.

*   We will select the most recent active key by `kid`.

### 8\. Common pitfalls

*   Missing or truncated JWK: ensure the JSON you provide is complete and not cut off. If sending through systems with field limits, use a TEXT/JSON-capable field.

*   Wrong encoding for `n`/`e`: must be base64url (no padding). Remove any leading 0x00 before encoding.

*   Algorithm mismatch: `alg` should be `RSA-OAEP-256` for encryption.

*   No `kid`: always include a stable, URL-safe `kid` for rotation.

### 9\. Validation checklist

*   JWK validates in your JOSE library (constructing a JWK/JWKS object should succeed)

*   JWKS endpoint is HTTPS and returns valid JSON with `keys: []`

*   You can decrypt a sample JWE using your private key

### 10\. Need help?

Contact your integration engineer with your JWKS URL or sample JWK. Include your desired `kid` and confirm your `userinfo_delivery` mode.
