Skip to main content

Overview

The scim client implements the SCIM 2.0 protocol for automated user provisioning. It supports both SCIM token management (for authenticating your identity provider) and full SCIM 2.0 user lifecycle operations. Access the SCIM client via client.scim.

Token Management

SCIM tokens authenticate your identity provider (IdP) when it provisions users. Tokens are bearer tokens — the raw secret is only returned once at creation time.

Create Token

from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    scim_token = client.scim.create_token("Okta Production")

    print(f"Token ID: {scim_token.id}")
    print(f"Label: {scim_token.label}")
    print(f"Token: {scim_token.token}")  # Store securely -- shown only once
    print(f"Created at: {scim_token.created_at}")

ScimTokenWithSecret

FieldTypeDescription
idstrUnique token identifier.
labelstrHuman-readable label.
tokenstrThe bearer token secret (only returned at creation).
created_atstrISO 8601 creation timestamp.
last_used_atstr | NoneISO 8601 timestamp of last use (or None).

List Tokens

result = client.scim.list_tokens()

for token in result.tokens:
    print(f"  {token.id}: {token.label} (created {token.created_at})")

ListScimTokensResponse

FieldTypeDescription
tokenstuple[ScimToken, ...]The list of SCIM tokens (without secrets).

ScimToken

FieldTypeDescription
idstrUnique token identifier.
labelstrHuman-readable label.
created_atstrISO 8601 creation timestamp.
last_used_atstr | NoneISO 8601 timestamp of last use.

Revoke Token

client.scim.revoke_token("scim_tok_abc123")
# Returns None on success

User Operations

SCIM 2.0 user operations support the full user lifecycle: create, read, update (full and partial), list, and delete.

List Users

from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    result = client.scim.list_users(start_index=1, count=25)

    print(f"Total results: {result.total_results}")
    print(f"Start index: {result.start_index}")
    print(f"Items per page: {result.items_per_page}")
    for user in result.resources:
        print(f"  {user.user_name} (active: {user.active})")

Parameters

ParameterTypeRequiredDescription
start_indexint | NoneNo1-based index of the first result.
countint | NoneNoMaximum number of results to return.
Both parameters are keyword-only.

ScimListResponse

FieldTypeDescription
total_resultsintTotal number of matching users.
start_indexint1-based index of the first result.
items_per_pageintNumber of results per page.
resourcestuple[ScimUser, ...]The list of users.

Create User

from grantex import Grantex, CreateScimUserParams

with Grantex(api_key="gx_live_...") as client:
    user = client.scim.create_user(CreateScimUserParams(
        user_name="alice@example.com",
        display_name="Alice Smith",
        external_id="ext_12345",
        emails=[{"value": "alice@example.com", "primary": True}],
        active=True,
    ))

    print(f"User ID: {user.id}")
    print(f"Username: {user.user_name}")
    print(f"Active: {user.active}")

CreateScimUserParams

FieldTypeRequiredDefaultDescription
user_namestrYesThe user’s username (typically email).
display_namestr | NoneNoNoneDisplay name.
external_idstr | NoneNoNoneExternal ID from the IdP.
emailslist[dict[str, Any]] | NoneNoNoneList of email objects.
activeboolNoTrueWhether the user is active.

Get User

user = client.scim.get_user("scim_user_abc123")

print(f"Username: {user.user_name}")
print(f"Display name: {user.display_name}")
print(f"Active: {user.active}")
print(f"Emails: {[(e.value, e.primary) for e in user.emails]}")
print(f"Created: {user.meta.created}")

Replace User (PUT)

Full replacement of a user’s attributes:
from grantex import Grantex, CreateScimUserParams

with Grantex(api_key="gx_live_...") as client:
    updated = client.scim.replace_user(
        "scim_user_abc123",
        CreateScimUserParams(
            user_name="alice@example.com",
            display_name="Alice Johnson",
            active=True,
        ),
    )

    print(f"Updated: {updated.display_name}")

Update User (PATCH)

Partial update using SCIM Operations:
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    updated = client.scim.update_user(
        "scim_user_abc123",
        operations=[
            {"op": "replace", "path": "displayName", "value": "Alice Johnson"},
            {"op": "replace", "path": "active", "value": False},
        ],
    )

    print(f"Display name: {updated.display_name}")
    print(f"Active: {updated.active}")

Delete User

Deprovision a user:
client.scim.delete_user("scim_user_abc123")
# Returns None on success

ScimUser Type

The ScimUser frozen dataclass has the following fields:
FieldTypeDescription
idstrUnique user identifier.
user_namestrThe user’s username.
activeboolWhether the user is active.
emailstuple[ScimEmail, ...]The user’s email addresses.
metaScimUserMetaSCIM metadata (timestamps, type).
external_idstr | NoneExternal ID from the IdP.
display_namestr | NoneDisplay name.

ScimEmail

FieldTypeDescription
valuestrThe email address.
primaryboolWhether this is the primary email.

ScimUserMeta

FieldTypeDescription
resource_typestrThe SCIM resource type.
createdstrISO 8601 creation timestamp.
last_modifiedstrISO 8601 last-modified timestamp.