SCIM 2.0 Provisioning API
Auris implements the SCIM 2.0 (System for Cross-domain Identity Management) protocol for automated user and group provisioning. SCIM enables identity providers like Okta, Azure AD (Entra ID), OneLogin, and JumpCloud to automatically create, update, and deactivate user accounts in Auris when changes are made in the IdP directory.
The SCIM API follows RFC 7643 (Core Schema) and RFC 7644 (Protocol) specifications.
SCIM Connection Setup
Before your IdP can provision users, you must create a SCIM connection in the Auris Console:
- Go to Console > Settings > SCIM Provisioning
- Click Add Connection
- Note the SCIM Base URL and Bearer Token
- Configure these in your IdP’s SCIM integration settings
The SCIM base URL follows this format:
https://api.altovar.net/api/scim/v2Authentication
All SCIM endpoints use Bearer token authentication. The token is generated when creating a SCIM connection in the Auris Console.
Authorization: Bearer scim_token_hereThe token authenticates the IdP and identifies which SCIM connection configuration to use (including the target Keycloak realm and attribute mappings).
SCIM tokens are long-lived and grant full provisioning access. Treat them as secrets. Rotate tokens periodically via the Auris Console.
Connection Management
These endpoints are for managing SCIM connections from the Auris Console (admin API). They are not part of the SCIM protocol itself.
/api/scim/connectionsRequires: view:scim_connectionsList all SCIM connections for the tenant.
Success response
{
"ok": true,
"data": [
{
"id": "scim_conn_abc123",
"name": "Okta Production",
"provider": "okta",
"keycloakRealm": "acme-corp",
"isActive": true,
"lastSyncAt": "2025-02-18T09:00:00Z",
"userCount": 245,
"groupCount": 12,
"createdAt": "2025-01-15T10:00:00Z"
}
]
}/api/scim/connectionsRequires: manage:scim_connectionsCreate a new SCIM connection. Returns the connection details including the generated Bearer token. The token is only returned once — store it securely.
Request body
{
"name": "Okta Production",
"provider": "okta",
"keycloakRealm": "acme-corp"
}Success response
{
"ok": true,
"data": {
"id": "scim_conn_def456",
"name": "Okta Production",
"provider": "okta",
"keycloakRealm": "acme-corp",
"token": "scim_abc123def456...",
"baseUrl": "https://api.altovar.net/api/scim/v2",
"isActive": true,
"createdAt": "2025-02-18T10:00:00Z"
}
}Users
List Users
/api/scim/v2/UsersRequires: SCIM Bearer tokenList users in the tenant. Supports SCIM filtering, pagination, and attribute selection. Returns users in SCIM Core Schema format.
Query parameters
| Parameter | Type | Description |
|---|---|---|
filter | string | SCIM filter expression (see Filter Syntax) |
startIndex | integer | 1-based start index (default: 1) |
count | integer | Maximum results per page (default: 20, max: 100) |
sortBy | string | Attribute to sort by (e.g., userName) |
sortOrder | ascending | descending | Sort direction (default: ascending) |
attributes | string | Comma-separated list of attributes to include |
excludedAttributes | string | Comma-separated list of attributes to exclude |
Example request
GET /api/scim/v2/Users?filter=userName eq "[email protected]"&count=10Success response
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 245,
"startIndex": 1,
"itemsPerPage": 20,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_abc123",
"externalId": "okta_user_001",
"userName": "[email protected]",
"name": {
"givenName": "Alice",
"familyName": "Smith",
"formatted": "Alice Smith"
},
"displayName": "Alice Smith",
"emails": [
{
"value": "[email protected]",
"type": "work",
"primary": true
}
],
"phoneNumbers": [
{
"value": "+39021234567",
"type": "work"
}
],
"active": true,
"groups": [
{
"value": "group_eng",
"display": "Engineering"
}
],
"meta": {
"resourceType": "User",
"created": "2025-01-15T10:00:00Z",
"lastModified": "2025-02-18T09:00:00Z",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_abc123"
}
}
]
}SCIM responses use the SCIM schema format (not the standard Auris API envelope). The schemas field, Resources array, and meta object are required by the SCIM specification.
Get User
/api/scim/v2/Users/[id]Requires: SCIM Bearer tokenRetrieve a single user by their Auris user ID. Returns the full SCIM user representation.
Success response
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_abc123",
"externalId": "okta_user_001",
"userName": "[email protected]",
"name": {
"givenName": "Alice",
"familyName": "Smith",
"formatted": "Alice Smith"
},
"displayName": "Alice Smith",
"emails": [
{
"value": "[email protected]",
"type": "work",
"primary": true
}
],
"active": true,
"groups": [
{
"value": "group_eng",
"display": "Engineering"
}
],
"meta": {
"resourceType": "User",
"created": "2025-01-15T10:00:00Z",
"lastModified": "2025-02-18T09:00:00Z",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_abc123"
}
}Error response (SCIM format)
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail": "User not found",
"status": "404"
}Create User
/api/scim/v2/UsersRequires: SCIM Bearer tokenCreate a new user account. The user is created in both the Auris database and the Keycloak
realm associated with the SCIM connection. If externalId is provided, it is stored for
future reconciliation.
Request body
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"externalId": "okta_user_002",
"userName": "[email protected]",
"name": {
"givenName": "Bob",
"familyName": "Jones"
},
"displayName": "Bob Jones",
"emails": [
{
"value": "[email protected]",
"type": "work",
"primary": true
}
],
"active": true
}SCIM-to-Auris field mapping (default)
| SCIM Field | Auris Field | Notes |
|---|---|---|
userName | email / scimUserName | Used as the primary identifier |
externalId | scimExternalId | IdP-side unique identifier |
name.givenName | firstName | |
name.familyName | lastName | |
displayName | Computed | firstName + " " + lastName |
emails[primary].value | email | Primary email becomes the Auris email |
phoneNumbers[0].value | phoneNumber | |
active | enabled |
Success response (HTTP 201)
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_new789",
"externalId": "okta_user_002",
"userName": "[email protected]",
"name": {
"givenName": "Bob",
"familyName": "Jones",
"formatted": "Bob Jones"
},
"displayName": "Bob Jones",
"emails": [
{
"value": "[email protected]",
"type": "work",
"primary": true
}
],
"active": true,
"meta": {
"resourceType": "User",
"created": "2025-02-18T10:00:00Z",
"lastModified": "2025-02-18T10:00:00Z",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_new789"
}
}Error response
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail": "User with userName '[email protected]' already exists",
"status": "409",
"scimType": "uniqueness"
}Replace User (Full Update)
/api/scim/v2/Users/[id]Requires: SCIM Bearer tokenReplace a user resource entirely. All SCIM attributes in the request body replace the current values. Attributes not present in the request body are cleared (set to null/empty).
Request body
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"externalId": "okta_user_001",
"userName": "[email protected]",
"name": {
"givenName": "Alicia",
"familyName": "Smith-Jones"
},
"emails": [
{
"value": "[email protected]",
"type": "work",
"primary": true
}
],
"active": true
}Success response: Full SCIM user representation (same format as GET).
Partial Update (PATCH)
/api/scim/v2/Users/[id]Requires: SCIM Bearer tokenPartially update a user using SCIM PATCH operations. This is the most commonly used update
method by IdPs. Supports add, replace, and remove operations.
Request body — Deactivate user
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "active",
"value": false
}
]
}Request body — Update multiple fields
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "name.familyName",
"value": "Smith-Jones"
},
{
"op": "replace",
"path": "emails[type eq \"work\"].value",
"value": "[email protected]"
}
]
}PATCH operation types
| Operation | Description |
|---|---|
add | Add a new value to a multi-valued attribute or set a single-valued attribute |
replace | Replace the current value of an attribute |
remove | Remove an attribute value |
Success response: Full SCIM user representation reflecting the updated state.
Delete User
/api/scim/v2/Users/[id]Requires: SCIM Bearer tokenDelete (deactivate) a user. In Auris, SCIM delete performs a soft-delete: the user is disabled and their Keycloak account is removed, but the database record is retained for audit purposes.
Success response: HTTP 204 No Content (empty body, per SCIM spec).
Groups
List Groups
/api/scim/v2/GroupsRequires: SCIM Bearer tokenList groups in the tenant. Groups in Auris correspond to roles. Supports SCIM filtering and pagination.
Query parameters
| Parameter | Type | Description |
|---|---|---|
filter | string | SCIM filter expression |
startIndex | integer | 1-based start index (default: 1) |
count | integer | Maximum results per page (default: 20) |
Success response
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 5,
"startIndex": 1,
"itemsPerPage": 20,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": "role_abc123",
"displayName": "engineering",
"members": [
{
"value": "usr_abc123",
"display": "[email protected]"
},
{
"value": "usr_def456",
"display": "[email protected]"
}
],
"meta": {
"resourceType": "Group",
"created": "2025-01-01T00:00:00Z",
"lastModified": "2025-02-15T10:00:00Z",
"location": "https://api.altovar.net/api/scim/v2/Groups/role_abc123"
}
}
]
}Get Group
/api/scim/v2/Groups/[id]Requires: SCIM Bearer tokenRetrieve a single group by ID, including its member list.
Create Group
/api/scim/v2/GroupsRequires: SCIM Bearer tokenCreate a new group (role) with optional initial members.
Request body
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "marketing",
"members": [
{
"value": "usr_abc123"
}
]
}Success response (HTTP 201): Full SCIM group representation.
Replace Group
/api/scim/v2/Groups/[id]Requires: SCIM Bearer tokenReplace a group resource entirely. The member list in the request replaces the current members.
Partial Update Group
/api/scim/v2/Groups/[id]Requires: SCIM Bearer tokenPartially update a group using SCIM PATCH operations. Most commonly used to add or remove members.
Request body — Add members
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [
{ "value": "usr_ghi789" },
{ "value": "usr_jkl012" }
]
}
]
}Request body — Remove a member
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "remove",
"path": "members[value eq \"usr_abc123\"]"
}
]
}Delete Group
/api/scim/v2/Groups/[id]Requires: SCIM Bearer tokenDelete a group (role). All members are unassigned. Returns HTTP 204 No Content.
Bulk Operations
/api/scim/v2/BulkRequires: SCIM Bearer tokenExecute multiple SCIM operations in a single request. Supports up to 100 operations per request. Each operation is processed independently — a failure in one operation does not prevent others from executing. Conforms to RFC 7644 Section 3.7.
Request body
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Users",
"bulkId": "user1",
"data": {
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Charlie",
"familyName": "Brown"
},
"emails": [{ "value": "[email protected]", "primary": true }],
"active": true
}
},
{
"method": "PATCH",
"path": "/Users/usr_abc123",
"data": {
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "active", "value": false }
]
}
},
{
"method": "DELETE",
"path": "/Users/usr_old999"
}
]
}Success response
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "user1",
"status": "201",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_new123",
"response": {
"id": "usr_new123",
"userName": "[email protected]"
}
},
{
"method": "PATCH",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_abc123",
"status": "200"
},
{
"method": "DELETE",
"location": "https://api.altovar.net/api/scim/v2/Users/usr_old999",
"status": "204"
}
]
}Failed operation example
{
"method": "POST",
"bulkId": "user2",
"status": "409",
"response": {
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail": "User with userName '[email protected]' already exists",
"scimType": "uniqueness"
}
}Limits
| Limit | Value |
|---|---|
| Maximum operations per request | 100 |
| Supported methods | POST, PUT, PATCH, DELETE |
GET in bulk | Not supported (use list endpoints instead) |
Bulk operations are non-transactional. Each operation is processed independently. If operation #3 fails, operations #1, #2, #4, etc. are still processed. Check the status field of each operation in the response.
Filter Syntax
The SCIM filter syntax (RFC 7644 Section 3.4.2.2) supports attribute comparison, logical operators, and grouping. Auris implements a recursive descent parser that handles the full filter grammar.
Comparison Operators
| Operator | Description | Example |
|---|---|---|
eq | Equal | userName eq "[email protected]" |
ne | Not equal | active ne false |
co | Contains (substring) | name.familyName co "smith" |
sw | Starts with | userName sw "alice" |
ew | Ends with | userName ew "@example.com" |
gt | Greater than | meta.lastModified gt "2025-01-01T00:00:00Z" |
lt | Less than | meta.created lt "2025-02-01T00:00:00Z" |
ge | Greater than or equal | meta.lastModified ge "2025-01-01T00:00:00Z" |
le | Less than or equal | meta.created le "2025-02-01T00:00:00Z" |
pr | Present (attribute exists and is non-empty) | phoneNumbers pr |
Logical Operators
| Operator | Description | Example |
|---|---|---|
and | Both conditions must be true | active eq true and name.familyName co "smith" |
or | At least one condition must be true | userName eq "[email protected]" or userName eq "[email protected]" |
Grouping
Use parentheses to control evaluation order:
(active eq true) and (name.familyName eq "Smith" or name.familyName eq "Jones")Dot-Notation Attribute Paths
Nested attributes use dot notation:
name.givenName eq "Alice"
emails[type eq "work"].value sw "alice"Filter Examples
Find a user by email:
GET /api/scim/v2/Users?filter=userName eq "[email protected]"Find all active users with a specific last name:
GET /api/scim/v2/Users?filter=active eq true and name.familyName eq "Smith"Find users modified after a specific date:
GET /api/scim/v2/Users?filter=meta.lastModified gt "2025-02-01T00:00:00Z"Find users with a phone number:
GET /api/scim/v2/Users?filter=phoneNumbers prAttribute Mapping
Auris supports custom attribute mapping between SCIM attributes and Auris user fields. Mappings can be configured per SCIM connection via the Console or API.
/api/scim/connections/[id]/mappingsRequires: manage:scim_connectionsList attribute mappings for a SCIM connection.
Success response
{
"ok": true,
"data": [
{
"id": "map_abc123",
"scimAttribute": "userName",
"aurisAttribute": "email",
"direction": "both",
"isActive": true
},
{
"id": "map_def456",
"scimAttribute": "name.givenName",
"aurisAttribute": "firstName",
"direction": "both",
"isActive": true
},
{
"id": "map_ghi789",
"scimAttribute": "urn:custom:department",
"aurisAttribute": "metadata.department",
"direction": "inbound",
"isActive": true
}
]
}Mapping directions
| Direction | Description |
|---|---|
inbound | IdP to Auris only (used during provisioning from the IdP) |
outbound | Auris to IdP only (used when the IdP reads from Auris) |
both | Bidirectional mapping |
/api/scim/connections/[id]/mappingsRequires: manage:scim_connectionsCreate a new attribute mapping.
Request body
{
"scimAttribute": "urn:custom:department",
"aurisAttribute": "metadata.department",
"direction": "inbound"
}/api/scim/connections/[id]/mappings/[mappingId]Requires: manage:scim_connectionsDelete an attribute mapping.
Sync Statistics
/api/scim/connections/[id]/statsRequires: view:scim_connectionsGet provisioning statistics for a SCIM connection, broken down by time period.
Success response
{
"ok": true,
"data": {
"last24Hours": {
"created": 5,
"updated": 12,
"deactivated": 1,
"errors": 0
},
"last7Days": {
"created": 23,
"updated": 89,
"deactivated": 4,
"errors": 2
},
"last30Days": {
"created": 67,
"updated": 312,
"deactivated": 11,
"errors": 5
}
}
}Connection Testing
/api/scim/connections/[id]/testRequires: manage:scim_connectionsTest a SCIM connection by performing a health check. Verifies that the Bearer token is valid, the Keycloak realm is accessible, and the connection can list users.
Success response
{
"ok": true,
"data": {
"success": true,
"tokenValid": true,
"realmAccessible": true,
"userCount": 245,
"latency": 89
}
}Failed test response
{
"ok": true,
"data": {
"success": false,
"tokenValid": true,
"realmAccessible": false,
"error": "Keycloak realm 'acme-corp' is not reachable"
}
}SCIM Error Format
SCIM errors follow the RFC 7644 error schema:
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail": "Human-readable error description",
"status": "400",
"scimType": "invalidValue"
}SCIM error types
| scimType | HTTP Status | Description |
|---|---|---|
invalidValue | 400 | Request contains an invalid attribute value |
invalidFilter | 400 | Filter expression has a syntax error |
tooMany | 400 | Bulk request exceeds the maximum operation count |
uniqueness | 409 | Attribute value violates a uniqueness constraint (e.g., duplicate email) |
mutability | 400 | Attempted to modify a read-only attribute |
| (none) | 401 | Invalid or missing Bearer token |
| (none) | 404 | Resource not found |
IdP-Specific Notes
Okta
Okta sends userName as the user’s email by default. The Okta SCIM app supports:
- User provisioning (create, update, deactivate)
- Group push (assign Okta groups to Auris roles)
- Profile sync (attribute mapping in Okta admin)
Set the SCIM connector base URL to https://api.altovar.net/api/scim/v2 and authentication to HTTP Header with the Bearer token.
Azure AD (Entra ID)
Azure AD uses externalId as the primary reconciliation key. Configure:
- Provisioning mode: Automatic
- Tenant URL:
https://api.altovar.net/api/scim/v2 - Secret Token: Your SCIM Bearer token
- Mapping: Map
userPrincipalNametouserName
Azure AD sends PATCH requests with a slightly non-standard format for multi-valued attributes. Auris handles these variations automatically.
OneLogin
OneLogin supports SCIM 2.0 provisioning. Configure the SCIM Base URL and Bearer token in the OneLogin app’s provisioning settings. OneLogin uses externalId for user reconciliation.
Permissions Reference
| Permission | Description |
|---|---|
manage:scim_connections | Create, update, and delete SCIM connections and attribute mappings |
view:scim_connections | View SCIM connections and sync statistics |
view:scim_logs | View SCIM provisioning logs |
The SCIM protocol endpoints (/api/scim/v2/*) use Bearer token authentication from the SCIM connection, not the standard Auris admin permissions. The permissions listed above apply only to the connection management endpoints in the Auris Console.
Related
- SCIM 2.0 Protocol — How SCIM provisioning works at the protocol level
- SCIM 2.0 Provisioning — Step-by-step SCIM setup guide
- SCIM Provisioning — Configure SCIM connections from the Console
- Users API — Manual user management endpoints
- User Import & Export API — Bulk user migration alternative