Skip to content

SCIM 2.0

Authrim supports SCIM 2.0 (System for Cross-domain Identity Management) for automated user and group provisioning.

  • Standards: RFC 7643 (Core Schema), RFC 7644 (Protocol)
  • Status: Fully Implemented
  • Base URL: /scim/v2
  • User CRUD operations (Create, Read, Update, Delete)
  • Group CRUD operations
  • Discovery endpoints: /ServiceProviderConfig, /ResourceTypes, /Schemas
  • Bulk operations with /Bulk
  • Filtering with SCIM query syntax
  • Pagination with startIndex and count
  • Resource versioning with ETags
  • Partial updates with PATCH operations
  • Enterprise User extension
  • Bearer token authentication

SCIM provisioning requests require a Bearer token:

Authorization: Bearer YOUR_SCIM_TOKEN

Discovery endpoints under /scim/v2/ServiceProviderConfig, /scim/v2/ResourceTypes, and /scim/v2/Schemas are available without a bearer token so SCIM clients can discover server capabilities.

  1. Navigate to Admin UI > SCIM Tokens or call POST /api/admin/scim-tokens
  2. Enter a description (e.g., “Okta SCIM Integration”)
  3. Set expiresInDays (default: 365, maximum: 3650)
  4. Copy the token immediately (it will not be shown again)

Admin API endpoints:

MethodEndpointDescription
GET/api/admin/scim-tokensList SCIM token metadata
POST/api/admin/scim-tokensCreate a SCIM token
DELETE/api/admin/scim-tokens/{tokenHash}Revoke a SCIM token
GET /scim/v2/Users

Query Parameters:

ParameterTypeDescriptionExample
filterstringSCIM filter expressionuserName eq "john@example.com"
sortBystringAttribute to sort byuserName
sortOrderstringascending or descendingascending
startIndexinteger1-based pagination index1
countintegerNumber of results (max 1000)100

Response:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 250,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "user-123",
"userName": "john@example.com",
"name": {
"givenName": "John",
"familyName": "Doe"
},
"emails": [{"value": "john@example.com", "primary": true}],
"active": true,
"meta": {
"resourceType": "User",
"created": "2024-01-01T00:00:00Z",
"lastModified": "2024-01-02T00:00:00Z",
"location": "https://auth.example.com/scim/v2/Users/user-123",
"version": "W/\"1704153600000\""
}
}
]
}
GET /scim/v2/Users/{id}
POST /scim/v2/Users
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "john@example.com",
"name": {
"givenName": "John",
"familyName": "Doe"
},
"emails": [{"value": "john@example.com", "primary": true}],
"active": true
}
PATCH /scim/v2/Users/{id}
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "replace", "path": "name.givenName", "value": "Jane"},
{"op": "replace", "path": "active", "value": false}
]
}

Supported Operations:

  • add - Add new attribute
  • replace - Replace existing attribute
  • remove - Remove attribute
PUT /scim/v2/Users/{id}
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "john@example.com",
...
}
DELETE /scim/v2/Users/{id}
GET /scim/v2/Groups
POST /scim/v2/Groups
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Engineering",
"members": [
{"value": "user-123", "type": "User"}
]
}
GET /scim/v2/ServiceProviderConfig
GET /scim/v2/ResourceTypes
GET /scim/v2/Schemas
GET /scim/v2/Schemas/{schemaId}

ServiceProviderConfig advertises support for PATCH, Bulk, filtering, sorting, ETags, and OAuth Bearer token authentication.

POST /scim/v2/Bulk
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"bulkId": "user1",
"path": "/Users",
"data": {
"userName": "jane@example.com",
"active": true
}
}
]
}

Bulk limits default to 100 operations and 1 MB payloads. They can be configured with SCIM_BULK_MAX_OPERATIONS and SCIM_BULK_MAX_PAYLOAD_SIZE in KV.

SCIM supports complex filtering using standardized query syntax.

OperatorDescriptionExample
eqEqualuserName eq "john@example.com"
neNot equalactive ne false
coContainsuserName co "john"
swStarts withuserName sw "john"
ewEnds withuserName ew "example.com"
prPresentphoneNumber pr
gtGreater thanmeta.created gt "2024-01-01"
ltLess thanmeta.created lt "2024-12-31"
OperatorDescriptionExample
andLogical ANDuserName eq "john" and active eq true
orLogical ORuserName eq "john" or userName eq "jane"
notLogical NOTnot (active eq false)
Terminal window
# Find user by email
GET /scim/v2/Users?filter=userName eq "john@example.com"
# Find active users
GET /scim/v2/Users?filter=active eq true
# Complex filter
GET /scim/v2/Users?filter=(userName co "john" or userName co "jane") and active eq true

SCIM uses 1-based pagination with startIndex and count parameters.

Terminal window
# First page (items 1-100)
GET /scim/v2/Users?startIndex=1&count=100
# Second page (items 101-200)
GET /scim/v2/Users?startIndex=101&count=100

SCIM supports ETags for optimistic concurrency control:

# Get user with ETag
GET /scim/v2/Users/user-123
Response: ETag: W/"1704153600000"
# Update with ETag
PUT /scim/v2/Users/user-123
If-Match: W/"1704153600000"
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "400",
"scimType": "invalidValue",
"detail": "userName is required"
}
scimTypeHTTP StatusDescription
invalidFilter400Invalid filter syntax
invalidValue400Invalid attribute value
uniqueness409Resource already exists
mutability400Attempt to modify read-only attribute
noTarget404Resource not found
invalidVers412ETag mismatch
  1. Generate SCIM token in Authrim Admin UI
  2. Configure Okta app:
    • SCIM Base URL: https://YOUR_DOMAIN/scim/v2
    • Authentication: HTTP Header
    • Authorization: Bearer YOUR_TOKEN
  3. Enable provisioning:
    • Create Users
    • Update User Attributes
    • Deactivate Users
  1. Add Enterprise Application (Non-gallery)
  2. Configure Provisioning:
    • Provisioning Mode: Automatic
    • Tenant URL: https://YOUR_DOMAIN/scim/v2
    • Secret Token: YOUR_TOKEN
  3. Test Connection and configure attribute mappings
  1. Applications > Add App > SCIM Provisioner
  2. Configuration:
    • SCIM Base URL: https://YOUR_DOMAIN/scim/v2
    • SCIM Bearer Token: YOUR_TOKEN
    • API Connection: SCIM 2.0
SCIM AttributeAuthrim canonical storageType
ididentity_accounts.legacy_user_id projectionstring (read-only)
externalIdidentity_accounts.external_idstring
userNamepreferred_username sensitive attribute, falling back to primary emailstring (required)
name.givenNameprofile_attribute_values + identity_sensitive_valuesstring
name.familyNameprofile_attribute_values + identity_sensitive_valuesstring
emails[primary].valuecontact_points + identity_sensitive_valuesstring (required)
phoneNumbers[primary].valuecontact_points + identity_sensitive_valuesstring
activeidentity_accounts.lifecycle_state projectionboolean
localesensitive profile attributestring
timezonezoneinfo sensitive profile attributestring

SCIM reads and writes through the canonical runtime identity projection. PII values are stored in the PII database when it is configured, while lookup hashes and lifecycle state remain in the core database.

  • Rotate tokens regularly (e.g., every 90 days)
  • Use separate tokens for each integration
  • Monitor token usage in audit logs
  • Use HTTPS for all SCIM requests
  • Use filtering to reduce response sizes
  • Implement pagination for large datasets
  • Use ETags to avoid unnecessary updates
  • Implement retry logic with exponential backoff
  • Handle 429 (rate limit) responses
  • Log all errors for troubleshooting
  • Standard SCIM operations use the configured moderate rate-limit profile
  • /scim/v2/Bulk uses the configured strict rate-limit profile
  • 429 Too Many Requests responses include Retry-After when available