SCIM 2.0
Authrim supports SCIM 2.0 (System for Cross-domain Identity Management) for automated user and group provisioning.
Overview
Supported Features
- User CRUD operations (Create, Read, Update, Delete)
- Group CRUD operations
- Filtering with SCIM query syntax
- Pagination with
startIndexandcount - Resource versioning with ETags
- Partial updates with PATCH operations
- Enterprise User extension
- Bearer token authentication
Authentication
All SCIM requests require a Bearer token:
Authorization: Bearer YOUR_SCIM_TOKENCreating a SCIM Token
- Navigate to Admin UI > SCIM Tokens
- Click Create Token
- Enter a description (e.g., “Okta SCIM Integration”)
- Set expiration (e.g., 365 days)
- Copy the token immediately (it won’t be shown again)
API Reference
Users
List Users
GET /scim/v2/UsersQuery Parameters:
| Parameter | Type | Description | Example |
|---|---|---|---|
filter | string | SCIM filter expression | userName eq "[email protected]" |
sortBy | string | Attribute to sort by | userName |
sortOrder | string | ascending or descending | ascending |
startIndex | integer | 1-based pagination index | 1 |
count | integer | Number 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", "name": { "givenName": "John", "familyName": "Doe" }, "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 User by ID
GET /scim/v2/Users/{id}Create User
POST /scim/v2/UsersContent-Type: application/json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "name": { "givenName": "John", "familyName": "Doe" }, "active": true}Update User (PATCH)
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 attributereplace- Replace existing attributeremove- Remove attribute
Replace User (PUT)
PUT /scim/v2/Users/{id}Content-Type: application/json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], ...}Delete User
DELETE /scim/v2/Users/{id}Groups
List Groups
GET /scim/v2/GroupsCreate Group
POST /scim/v2/GroupsContent-Type: application/json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"], "displayName": "Engineering", "members": [ {"value": "user-123", "type": "User"} ]}Filtering
SCIM supports complex filtering using standardized query syntax.
Filter Operators
| Operator | Description | Example |
|---|---|---|
eq | Equal | userName eq "[email protected]" |
ne | Not equal | active ne false |
co | Contains | userName co "john" |
sw | Starts with | userName sw "john" |
ew | Ends with | userName ew "example.com" |
pr | Present | phoneNumber pr |
gt | Greater than | meta.created gt "2024-01-01" |
lt | Less than | meta.created lt "2024-12-31" |
Logical Operators
| Operator | Description | Example |
|---|---|---|
and | Logical AND | userName eq "john" and active eq true |
or | Logical OR | userName eq "john" or userName eq "jane" |
not | Logical NOT | not (active eq false) |
Examples
# Find user by email
# Find active usersGET /scim/v2/Users?filter=active eq true
# Complex filterGET /scim/v2/Users?filter=(userName co "john" or userName co "jane") and active eq truePagination
SCIM uses 1-based pagination with startIndex and count parameters.
# 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=100Resource Versioning (ETags)
SCIM supports ETags for optimistic concurrency control:
# Get user with ETagGET /scim/v2/Users/user-123Response: ETag: W/"1704153600000"
# Update with ETagPUT /scim/v2/Users/user-123If-Match: W/"1704153600000"Error Responses
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "400", "scimType": "invalidValue", "detail": "userName is required"}| scimType | HTTP Status | Description |
|---|---|---|
invalidFilter | 400 | Invalid filter syntax |
invalidValue | 400 | Invalid attribute value |
uniqueness | 409 | Resource already exists |
mutability | 400 | Attempt to modify read-only attribute |
noTarget | 404 | Resource not found |
invalidVers | 412 | ETag mismatch |
Integration Guides
Okta
- Generate SCIM token in Authrim Admin UI
- Configure Okta app:
- SCIM Base URL:
https://YOUR_DOMAIN/scim/v2 - Authentication: HTTP Header
- Authorization: Bearer
YOUR_TOKEN
- SCIM Base URL:
- Enable provisioning:
- Create Users
- Update User Attributes
- Deactivate Users
Azure AD (Entra ID)
- Add Enterprise Application (Non-gallery)
- Configure Provisioning:
- Provisioning Mode: Automatic
- Tenant URL:
https://YOUR_DOMAIN/scim/v2 - Secret Token:
YOUR_TOKEN
- Test Connection and configure attribute mappings
OneLogin
- Applications > Add App > SCIM Provisioner
- Configuration:
- SCIM Base URL:
https://YOUR_DOMAIN/scim/v2 - SCIM Bearer Token:
YOUR_TOKEN - API Connection: SCIM 2.0
- SCIM Base URL:
Attribute Mapping
User Attributes
| SCIM Attribute | Authrim Field | Type |
|---|---|---|
id | id | string (read-only) |
userName | preferred_username | string (required) |
name.givenName | given_name | string |
name.familyName | family_name | string |
emails[primary].value | email | string (required) |
phoneNumbers[primary].value | phone_number | string |
active | active | boolean |
locale | locale | string |
timezone | zoneinfo | string |
Best Practices
Security
- 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
Performance
- Use filtering to reduce response sizes
- Implement pagination for large datasets
- Use ETags to avoid unnecessary updates
Error Handling
- Implement retry logic with exponential backoff
- Handle 429 (rate limit) responses
- Log all errors for troubleshooting
Rate Limits
- 100 requests per minute per token
429 Too Many Requestsresponse when exceededRetry-Afterheader indicates wait time