Skip to main content

Version: 3.9.x

Configure SCIM Provisioning for Developer Portal with Okta

This guide explains how to enable SCIM (System for Cross-domain Identity Management) provisioning for your Custom Developer Portal. By integrating Okta, you can automatically synchronize user accounts to your portal, ensuring consistent access control.

Since the Developer Portal is based on the API7 Developer Portal Boilerplate, this configuration involves modifying the source code to enable the SCIM plugin in the authentication system (Better Auth).

Prerequisites

  1. Custom Developer Portal deployed and configured based on the apps/site structure of the boilerplate. See Set Up Developer Portal with Provider Portal and Customize Developer Portal.
  2. An Okta account with administrative privileges.

Create a SCIM Application in Okta

Before modifying your portal code, set up a SCIM application in Okta.

  1. Log in to the Okta Admin Console.

  2. Navigate to Applications > Applications.

  3. Click Browse App Catalog.

  4. Search for SCIM and select SCIM 2.0 Test App (Header Auth).

    Search for SCIM integration in Okta

  5. Click Add Integration.

  6. In the General Settings tab, name the application (e.g., "API7 Portal").

    Configure general settings

  7. In the Sign-On Options tab, select Secure Web Authentication (SWA).

    • Alternatively, select SAML/OIDC if you have configured SSO separately.

    Select sign-on options

  8. Click Done to finish creating the application.

Enable SCIM in Developer Portal

Update your portal's code to install and configure the SCIM plugin.

Install SCIM Plugin

In your project root (or apps/site directory), install the SCIM plugin. Ensure the version matches your better-auth version.

pnpm add @better-auth/scim@1.4.10

Add Plugin to Server and Client

Modify the server and client files to register the SCIM plugin:

apps/site/src/lib/auth/server.ts
import {
// ... existing imports
organization,
openAPI,
} from 'better-auth/plugins';
import { scim } from '@better-auth/scim';

export const auth = betterAuth({
// ... existing config
plugins: [
nextCookies(),
organization(),
openAPI(),
scim(),
...getTestingConfig(),
],
});
apps/site/src/lib/auth/client.ts
import {
// ... existing imports
genericOAuthClient,
} from 'better-auth/client/plugins';
import { scimClient } from '@better-auth/scim/client';

export const authClient = createAuthClient({
basePath: AUTH_BASE_PATH,
plugins: [
organizationClient(),
magicLinkClient(),
genericOAuthClient(),
scimClient(),
],
});

Update Route Handler HTTP Methods

SCIM requires specific HTTP methods (PUT, PATCH, DELETE) for user management. Update your route handler for these methods:

apps/site/app/api/auth/[...all]/route.ts
// export const { GET, POST } = toNextJsHandler(auth.handler);
export const { GET, POST, PUT, PATCH, DELETE } = toNextJsHandler(auth.handler);

Update Database Schema

The SCIM plugin requires additional database tables. Generate the schema and apply migrations:

cd apps/site
pnpm db:generate-schema
pnpm db:generate
pnpm db:migrate

You should see an output similar to the following:

> @api7ee/site@0.5.6 db:migrate /path/to/your/project/apps/site
> drizzle-kit migrate

No config path provided, using default 'drizzle.config.ts'
Reading config file '/path/to/your/project/apps/site/drizzle.config.ts'
Using 'pg' driver for database querying
[] migrations applied successfully!

Generate SCIM Token

Create a temporary script to generate the SCIM token for Okta integration.

  1. Create the following script:

    apps/site/scripts/get-scim-token.ts
    import { auth } from '@/lib/auth/server';

    async function main() {
    // 1. Sign in as an admin to get a session
    const loginRes = await auth.api.signInEmail({
    returnHeaders: true,
    body: {
    email: 'admin@example.com', // Replace with your admin email
    password: 'password1234', // Replace with your admin password
    },
    });

    const headers = {
    cookie: loginRes.headers.get('set-cookie') || '',
    };

    // 2. Generate the SCIM Token for Okta
    const res = await auth.api.generateSCIMToken({
    body: {
    providerId: 'okta',
    },
    headers,
    });
    console.log('SCIM Token:', res.scimToken);
    }
    main().catch((err) => console.trace(err));
  2. Run the script:

    pnpm dlx tsx ./scripts/get-scim-token.ts
  3. Copy the generated token, which is in the format of Y0xRcHlHZTVVZGM5aTl3U19SSGtWSFczOm9rdGE=.

Configure Okta API Integration

Connect Okta to your Developer Portal.

  1. In Okta, navigate to the Provisioning tab of your SCIM application.

  2. Click Configure API Integration > Enable API Integration.

  3. Configure the following defaults:

    • SCIM 2.0 Base URL: Enter your portal's auth URL appended with /scim/v2, for example https://<YOUR_PORTAL_DOMAIN>/api/auth/scim/v2.
    • API Token: Enter Bearer <YOUR_SCIM_TOKEN>. Ensure there is a space between Bearer and the token.
  4. Click Test API Credentials to verify the connection. If successful, click Save.

Configure API integration

Configure Provisioning and Assign Users

Before you assign users to the application, you should first enable and configure how Okta will provision user accounts and lifecycle changes to your SCIM‑enabled app. This ensures that Okta can create, update, and deactivate accounts correctly once assignments are made.

Configure Provisioning

  1. In Okta, navigate to the Provisioning tab of your SCIM application.
  2. Select To App settings and click Edit to configure provisioning.
  3. Enable the following options so Okta can manage user lifecycle events in your app:
    • Create Users: provision new users created in Okta to the app
    • Update User Attributes: synchronize profile updates from Okta to the app
    • Deactivate Users: deactivate users in the app when they are unassigned or deactivated in Okta
  4. Click Save.

Enable create users

Assign Users

  1. In Okta, navigate to the Assignments tab of your SCIM application.
  2. Click Assign > Assign to People (or Assign to Groups).
  3. Select users or groups and click Assign, then Done.

Assign to users

Verify

To confirm user synchronization, check your Developer Portal’s user list or database to verify that the users you assigned in Okta have been provisioned correctly:

Verify users in database

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation