Bring your own key
Learn how to configure Bring Your Own Key (BYOK) authentication for your Zoom Marketplace applications. With BYOK, you can use your own cryptographic keys to enhance security and maintain greater control over your application's authentication process.
Overview
BYOK authentication gives developers control over their application's security by enabling them to manage their own encryption keys. This approach is especially valuable for applications with strict security compliance requirements or specific key management policies.
Prerequisites:
- A Zoom Developer account with permission to manage Marketplace app credentials.
- A secure key management process (HSM/KMS or equivalent recommended).
- A JWK/JWKS that follows RFC 7517 format requirements.
Generate your key pair
Generate a secure RSA or ECDSA key pair for signing your authentication tokens.
RSA key pair generation
- Generate RSA private key (2048-bit minimum recommended)
openssl genrsa -out private_key.pem 2048
- Extract public key from private key.
openssl rsa -in private_key.pem -pubout -out public_key.pem
ECDSA key pair generation
openssl ecparam -name prime256v1 -genkey -noout -out ec_private_key.pem
openssl ec -in ec_private_key.pem -pubout -out ec_public_key.pem
Prepare JWK/JWKS
When preparing JWK or JWKS, keep the following in mind:
- Provide public key material only.
- Do not include private key fields (for example d in RSA/EC JWKs).
- Use a valid kid so key rotation works reliably.
- If using JWKS URI, host a valid HTTPS endpoint returning parsable JWKS JSON.
Register your public key with Zoom
- Log into the Zoom App Marketplace as an admin or an account with developer rights.
- Select your application from the created app list or create a new General App.
- Go to the App Credentials, switch from Client Secret to Public Key.
- Choose one method:
- Paste JWK/JWKS directly.
- Provide a well-known jwks_uri URL.
- Save the configuration and note your Client ID.
Build the client_assertion JWT
For the signed JWT include:
iss / sub: set toclient_id.aud: must match the Zoom token endpoint audience; different endpoints require different audience values.exp,iat,jti: required for token lifetime and replay protection (jtishould be unique per assertion).
Exchange for access token
With your signed JWT token, make an authorization code grant request with client_assertion:
<your jwt bearer token> and client_assertion_type:urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
Authorization code grant with JWT bearer client assertion
The authorization code grant flow lets your app access Zoom resources on behalf of a user. With BYOK, use a JWT bearer token as the client assertion instead of a client secret. For details about the OAuth flow, see User authorization.
Redirect user for authorization
First, redirect the user to Zoom's authorization endpoint to obtain an authorization code:
GET https://zoom.us/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI
Exchange authorization code for access token
After the user authorizes your app, Zoom redirects to your redirect URI with an authorization code. Exchange the code for an access token by using your JWT bearer assertion.
Example Request
POST /oauth/token HTTP/1.1
Host: zoom.us
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=YOUR_REDIRECT_URI&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=YOUR_JWT_ASSERTION&client_id=CLIENT_ID
Request Parameters
| Parameter | Required | Description |
|---|---|---|
grant_type | Yes | Must be authorization_code |
code | Yes | The authorization code received from the OAuth callback |
redirect_uri | Yes | Must match the redirect URI used in the authorization request |
client_assertion_type | Yes | Must be urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
client_assertion | Yes | Your signed JWT bearer token |
client_id | Yes | Client ID in app credentials |
Token Response
A successful response returns the following JSON:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9...",
"expires_in": 3600,
"scope": "user:read:admin meeting:write:admin"
}
Response Fields
| Field | Description |
|---|---|
access_token | The access token to use for API requests |
token_type | Always bearer |
refresh_token | Token used to obtain a new access token when the current one expires |
expires_in | Number of seconds until the access token expires (typically 3600) |
scope | Space-separated list of scopes granted to the access token |
Make Authenticated API Requests
Use the access token in your API requests to authenticate with Zoom services.
Rotating between keys
You can rotate keys by providing a key set and adding new keys to it or removing old keys from it. Zoom validates the JWT against each key in the key set.