Skip to content

Add Modular SCIM provisioning

Automate user provisioning with SCIM. Directory API and webhooks for real-time user data sync

This guide shows you how to automate user provisioning with SCIM using Scalekit’s Directory API and webhooks. You’ll learn to sync user data in real-time, create webhook endpoints for instant updates, and build automated provisioning workflows that keep your application’s user data synchronized with your customers’ directory providers.

See the SCIM provisioning in action Play

With SCIM Provisioning from Scalekit, you can:

  • Use webhooks to listen for events from your customers’ directory providers (e.g., user updates, group changes)
  • Use REST APIs to list users, groups, and directories on demand

Scalekit abstracts the complexities of various directory providers, giving you a single interface to automate user lifecycle management. This enables you to create accounts for new hires during onboarding, deactivate accounts when employees depart, and adjust access levels as employees change roles.

Review the SCIM provisioning sequence SCIM Provisioning SequenceDirectory ProviderScalekitYour App User/Group changes occur Webhook events sent (user_created, user_updated, etc.) Process webhook and verify signature Update local user database (create, update, deactivate) API calls for sync (list users, groups) Fetch latest data from directory provider

SCIM Quickstart

Get moving, instantly, with your go-to AI assistant

Input this prompt in your IDE to analyze your existing code base and generate SCIM implementation code accordingly.

*Compatible with Cursor, Windsurf, VS Code, and any AI-powered tools

Copy llm prompt

User provisioning with Scalekit’s directory API

Section titled “User provisioning with Scalekit’s directory API”

Scalekit’s directory API allows you to fetch information about users, groups, and directories associated with an organization on-demand. This approach is ideal for scheduled synchronization tasks, bulk data imports, or when you need to ensure your application’s user data matches the latest directory provider state.

Let’s explore how to use the Directory API to retrieve user and group data programmatically.

  1. Before you begin, ensure that your organization has a directory set up in Scalekit.

    Scalekit offers language-specific SDKs for fast SSO integration. Use the installation instructions below for your technology stack:

    npm install @scalekit-sdk/node

    Navigate to Dashboard > Developers > Settings > API Credentials to obtain your credentials. Store your credentials securely in environment variables:

    .env
    # Get these values from Dashboard > Developers > Settings > API Credentials
    SCALEKIT_ENVIRONMENT_URL='https://b2b-app-dev.scalekit.com'
    SCALEKIT_CLIENT_ID='<CLIENT_ID_FROM_SCALEKIT_DASHBOARD>'
    SCALEKIT_CLIENT_SECRET='<SECRET_FROM_SCALEKIT_DASHBOARD>'
  2. Initialize the SDK and make your first API call

    Section titled “Initialize the SDK and make your first API call”

    Initialize the Scalekit client with your environment variables and make your first API call to list organizations.

    Terminal
    # Security: Replace <ACCESS_TOKEN> with a valid access token from Scalekit
    # This token authorizes your API requests to access organization data
    # Use case: Verify API connectivity and test authentication
    # Examples: Initial setup testing, debugging integration issues
    curl -L "https://$SCALEKIT_ENVIRONMENT_URL/api/v1/organizations?page_size=5" \
    -H "Authorization: Bearer <ACCESS_TOKEN>"
  3. After successfully listing organizations, you’ll need to retrieve the specific directory to begin syncing user and group data. You can retrieve directories using either the organization and directory IDs, or fetch the primary directory for an organization.

    Node.js
    try {
    // Use case: Get specific directory when organization has multiple directories
    // Examples: Department-specific provisioning, multi-division companies
    const { directory } = await scalekit.directory.getDirectory('<organization_id>', '<directory_id>');
    console.log(`Directory name: ${directory.name}`);
    // Use case: Get primary directory for simple provisioning workflows
    // Examples: Small organizations, single-directory setups
    const { directory } = await scalekit.directory.getPrimaryDirectoryByOrganizationId('<organization_id>');
    console.log(`Primary directory ID: ${directory.id}`);
    } catch (error) {
    console.error('Failed to retrieve directory:', error);
    // Handle error appropriately for your application
    }
  4. Once you have the directory information, you can fetch users within that directory. This is commonly used for bulk user synchronization and maintaining an up-to-date user database.

    Node.js
    try {
    // Use case: Bulk user synchronization and provisioning
    // Examples: New customer onboarding, scheduled user data sync
    const { users } = await scalekit.directory.listDirectoryUsers('<organization_id>', '<directory_id>');
    // Process each user for provisioning or updates
    users.forEach(user => {
    console.log(`User email: ${user.email}, Name: ${user.name}`);
    // TODO: Implement your user provisioning logic here
    });
    } catch (error) {
    console.error('Failed to list directory users:', error);
    // Handle error appropriately for your application
    }
  5. Groups are essential for implementing role-based access control (RBAC) in your application. After retrieving users, you can fetch groups to manage permissions and access levels based on organizational structure.

    Node.js
    try {
    // Use case: Role-based access control implementation
    // Examples: Department-level permissions, project-based access
    const { groups } = await scalekit.directory.listDirectoryGroups(
    '<organization_id>',
    '<directory_id>',
    );
    // Process each group for RBAC setup
    groups.forEach(group => {
    console.log(`Group name: ${group.name}, ID: ${group.id}`);
    // TODO: Implement your group-based permission logic here
    });
    } catch (error) {
    console.error('Failed to list directory groups:', error);
    // Handle error appropriately for your application
    }

    Scalekit’s Directory API provides a simple way to fetch user and group information on-demand. Refer to our API reference to explore more capabilities.

While the Directory API is perfect for scheduled synchronization, webhooks enable immediate, real-time user provisioning. When directory providers send events to Scalekit, we forward them instantly to your application, allowing you to respond to user changes as they happen.

This approach is ideal for scenarios requiring immediate action, such as new employee onboarding or emergency access revocation.

  1. Create a webhook endpoint to receive real-time events from directory providers. After implementing your endpoint, register it in Dashboard > Webhooks where you’ll receive a secret for payload verification.

    Express.js
    app.post('/webhook', async (req, res) => {
    // Security: ALWAYS verify requests are from Scalekit before processing
    // This prevents unauthorized parties from triggering your provisioning logic
    const event = req.body;
    const headers = req.headers;
    const secret = process.env.SCALEKIT_WEBHOOK_SECRET;
    try {
    // Verify webhook signature to prevent replay attacks and forged requests
    await scalekit.verifyWebhookPayload(secret, headers, event);
    } catch (error) {
    console.error('Webhook signature verification failed:', error);
    // Return 400 for invalid signatures - this prevents processing malicious requests
    return res.status(400).json({ error: 'Invalid signature' });
    }
    try {
    // Use case: Real-time user provisioning based on directory events
    // Examples: New hire onboarding, emergency access revocation, role changes
    const { email, name } = event.data;
    // Process the webhook event based on its type
    switch (event.type) {
    case 'organization.directory.user_created':
    await createUserAccount(email, name);
    break;
    case 'organization.directory.user_updated':
    await updateUserAccount(email, name);
    break;
    case 'organization.directory.user_deleted':
    await deactivateUserAccount(email);
    break;
    default:
    console.log(`Unhandled event type: ${event.type}`);
    }
    res.status(201).json({ message: 'Webhook processed successfully' });
    } catch (processingError) {
    console.error('Failed to process webhook event:', processingError);
    res.status(500).json({ error: 'Processing failed' });
    }
    });
  2. After implementing your secure webhook endpoint, register it in the Scalekit dashboard to start receiving events:

    1. Navigate to Dashboard > Webhooks
    2. Click +Add Endpoint
    3. Enter your webhook endpoint URL (e.g., https://your-app.com/api/webhooks/scalekit)
    4. Add a meaningful description for your reference
    5. Select the event types you want to receive. Common choices include:
      • organization.directory.user_created - New user provisioning
      • organization.directory.user_updated - User profile changes
      • organization.directory.user_deleted - User deactivation
      • organization.directory.group_created - New group creation
      • organization.directory.group_updated - Group modifications

    Once registered, your webhook endpoint will start receiving event payloads from directory providers in real-time.

  3. Scalekit standardizes event payloads across different directory providers, ensuring consistent data structure regardless of whether your customers use Azure AD, Okta, Google Workspace, or other providers.

    When directory changes occur, Scalekit sends events with the following structure:

    Webhook event payload
    {
    "id": "evt_1234567890",
    "type": "organization.directory.user_created",
    "data": {
    "email": "john.doe@company.com",
    "name": "John Doe",
    "organization_id": "org_12345",
    "directory_id": "dir_67890"
    },
    "timestamp": "2024-01-15T10:30:00Z"
    }

    You have now successfully implemented and registered a webhook endpoint, enabling your application to receive real-time events for automated user provisioning. Your system can now respond instantly to directory changes, providing seamless user lifecycle management.

    Refer to our webhook events documentation for the complete list of available event types and payload structures.