Skip to main content

Overview

To authenticate with Okta using Client Credentials, you need the following:
  1. Client ID - A unique identifier for your Okta API Services application.
  2. Private Key (JWK) - The RSA private key in JSON Web Key format, whose public key is registered in your Okta application.
  3. Okta Domain - The subdomain of your Okta organization.
  4. Scopes - A space-separated list of Okta Management API scopes (e.g. okta.users.read okta.users.manage).
This guide will walk you through creating an API Services application in Okta with private_key_jwt authentication.

Prerequisites:

  • You must have an Okta account. Sign up for a free developer account at developer.okta.com.

Step 1: Creating your Okta API Services application

  1. Log in to your Okta Admin Console.
  2. In the left sidebar, navigate to Applications > Applications.
  3. Click Create App Integration.
  4. Select API Services as the sign-in method and click Next.
  5. Give your application a name and click Save.
  6. On the application’s General tab, find your Client ID — you will need it in the final step.
  7. Set Client authentication to Public key / Private key. okta.* scopes are only supported with this authentication method.
  8. Disable Proof of possession (DPoP) as it’s not supported by Nango.
The application must be created as API Services.

Step 2: Generating and registering your RSA key pair

Okta uses private_key_jwt for API Services apps. You generate an RSA key pair, register the public JWK with Okta, and provide the private JWK to Nango. Generate a private JWK using the following Node.js script (requires Node.js 18+):
const { generateKeyPairSync } = require('crypto');
const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });

const privateJwk = privateKey.export({ format: 'jwk' });
const publicJwk  = publicKey.export({ format: 'jwk' });

// Assign a kid — must match between private and public JWK
const kid = require('crypto').randomUUID();
privateJwk.kid = kid;
publicJwk.kid  = kid;

console.log('=== PUBLIC JWK (upload to Okta) ===');
console.log(JSON.stringify(publicJwk, null, 2));
console.log('\n=== PRIVATE JWK (paste into Nango) ===');
console.log(JSON.stringify(privateJwk));
Register the public JWK in Okta:
  1. In the Admin Console, open your API Services application.
  2. Go to the General tab and scroll to the PUBLIC KEYS section.
  3. Click Add Key, paste the public JWK JSON output from the script above, and click Save.
The private JWK is what you paste into Nango. It includes all key material (d, p, q, dp, dq, qi) and the kid. Keep it secret.

Step 3: Finding your Okta Domain

Your Okta Domain is the subdomain of your Okta organization URL.
  • In the Admin Console, your browser’s address bar will show a URL like https://dev-12345678-admin.okta.com.
  • Your Okta Domain is the part before .okta.com, ignoring -admin (e.g., dev-12345678).
  • Alternatively, go to Settings > Account in the Admin Console to find your Okta domain.

Step 4: Grant API scopes to your application

Okta requires at least one scope in every token request. Before your application can request specific scopes, they must be granted:
  1. In the Admin Console, navigate to Applications > Applications and open your application.
  2. Click the Okta API Scopes tab.
  3. Grant the scopes your integration requires (e.g. okta.users.read, okta.users.manage).
A full list of available scopes is in the Okta Management API reference.

Step 5: Enter credentials in the Connect UI

Once you have your Client ID, Private Key (JWK), Okta Domain, and Scopes:
  1. Open the form where you need to authenticate with Okta (Client Credentials).
  2. Enter your Client ID.
  3. Paste your Private Key (JWK) — the full JSON object from the script above (single-line or formatted).
  4. Enter your Okta Domain (e.g., dev-12345678).
  5. Enter the Scopes as a space-separated list (e.g., okta.users.read okta.users.manage).
  6. Submit the form, and you should be successfully authenticated.
You are now connected to Okta (Client Credentials).