Nylas Connect works with any identity provider that issues JWTs (JSON Web Tokens) and exposes a JWKS (JSON Web Key Set) endpoint. This means you can use open-source solutions like Keycloak or Ory, cloud services like Firebase Auth or Supabase Auth, or even your own custom JWT server.
If your identity provider isn’t Auth0, Clerk, Google, or WorkOS, this is the guide for you.
How JWKS works with Nylas
Section titled “How JWKS works with Nylas”When you configure a custom identity provider, Nylas uses JWKS to verify the tokens your IDP issues:
- Your IDP signs JWTs with a private key.
- Your IDP exposes a JWKS endpoint (a public URL that serves the corresponding public keys).
- When Nylas receives a request with your IDP token, it fetches the public keys from your JWKS endpoint and verifies the token signature.
This means Nylas never needs your IDP’s private keys. It only needs the JWKS URL to verify that tokens are legitimate.
Before you begin
Section titled “Before you begin”You need an identity provider with JWKS support and a Nylas application configured to work together.
Configure Nylas Dashboard
Section titled “Configure Nylas Dashboard”Before connecting your identity provider, configure the IDP settings in the Nylas Dashboard:
-
Navigate to your application in the Nylas Dashboard.
-
Go to Hosted Authentication → Identity Providers.
-
Configure the following settings:
-
Allowed Origins: Add the domains where your application will be hosted (e.g.,
http://localhost:3000,https://yourapp.com). These origins will be allowed to make requests to Nylas with your IDP tokens. -
Callback URIs: Add the redirect URIs that Nylas will use after authentication (e.g.,
http://localhost:3000/auth/callback). These must match theredirectUriconfigured in your NylasConnect instance.
-
You can access the Identity Provider settings page directly at:
https://dashboard-v3.nylas.com/applications/<YOUR_APP_ID>/hosted-authentication/idp-settingsConfigure your JWKS endpoint in Nylas
Section titled “Configure your JWKS endpoint in Nylas”In addition to the standard Nylas Dashboard setup, you need to provide your JWKS endpoint URL:
- In the Nylas Dashboard, go to Hosted Authentication → Identity Providers.
- Enter your IDP’s JWKS URI (e.g.,
https://your-idp.com/.well-known/jwks.json). - Save the configuration.
JWKS endpoint requirements
Section titled “JWKS endpoint requirements”Your identity provider’s JWKS endpoint must:
- Be publicly accessible over HTTPS (Nylas needs to fetch keys at runtime)
- Serve a valid JWKS JSON document with RSA or EC public keys
- Include the
kid(key ID) header in issued JWTs that matches a key in the JWKS response - Issue JWTs with a
subclaim that uniquely identifies the user
Common JWKS endpoint paths by provider:
| Provider | JWKS endpoint |
|---|---|
| Keycloak | https://<host>/realms/<realm>/protocol/openid-connect/certs |
| Ory / Hydra | https://<host>/.well-known/jwks.json |
| Firebase Auth | https://www.googleapis.com/service_accounts/v1/jwk/[email protected] |
| Supabase Auth | https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json |
| Custom server | Typically https://your-domain.com/.well-known/jwks.json |
Implementation
Section titled “Implementation”The pattern is the same as any other IDP integration: pass your token to Nylas Connect through the identityProviderToken callback. The specifics of how you obtain the token depend on your IDP.
Here’s a generic example assuming your IDP provides a getToken() method:
import { NylasConnect } from "@nylas/connect";
async function getIdpToken(): Promise<string | null> { // Replace this with your IDP's token retrieval method. // Examples: // Keycloak: keycloak.token // Firebase: await firebase.auth().currentUser.getIdToken() // Supabase: (await supabase.auth.getSession()).data.session?.access_token // Custom: await fetch("/api/auth/token").then(r => r.json()).then(d => d.token) return null;}
const nylasConnect = new NylasConnect({ clientId: "<NYLAS_CLIENT_ID>", redirectUri: "http://localhost:3000/auth/callback", identityProviderToken: async () => { try { return await getIdpToken(); } catch (error) { console.error("Failed to get IDP token:", error); return null; } }});
async function connectEmail() { try { const result = await nylasConnect.connect({ method: "popup" }); console.log("Email connected:", result.grantInfo?.email); } catch (error) { console.error("Failed to connect email:", error); }}
async function logout() { await nylasConnect.logout(); // Also sign out from your IDP}Keycloak example
Section titled “Keycloak example”import Keycloak from "keycloak-js";import { NylasConnect } from "@nylas/connect";
const keycloak = new Keycloak({ url: "https://your-keycloak-server.com", realm: "<REALM_NAME>", clientId: "<KEYCLOAK_CLIENT_ID>"});
await keycloak.init({ onLoad: "login-required" });
const nylasConnect = new NylasConnect({ clientId: "<NYLAS_CLIENT_ID>", redirectUri: "http://localhost:3000/auth/callback", identityProviderToken: async () => { await keycloak.updateToken(30); return keycloak.token || null; }});Firebase Auth example
Section titled “Firebase Auth example”import { getAuth } from "firebase/auth";import { NylasConnect } from "@nylas/connect";
const auth = getAuth();
const nylasConnect = new NylasConnect({ clientId: "<NYLAS_CLIENT_ID>", redirectUri: "http://localhost:3000/auth/callback", identityProviderToken: async () => { const user = auth.currentUser; if (!user) return null; return await user.getIdToken(); }});Make API calls
Section titled “Make API calls”After the user authenticates with your IDP and connects their email, use the IDP token to make Nylas API requests. The pattern is the same as other providers: pass the token as a Bearer token and include the X-Nylas-External-User-Id header with the user’s sub claim:
function parseSubFromJwt(token: string): string | null { try { const base64Payload = token.split(".")[1]; const payload = JSON.parse(atob(base64Payload)); return payload?.sub || null; } catch { return null; }}
async function fetchEmails() { const token = await getIdpToken(); const userId = parseSubFromJwt(token || "");
const response = await fetch( `https://api.us.nylas.com/v3/grants/me/messages`, { headers: { Authorization: `Bearer ${token}`, "X-Nylas-External-User-Id": userId || "" } } );
return await response.json();}Use https://api.us.nylas.com for US-hosted applications or https://api.eu.nylas.com for EU-hosted applications.
Troubleshooting
Section titled “Troubleshooting”| Problem | Cause | Solution |
|---|---|---|
401 Unauthorized on API calls | Nylas can’t verify the token | Confirm your JWKS URI is correct and publicly accessible. Check that the kid in your JWT header matches a key in the JWKS response. |
| Token verification fails | Key mismatch | Ensure your IDP is using the same key pair for signing tokens as the one published at the JWKS endpoint. |
sub claim missing | Token format issue | Check that your IDP includes a sub claim in the JWT payload. Some IDPs use custom claim names. |
| JWKS endpoint unreachable | Network or CORS issue | The JWKS endpoint must be publicly accessible over HTTPS. It doesn’t need CORS headers because Nylas fetches it server-side. |
What’s next
Section titled “What’s next”- Session management for monitoring connection state
- Error handling for handling authentication failures
- Nylas Connect overview for standalone OAuth without an IDP
- Auth0, Clerk, Google, or WorkOS for provider-specific guides