Okta’s SCIM provisioning is essentially a standardized way for Okta to talk to other applications about users, telling them when to create, update, or deactivate accounts.
Let’s see this in action. Imagine you’re onboarding a new employee, Sarah.
First, in Okta, you assign Sarah to the "Sales Team" application.
// Okta User Assignment Event (simplified)
{
"eventType": "user.session.impersonate.success",
"actor": {
"id": "00u123abc456def789",
"type": "User",
"displayName": "Admin User",
"alternateId": "admin@example.com"
},
"published": "2023-10-27T10:00:00.000Z",
"severity": "INFO",
"appName": "Salesforce",
"user": {
"id": "00u987zyx654wvu321",
"type": "User",
"login": "sarah.jones@example.com",
"firstName": "Sarah",
"lastName": "Jones"
},
"действие": {
"name": "assign",
"меседж": "User assigned to application"
}
}
Okta then translates this assignment into a SCIM POST request to Salesforce’s SCIM endpoint, asking it to create Sarah.
// SCIM POST Request to Salesforce (simplified)
POST /scim/v2/Users HTTP/1.1
Host: your-salesforce-instance.scim.salesforce.com
Authorization: Bearer <access_token>
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"externalId": "00u987zyx654wvu321",
"active": true,
"userName": "sarah.jones@example.com",
"name": {
"givenName": "Sarah",
"familyName": "Jones"
},
"emails": [
{
"value": "sarah.jones@example.com",
"type": "work"
}
]
}
Salesforce receives this, creates Sarah’s account, and responds with a 201 Created status and the user’s SCIM ID.
// SCIM 201 Created Response from Salesforce (simplified)
HTTP/1.1 201 Created
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "a1b2c3d4e5f67890",
"externalId": "00u987zyx654wvu321",
"active": true,
"userName": "sarah.jones@example.com",
"name": {
"givenName": "Sarah",
"familyName": "Jones"
},
"emails": [
{
"value": "sarah.jones@example.com",
"type": "work"
}
],
"meta": {
"created": "2023-10-27T10:05:00.000Z",
"lastModified": "2023-10-27T10:05:00.000Z",
"version": "1"
}
}
Later, if Sarah changes her name to "Sarah Smith" in Okta, Okta sends a PUT request to Salesforce’s SCIM endpoint, updating her record.
// SCIM PUT Request to Salesforce (simplified)
PUT /scim/v2/Users/a1b2c3d4e5f67890 HTTP/1.1
Host: your-salesforce-instance.scim.salesforce.com
Authorization: Bearer <access_token>
Content-Type: application/scim+json
If-Match: "1" // SCIM ETag for optimistic concurrency
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"externalId": "00u987zyx654wvu321",
"active": true,
"userName": "sarah.jones@example.com", // userName is immutable
"name": {
"givenName": "Sarah",
"familyName": "Smith" // Updated familyName
},
"emails": [
{
"value": "sarah.jones@example.com",
"type": "work"
}
]
}
When Sarah leaves the company, you deactivate her Okta account. Okta then sends a SCIM PATCH request to set active to false.
// SCIM PATCH Request to Salesforce (simplified)
PATCH /scim/v2/Users/a1b2c3d4e5f67890 HTTP/1.1
Host: your-salesforce-instance.scim.salesforce.com
Authorization: Bearer <access_token>
Content-Type: application/scim+json
If-Match: "2" // SCIM ETag for optimistic concurrency
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOperation"],
"Operations": [
{
"op": "replace",
"path": "active",
"value": false
}
]
}
This whole process automates user lifecycle management, ensuring that when someone joins, leaves, or changes roles, their access in connected applications is updated automatically and consistently. The core problem it solves is the manual, error-prone process of creating, updating, and deactivating user accounts across multiple systems. Okta acts as the single source of truth for user identity, and SCIM is the language it uses to communicate those changes to downstream applications.
The system operates on a push model. Okta detects a change (like an assignment or profile update) and pushes the corresponding SCIM request to the application. The application, in turn, acts as the SCIM service provider, receiving and processing these requests. Okta is the SCIM client. The externalId attribute is crucial; it’s Okta’s unique identifier for the user, which the application stores and uses to correlate its own user object with Okta’s. This externalId is typically mapped to a unique ID field in the target application.
One fundamental aspect that trips many people up is how userName is handled. While most attributes can be updated via PUT or PATCH, the userName (often the primary email address) is typically immutable in SCIM. If you need to change a user’s userName, you usually have to deactivate the existing user and create a new one with the new userName. Okta’s SCIM implementation often handles this by using the externalId to find the user and then performing a PATCH operation. If the userName needs to change, Okta might provision a new user and then attempt to deactivate the old one, or it might have specific logic for handling userName changes if the application’s SCIM implementation supports it via a specific extension or workflow.
The next logical step to explore is handling group memberships and role assignments via SCIM, as this extends the automation beyond just individual user accounts.