Skip to main content

Overview

TextQL supports SCIM 2.0 (System for Cross-domain Identity Management) for automated user and group provisioning. When connected to your identity provider, SCIM keeps your TextQL organization in sync. Users and groups are automatically created, updated, and deactivated as changes happen in your IdP.

Supported Identity Providers

Any identity provider that supports the SCIM 2.0 protocol can be used, including:
  • Okta
  • Microsoft Entra ID (Azure AD)
  • OneLogin
  • Ping Identity

Prerequisites

Before configuring SCIM, ensure:
  1. You have admin access to your TextQL organization
  2. You have admin access to your identity provider

Setting Up SCIM

Step 1: Generate a SCIM Token

From the left sidebar, click Settings. In the Configuration tab, scroll to the SCIM Provisioning section and click Create Token. Give your token a description (e.g., “Okta SCIM”) so you can identify it later.
Copy your SCIM token immediately after creation. For security reasons, you won’t be able to see the full token again.

Step 2: Configure Your Identity Provider

In your identity provider, create a new SCIM application or add SCIM provisioning to your existing application. You’ll need:
  • SCIM Base URL: https://app.textql.com/scim/v2 (for VPC or custom deployments, use your own TextQL host)
  • Authentication: Bearer token (paste the token from Step 1)

Ping Identity — Required Attribute Mappings

For TextQL to sync first and last names from PingOne, add the following custom attributes to your TextQL application in PingOne under Custom Attributes: These are in addition to the required sub (User ID) mapping. Without them, users will be provisioned but their display names will not populate in TextQL.

Step 3: Enable Provisioning

In your identity provider, enable the provisioning features you want:

Step 4: Assign Users and Groups

In your identity provider, assign users and groups to the TextQL application. Your IdP will begin syncing them automatically.

How It Works

User Provisioning

When your IdP pushes a user to TextQL via SCIM:
  1. TextQL checks if the user’s email already exists
  2. If the user exists, a SCIM mapping is created linking the IdP’s external ID to the existing account
  3. If the user doesn’t exist, a new identity and organization membership are created
  4. The user can immediately log in
When a user is deactivated in your IdP:
  1. The IdP sends a SCIM deactivation request
  2. TextQL marks the user as inactive
  3. The user can no longer access the organization
  4. Their data and history are preserved (not deleted)

Group Provisioning

SCIM groups map to TextQL roles. When your IdP pushes a group:
  1. A new role is created in TextQL with the group’s display name
  2. Members of the group are assigned to that role
  3. Adding or removing members in your IdP automatically updates role assignments
  4. Deleting a group in your IdP removes the corresponding role
When updating group membership, TextQL accepts both object-form and path-based PATCH operations. Okta’s group push feature uses path-based syntax ("path": "members") for replace operations, which is fully supported.
If a group push operation contains a malformed members payload, TextQL returns a 400 Bad Request immediately rather than silently ignoring the bad data.

Managing SCIM Tokens

You can create multiple SCIM tokens if needed (e.g., one per IdP environment). To revoke a token, go to Settings → Security → SCIM Provisioning and click Revoke next to the token. Revoking a token immediately stops all provisioning from any IdP using that token. Existing users and groups are not affected; they remain in their current state.

Troubleshooting

Users not being provisioned

  • Verify the SCIM token is active (not revoked or expired)
  • Check that users are assigned to the TextQL application in your IdP
  • Ensure the SCIM Base URL is correct

Users provisioned without a role

  • Symptom: a user appears in TextQL after provisioning but has no role and cannot access anything.
  • Cause: if a user is provisioned without any group assignments, and no default role is configured, the user lands in the organization without permissions.
  • Resolution: assign the user to at least one group in your IdP before or during provisioning. If groups are being sent but the user still has no role, check whether group push is enabled separately in your IdP’s provisioning settings.

Groups not syncing

  • Confirm group push is enabled in your IdP’s provisioning settings
  • Verify the groups are assigned to the TextQL application
  • Check that group members also have individual user assignments
  • Group display name mismatch: TextQL maps SCIM groups to internal roles by displayName. Verify the group names in your IdP match the role names configured in TextQL — matching is case-sensitive.
  • members field omitted: a PUT /Groups/:id with the members field absent preserves existing membership. A PUT with "members": [] clears all members. Confirm your IdP is sending the members array explicitly.

”A role with this name is already linked to a SCIM group” (409 Conflict) on push

  • This error occurs when your IdP tries to push a group whose display name matches a TextQL role that is already managed by a different SCIM mapping.
  • To resolve: either rename the group in your IdP, or delete the existing SCIM mapping for that role before re-pushing.

Duplicate group conflict (409) on creation

  • Some IdPs (including Okta) don’t send an externalId for groups. When it’s absent, TextQL falls back to displayName uniqueness — if a group with the same display name already exists, creation is rejected.
  • Check Settings → Roles for an existing group with the same display name. Either delete it or rename the group in your IdP before pushing again.

User deactivation not working

  • Ensure your IdP is sending a SCIM PATCH with active: false (most IdPs do this by default)
  • Verify the SCIM token has not been revoked

Authentication failures (401)

  • Symptom: all SCIM requests return 401 Authentication failed.
  • Missing or malformed Authorization header — the header must be Bearer <token>. Pasting the raw token without the Bearer prefix will cause authentication to fail. This is a common misconfiguration in Okta’s SCIM setup screen: the API Token field requires the token prefixed with Bearer , e.g. Bearer <your-token>.
  • Expired token — SCIM tokens can be created with an expiry date. If expired, generate a new one in Settings → Security → SCIM Provisioning.
  • Revoked token — if the token was revoked, a new one must be generated.
  • Wrong token — tokens cannot be retrieved after creation. If unsure, revoke and regenerate.
  • OAuth client credentials — if using Basic auth, confirm the client_id and client_secret are correct and the client has not expired.

”Error authenticating: Unauthorized” during Okta’s credential test

  • Symptom: Okta’s “Test API Credentials” button fails with an authorization error, even though the token appears correct.
  • Cause: Okta’s credential test can fail if no users are assigned to the TextQL application yet. This is expected behavior — it does not indicate a real authentication problem.
  • Resolution: confirm the token is entered as Bearer <your-token> in Okta’s API Token field, then assign at least one user to the TextQL application in Okta and retry the credential test.

Changes not appearing immediately

  • Most IdPs sync on a schedule (typically every 30-60 minutes)
  • Use your IdP’s “Push Now” or “Force Sync” option to trigger an immediate sync

Rate limiting (429)

  • SCIM endpoints enforce per-organization rate limiting (default 500 requests/minute). The response includes a Retry-After header indicating how many seconds to wait before retrying.
  • Most IdPs respect Retry-After automatically. If you’re running a large initial provisioning run and hitting limits, configure your IdP’s SCIM sync interval to be less aggressive, or batch requests with delays between them.
  • Self-hosted/VPC deployments can raise this limit — reach out to your TextQL FDE for the Kubernetes Troubleshooting guide, which covers the operational commands to check and adjust it.

Stale permissions after deactivation and reactivation

  • When a user is deactivated, their SCIM-sourced role assignments should be cleaned up. If stale records persist, reactivation can result in duplicate or incorrect permissions.
  • Deactivate the user again, wait for the deactivation to sync, then reactivate — this triggers a clean provisioning cycle. If the problem persists, contact TextQL support for manual cleanup.

Firewall blocking group requests (403)

  • Symptom: user provisioning works, but all requests to /scim/v2/Groups return 403 Forbidden, while user sync succeeds.
  • How to tell it’s a network-layer block, not a SCIM auth failure: a genuine SCIM auth failure returns a JSON error body ({"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "401", "detail": "Authentication failed"}). A network-layer block returns a plain HTML 403 with no JSON body.
  • Resolution: review any WAF or firewall rules in front of your deployment. A rule matching path patterns containing /Groups may be blocking group traffic while leaving /Users unaffected — add an allow rule for /scim/v2/Groups* with higher priority, or scope the blocking rule more narrowly.

Content-Type errors

  • TextQL’s SCIM implementation accepts application/scim+json and rewrites it to application/json internally before parsing. If a proxy or WAF between your IdP and TextQL is stripping or rejecting this content type, configure it to pass application/scim+json through unchanged.

Filter queries not working

  • TextQL supports a subset of the SCIM filter spec: attribute eq "value" (equality only).
  • Supported attributes for Users: userName, emails.value, externalId, active. For Groups: displayName, externalId.
  • Compound filters (and, or, not) and operators other than eq return a 400 invalidFilter error.

VPC deployments: SCIM requests intercepted by auth middleware

  • Symptom: SCIM fails entirely for a VPC deployment — all requests return authentication errors even with a valid token.
  • Cause: in VPC deployments, SCIM routes must be excluded from the Oathkeeper frontend catch-all authentication rule. On an older configuration, Oathkeeper may intercept SCIM bearer token requests and apply browser-based OIDC authentication instead, causing all SCIM calls to fail.
  • Resolution: contact TextQL support and provide your Oathkeeper configmap output — we’ll verify whether the SCIM path exclusion is present and provide an updated chart configuration if needed. Reach out to your TextQL FDE for the Kubernetes Troubleshooting guide, which covers how to pull that configmap.
Running SCIM on a self-hosted/VPC deployment? Reach out to your TextQL FDE for the Kubernetes: Logs & Troubleshooting guide, which covers the SCIM endpoints reference, kubectl/Oathkeeper operational commands, and the Helm values that control SCIM/OIDC behavior.

Security Considerations

  • SCIM tokens are stored as hashed values. TextQL cannot retrieve the original token after creation.
  • All SCIM endpoints require a valid bearer token.
  • SCIM operations are scoped to the organization that owns the token.
  • Only organization administrators can create or revoke SCIM tokens.
  • User deactivation via SCIM is a soft delete. Accounts can be reactivated if the user is re-assigned in your IdP.