mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 15:47:24 +00:00
docs: scim v2 interface (#9246)
# Which Problems Are Solved - Lack of documentation for the SCIM v2 interface # How the Problems Are Solved - Introduced a new documentation page detailing the SCIM v2 interface # Additional Context Part of #8140 --------- Co-authored-by: Fabienne Bühler <fabienne@zitadel.com>
This commit is contained in:
parent
4498f9c8f3
commit
60cfa6cb76
868
docs/docs/apis/scim2.md
Normal file
868
docs/docs/apis/scim2.md
Normal file
@ -0,0 +1,868 @@
|
||||
---
|
||||
title: SCIM v2.0 (Preview)
|
||||
---
|
||||
|
||||
:::info
|
||||
The SCIM v2 interface of Zitadel is currently in a [preview stage](/support/software-release-cycles-support#preview).
|
||||
It is not yet feature-complete, may contain bugs, and is not generally available.
|
||||
|
||||
Do not use it for production yet.
|
||||
|
||||
As long as the feature is in a preview state, it will be available for free, it will be put behind a commercial license once it is fully available.
|
||||
:::
|
||||
|
||||
The Zitadel [SCIM v2](https://scim.cloud/) service provider interface enables seamless integration of identity and
|
||||
access management (IAM) systems with Zitadel,
|
||||
following the System for Cross-domain Identity Management (SCIM) v2.0 specification.
|
||||
This interface allows standardized management of IAM resources, making it easier to automate user provisioning and
|
||||
deprovisioning.
|
||||
|
||||
## Supported endpoints
|
||||
|
||||
The Zitadel SCIM v2.0 service provider implementation supports the following endpoints.
|
||||
The base URL for the SCIM endpoint in Zitadel is: `https://${ZITADEL_DOMAIN}/scim/v2/{orgId}`.
|
||||
|
||||
| Endpoint | Remarks |
|
||||
|-------------------------------------------------------------------------|------------------------------------------------------------|
|
||||
| `GET /scim/v2/{orgId}/ServiceProviderConfig` | Retrieve the configuration of the Zitadel service provider |
|
||||
| `GET /scim/v2/{orgId}/Schemas` | Retrieve all supported schemas |
|
||||
| `GET /scim/v2/{orgId}/Schemas/{id}` | Retrieve a known supported schema |
|
||||
| `GET /scim/v2/{orgId}/ResourceTypes` | Retrieve all supported resource types |
|
||||
| `GET /scim/v2/{orgId}/ResourceTypes/{name}` | Retrieve a known supported resource type |
|
||||
| `GET /scim/v2/{orgId}/Users/{id}` | Retrieve a known user |
|
||||
| `GET /scim/v2/{orgId}/Users`<br />`POST /scim/v2/{orgId}/Users/.search` | Query users (including filtering, sorting, paging) |
|
||||
| `POST /scim/v2/{orgId}/Users` | Create a user |
|
||||
| `PUT /scim/v2/{orgId}/Users/{id}` | Replace a user |
|
||||
| `PATCH /scim/v2/{orgId}/Users/{id}` | Modify a user |
|
||||
| `DELETE /scim/v2/{orgId}/Users/{id}` | Delete a user |
|
||||
| `POST /scim/v2/{orgId}/Bulk` | Apply multiple operations in a single request |
|
||||
|
||||
## Authentication
|
||||
|
||||
The SCIM interface adheres to Zitadel's standard API authentication methods.
|
||||
For detailed instructions on authenticating with the SCIM interface, refer to the [Authenticate Service Users Guide](/guides/integrate/service-users/authenticate-service-users).
|
||||
|
||||
## Query
|
||||
|
||||
The list users endpoint supports sorting and filtering for both `GET /scim/v2/{orgId}/Users` and `POST /scim/v2/{orgId}/Users/.search` requests.
|
||||
By default, the response includes up to 100 users, with a maximum allowable value for `count` set to 100.
|
||||
|
||||
### Sort
|
||||
|
||||
The following attributes are supported in the `SortBy` attribute.
|
||||
|
||||
- `meta.created`
|
||||
- `meta.lastModified`
|
||||
- `id`
|
||||
- `username`
|
||||
- `name.familyName`
|
||||
- `name.givenName`
|
||||
- `emails` and `emails.value`
|
||||
|
||||
### Filter
|
||||
|
||||
The following filter attributes and operators are supported:
|
||||
|
||||
| Attribute | Supported operators |
|
||||
|------------------------------|------------------------------|
|
||||
| `meta.created` | `EQ`, `GT`, `GE`, `LT`, `LE` |
|
||||
| `meta.lastModified` | `EQ`, `GT`, `GE`, `LT`, `LE` |
|
||||
| `id` | `EQ`, `NE`, `CO`, `SW`, `EW` |
|
||||
| `externalId` | `EQ`, `NE` |
|
||||
| `username` | `EQ`, `NE`, `CO`, `SW`, `EW` |
|
||||
| `name.familyName` | `EQ`, `NE`, `CO`, `SW`, `EW` |
|
||||
| `name.givenName` | `EQ`, `NE`, `CO`, `SW`, `EW` |
|
||||
| `emails`<br />`emails.value` | `EQ`, `NE`, `CO`, `SW`, `EW` |
|
||||
| `active` | `EQ`, `NE` |
|
||||
|
||||
Filters can have a maximum length of 1000 characters.
|
||||
|
||||
## Examples
|
||||
|
||||
Here are practical examples demonstrating how to interact with the SCIM API,
|
||||
providing clear guidance on common use cases such as creating a user.
|
||||
Make sure to replace any placeholder values (`${}`) with the actual values from your environment.
|
||||
|
||||
<details>
|
||||
<summary>`POST /Users`: Create a minimal user</summary>
|
||||
|
||||
```bash
|
||||
curl -X POST "https://${DOMAIN}/scim/v2/${ORG_ID}/Users" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName": "john.doe",
|
||||
"name": {
|
||||
"familyName": "Doe",
|
||||
"givenName": "John"
|
||||
},
|
||||
"password": "Password1!",
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
]
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
**Response (`201 Created`)**
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:User"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "User",
|
||||
"created": "2025-01-27T15:30:27.651321Z",
|
||||
"lastModified": "2025-01-27T15:30:27.651321Z",
|
||||
"version": "2",
|
||||
"location": "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/304499468865155777"
|
||||
},
|
||||
"id": "304499468865155777",
|
||||
"userName": "john.doe",
|
||||
"name": {
|
||||
"familyName": "Doe",
|
||||
"givenName": "John"
|
||||
},
|
||||
"preferredLanguage": "en",
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`POST /Users`: Create a full user</summary>
|
||||
|
||||
```bash
|
||||
curl -X POST "https://${DOMAIN}/scim/v2/${ORG_ID}/Users" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "Mr. John J Doe, III",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"type": "work",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+1 555-555-5555",
|
||||
"type": "work",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"userType": "Employee",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "en-US",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"password": "Password1!"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response (`201 Created`)**
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:User"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "User",
|
||||
"created": "2025-01-27T15:31:47.84572Z",
|
||||
"lastModified": "2025-01-27T15:31:47.84572Z",
|
||||
"version": "16",
|
||||
"location": "https://localhost:8080/scim/v2/303879575732073153/Users/304499603368096449"
|
||||
},
|
||||
"id": "304499603368096449",
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "John Doe",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "en-US",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+15555555555",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`GET /Users/{id}`: Retrive a known user</summary>
|
||||
|
||||
```bash
|
||||
curl -G "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}" \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}"
|
||||
```
|
||||
|
||||
|
||||
**Response (`200 OK`)**
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:User"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "User",
|
||||
"created": "2025-01-27T15:31:47.84572Z",
|
||||
"lastModified": "2025-01-27T15:31:47.84572Z",
|
||||
"version": "16",
|
||||
"location": "https://localhost:8080/scim/v2/303879575732073153/Users/304499603368096449"
|
||||
},
|
||||
"id": "304499603368096449",
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "John Doe",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "en-US",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+15555555555",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`GET /Users`: List users created after a given date sorted by the creation date</summary>
|
||||
|
||||
```bash
|
||||
curl -G "https://${DOMAIN}/scim/v2/${ORG_ID}/Users" \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-urlencode "sortBy=meta.created" \
|
||||
--data-urlencode "sortOrder=descending" \
|
||||
--data-urlencode "filter=meta.created gt \"2025-01-24T09:22:35.695245Z\""
|
||||
```
|
||||
|
||||
**Response (`200 OK`)**
|
||||
```json
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"itemsPerPage": 100,
|
||||
"totalResults": 1,
|
||||
"startIndex": 1,
|
||||
"Resources": [
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:User"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "User",
|
||||
"created": "2025-01-27T15:31:47.84572Z",
|
||||
"lastModified": "2025-01-27T15:31:47.84572Z",
|
||||
"version": "3",
|
||||
"location": "https://localhost:8080/scim/v2/303879575732073153/Users/304499603368096449"
|
||||
},
|
||||
"id": "304499603368096449",
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "John Doe",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "und",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+15555555555",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`PATCH /Users/{id}`: Set a user inactive</summary>
|
||||
|
||||
```bash
|
||||
curl -X PATCH "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||||
"Operations": [
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "active",
|
||||
"value": false
|
||||
}
|
||||
]
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
**Response**: `204 No Content`
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`PATCH /Users/{id}`: Set the password of a user</summary>
|
||||
|
||||
```bash
|
||||
curl -X PATCH "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||||
"Operations": [
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "password",
|
||||
"value": "Password2!"
|
||||
}
|
||||
]
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
**Response**: `204 No Content`
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`PUT /Users/{id}`: Replace a full user</summary>
|
||||
|
||||
```bash
|
||||
curl -X PUT "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "Mr. John J Doe, III",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"type": "work",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+1 555-555-5555",
|
||||
"type": "work",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"userType": "Employee",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "en-US",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"password": "Password1!"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response (`200 OK`)**
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:User"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "User",
|
||||
"created": "2025-01-27T15:31:47.84572Z",
|
||||
"lastModified": "2025-01-27T15:31:47.84572Z",
|
||||
"version": "16",
|
||||
"location": "https://localhost:8080/scim/v2/303879575732073153/Users/304499603368096449"
|
||||
},
|
||||
"id": "304499603368096449",
|
||||
"externalId": "8d4b51c0-51bd-4386-ae17-79ce5fd36517",
|
||||
"userName": "john.doe@example.com",
|
||||
"name": {
|
||||
"formatted": "John Doe",
|
||||
"familyName": "Doe",
|
||||
"givenName": "John",
|
||||
"middleName": "Jim",
|
||||
"honorificPrefix": "Mr.",
|
||||
"honorificSuffix": "III"
|
||||
},
|
||||
"displayName": "John Doe",
|
||||
"nickName": "Johnny",
|
||||
"profileUrl": "https://login.example.com/john.doe",
|
||||
"title": "Tour Guide",
|
||||
"preferredLanguage": "en-US",
|
||||
"locale": "en-US",
|
||||
"timezone": "America/Los_Angeles",
|
||||
"active": true,
|
||||
"emails": [
|
||||
{
|
||||
"value": "john.doe@example.com",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"value": "+15555555555",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"ims": [
|
||||
{
|
||||
"value": "@j.doe",
|
||||
"type": "X"
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "work",
|
||||
"streetAddress": "100 Universal City Plaza",
|
||||
"locality": "Hollywood",
|
||||
"region": "CA",
|
||||
"postalCode": "91608",
|
||||
"country": "USA",
|
||||
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
|
||||
"primary": true
|
||||
}
|
||||
],
|
||||
"photos": [
|
||||
{
|
||||
"value": "https://photos.example.com/profilephoto/john.doe/F",
|
||||
"type": "photo"
|
||||
}
|
||||
],
|
||||
"entitlements": [
|
||||
{
|
||||
"value": "read-passports",
|
||||
"display": "Read Passports"
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"value": "user-admin",
|
||||
"display": "User administrator"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`DELETE /Users/{id}`: Delete a user</summary>
|
||||
|
||||
```bash
|
||||
curl -X DELETE "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}"
|
||||
```
|
||||
|
||||
**Response**: `204 No Content`
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>`POST /Bulk`: Update the password of one user and delete another one</summary>
|
||||
|
||||
```bash
|
||||
curl -X POST "https://${DOMAIN}/scim/v2/${ORG_ID}/Bulk" \
|
||||
-H 'Content-Type: application/scim+json' \
|
||||
-H 'Accept: application/scim+json' \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
--data-raw '
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
||||
"Operations": [
|
||||
{
|
||||
"method": "PATCH",
|
||||
"path": "/Users/${USER_ID}",
|
||||
"data": {
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||||
"Operations": [
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "password",
|
||||
"value": "Password2!"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/Users/${USER_ID2}"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
**Response**: `200 OK`
|
||||
|
||||
```json
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkResponse"],
|
||||
"Operations": [
|
||||
{
|
||||
"method": "PATCH",
|
||||
"location": "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID}",
|
||||
"status": "204"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"location": "https://${DOMAIN}/scim/v2/${ORG_ID}/Users/${USER_ID2}",
|
||||
"status": "204"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>`GET /ServiceProviderConfig`: Get service provider configuration</summary>
|
||||
|
||||
```bash
|
||||
curl -G "https://${DOMAIN}/scim/v2/${ORG_ID}/ServiceProviderConfig" \
|
||||
-H 'Accept: application/scim+json'
|
||||
```
|
||||
|
||||
**Response**: `200 OK`
|
||||
|
||||
```json
|
||||
{
|
||||
"schemas": [
|
||||
"urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"
|
||||
],
|
||||
"meta": {
|
||||
"resourceType": "ServiceProviderConfig",
|
||||
"location": "https://${DOMAIN}/scim/v2/${ORG_ID}/ServiceProviderConfig"
|
||||
},
|
||||
"documentationUri": "https://zitadel.com/docs/guides/manage/user/scim2",
|
||||
"patch": {
|
||||
"supported": true
|
||||
},
|
||||
"bulk": {
|
||||
"supported": true,
|
||||
"maxOperations": 100,
|
||||
"maxPayloadSize": 1000000
|
||||
},
|
||||
"filter": {
|
||||
"supported": true,
|
||||
"maxResults": 100
|
||||
},
|
||||
"changePassword": {
|
||||
"supported": true
|
||||
},
|
||||
"sort": {
|
||||
"supported": true
|
||||
},
|
||||
"etag": {
|
||||
"supported": false
|
||||
},
|
||||
"authenticationSchemes": [
|
||||
{
|
||||
"name": "Zitadel authentication token",
|
||||
"description": "Authentication scheme using the OAuth Bearer Token Standard",
|
||||
"specUri": "https://www.rfc-editor.org/info/rfc6750",
|
||||
"documentationUri": "https://zitadel.com/docs/guides/integrate/service-users/authenticate-service-users",
|
||||
"type": "oauthbearertoken",
|
||||
"primary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Error handling
|
||||
|
||||
The SCIM interface uses standard HTTP status codes and error messages to indicate the success or failure of API requests
|
||||
following the error handling guidelines of [RFC7644](https://datatracker.ietf.org/doc/html/rfc7644#section-3.12).
|
||||
|
||||
In addition to the default SCIM error schema (`urn:ietf:params:scim:api:messages:2.0:Error`),
|
||||
Zitadel extends the error response with a custom schema, `urn:ietf:params:scim:api:zitadel:messages:2.0:ErrorDetail`.
|
||||
This schema includes additional attributes, such as the untranslated error message and an error id,
|
||||
which aids pinpointing the source of the error in the system.
|
||||
|
||||
## Resources
|
||||
|
||||
- **[Zitadel SCIM Documentation](/guides/manage/user/scim2)**: Documentation of Zitadel's SCIM implementation, including configuration details and known limitations.
|
||||
- **[SCIM](https://scim.cloud/)**: The Webpage of SCIM.
|
||||
- **[RFC7643](https://tools.ietf.org/html/rfc7643) Core Schema**:
|
||||
The Core Schema provides a platform-neutral schema and extension model for representing users and groups.
|
||||
- **[RFC7644](https://tools.ietf.org/html/rfc7644) Protocol**:
|
||||
The SCIM Protocol is an application-level, REST protocol for provisioning and managing identity data on the web.
|
||||
- **[RFC7642](https://tools.ietf.org/html/rfc7642) Definitions, Overview, Concepts, and Requirements**:
|
||||
This document lists the user scenarios and use cases of System for Cross-domain Identity Management (SCIM).
|
127
docs/docs/guides/manage/user/scim2.md
Normal file
127
docs/docs/guides/manage/user/scim2.md
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
title: SCIM v2.0 (Preview)
|
||||
---
|
||||
|
||||
:::info
|
||||
The SCIM v2 interface of Zitadel is currently in a [preview stage](/support/software-release-cycles-support#preview).
|
||||
It is not yet feature-complete, may contain bugs, and is not generally available.
|
||||
|
||||
Do not use it for production yet.
|
||||
|
||||
As long as the feature is in a preview state, it will be available for free, it will be put behind a commercial license once it is fully available.
|
||||
:::
|
||||
|
||||
The Zitadel [SCIM v2](https://scim.cloud/) service provider interface enables seamless integration of identity and
|
||||
access management (IAM) systems with Zitadel,
|
||||
following the System for Cross-domain Identity Management (SCIM) v2.0 specification.
|
||||
This interface allows standardized management of IAM resources, making it easier to automate user provisioning and
|
||||
deprovisioning.
|
||||
|
||||
## API
|
||||
|
||||
To learn more about Zitadel's SCIM API, see the API documentation [here](/apis/scim2).
|
||||
|
||||
## Provisioning domain
|
||||
|
||||
A provisioning domain refers to an administrative domain that exists outside the domain of a service provider due to
|
||||
legal or technical reasons.
|
||||
For more details, refer to the [definitions](https://datatracker.ietf.org/doc/html/rfc7643#section-1.2)
|
||||
of [RFC7643](https://datatracker.ietf.org/doc/html/rfc7643).
|
||||
|
||||
The `externalId` of a user is scoped to the provisioning domain.
|
||||
To set a provisioning domain for a machine user,
|
||||
add a metadata entry with the key `urn:zitadel:scim:provisioningDomain` and assign its value to the corresponding
|
||||
provisioning domain.
|
||||
|
||||
When a machine user has a `urn:zitadel:scim:provisioningDomain` metadata set,
|
||||
the `externalId` of all users provisioned or queried by that machine user is stored in the users' metadata.
|
||||
The key format is `urn:zitadel:scim:{provisioningDomain}:externalId`,
|
||||
where `{provisioningDomain}` is replaced with the machine user's provisioning domain.
|
||||
If the machine user does not have a provisioning domain set,
|
||||
a simplified metadata key `urn:zitadel:scim:externalId` is used to store and retrieve the `externalId` of users.
|
||||
|
||||
## Mapping
|
||||
|
||||
The table below outlines how supported SCIM attributes in the user schema map to corresponding Zitadel user attributes.
|
||||
Some attributes are directly mapped to Zitadel user attributes, while others are stored in the user's metadata.
|
||||
For more information about user metadata, see [here](../customize/user-metadata).
|
||||
|
||||
| SCIM | Zitadel | Remarks |
|
||||
|------------------------|-----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | `userId` | |
|
||||
| `username` | `username` | |
|
||||
| `name.formatted` | `profile.displayName` | The SCIM attribute `displayName` takes precedence over `name.formatted` |
|
||||
| `name.familyName` | `profile.familyName` | |
|
||||
| `name.middleName` | `metadata[urn:zitadel:scim:name.middleName]` | |
|
||||
| `name.honorificPrefix` | `metadata[urn:zitadel:scim:name.honorificPrefix]` | |
|
||||
| `name.honorificSuffix` | `metadata[urn:zitadel:scim:name.honorificSuffix]` | |
|
||||
| `displayName` | `profile.displayName` | The SCIM attribute `displayName` takes precedence over `name.formatted` |
|
||||
| `nickName` | `profile.nickName` | |
|
||||
| `profileUrl` | `metadata[urn:zitadel:scim:profileUrl]` | |
|
||||
| `title` | `metadata[urn:zitadel:scim:title]` | |
|
||||
| `preferredLanguage` | `profile.preferredLanguage` | |
|
||||
| `locale` | `metadata[urn:zitadel:scim:locale]` | |
|
||||
| `timezone` | `metadata[urn:zitadel:scim:timezone]` | |
|
||||
| `active` | `state` | `Initial` and `Active` are mapped to `active = true`, all other states are mapped to `active = false`.<br />The `active` value can only be updated if the user is in the state `Active` or `Inactive`. |
|
||||
| `password` | `password` | |
|
||||
| `emails` | `email` | Only the `primary` email is stored in Zitadel, if there is no `primary` email, the first one is stored. By default emails from SCIM are considered verified, this can be adjusted in the [configuration](#configuration). |
|
||||
| `phoneNumbers` | `phone` | Only the `primary` phone number is stored in Zitadel, if there is no `primary` phone number, the first one is stored. By default phone numbers from SCIM are considered verified, this can be adjusted in the [configuration](#configuration). |
|
||||
| `ims` | `metadata[urn:zitadel:scim:ims]` | Serialized as JSON. |
|
||||
| `photos` | `metadata[urn:zitadel:scim:photos]` | Serialized as JSON. |
|
||||
| `addresses` | `metadata[urn:zitadel:scim:addresses]` | Serialized as JSON. |
|
||||
| `entitlements` | `metadata[urn:zitadel:scim:entitlements]` | Serialized as JSON. |
|
||||
| `roles` | `metadata[urn:zitadel:scim:roles]` | Serialized as JSON. |
|
||||
| `externalId` | `metadata[urn:zitadel:scim:externalId]`<br />`metadata[urn:zitadel:scim:{provisioningDomain}:externalId]` | See [provisioning domain](#provisioning-domain). |
|
||||
|
||||
## Configuration
|
||||
|
||||
This section provides details on the runtime configuration of the SCIM interface of Zitadel.
|
||||
|
||||
By default, Zitadel's SCIM interface assumes that email addresses and phone numbers are verified.
|
||||
The bulk endpoint supports up to 100 operations per request, with a maximum request body size of 1 MB.
|
||||
This behavior can be adjusted through the Zitadel runtime configuration settings:
|
||||
|
||||
```yaml
|
||||
SCIM:
|
||||
EmailVerified: true
|
||||
PhoneVerified: true
|
||||
MaxRequestBodySize: 1_000_000
|
||||
Bulk:
|
||||
MaxOperationsCount: 100
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
This section outlines the known limitations of the Zitadel SCIM implementation,
|
||||
including unsupported features, partial compliance with the SCIM specification,
|
||||
and any potential edge cases to consider during integration.
|
||||
|
||||
### Supported schemas
|
||||
|
||||
Only the users schema `urn:ietf:params:scim:schemas:core:2.0:User` is supported.
|
||||
|
||||
### Required attributes
|
||||
|
||||
The following SCIM user attributes are required, in addition to those required by the SCIM standard:
|
||||
|
||||
* `name.familyName`
|
||||
* `name.givenName`
|
||||
* `emails`: at least one email is required
|
||||
|
||||
### Duplicated attribute mapping
|
||||
|
||||
The SCIM user attributes `name.formatted` and `displayName` are both mapped to the `profile.displayName` attribute in
|
||||
Zitadel.
|
||||
When a user is provisioned with different values for these attributes, `displayName` takes precedence.
|
||||
Only the value of `displayName` is stored and returned in subsequent queries.
|
||||
|
||||
## Resources
|
||||
|
||||
- **[Zitadel SCIM API Documentation](/apis/scim2)**: Documentation of Zitadel's SCIM API implementation.
|
||||
- **[SCIM](https://scim.cloud/)**: The Webpage of SCIM.
|
||||
- **[RFC7643](https://tools.ietf.org/html/rfc7643) Core Schema**:
|
||||
The Core Schema provides a platform-neutral schema and extension model for representing users and groups.
|
||||
- **[RFC7644](https://tools.ietf.org/html/rfc7644) Protocol**:
|
||||
The SCIM Protocol is an application-level, REST protocol for provisioning and managing identity data on the web.
|
||||
- **[RFC7642](https://tools.ietf.org/html/rfc7642) Definitions, Overview, Concepts, and Requirements**:
|
||||
This document lists the user scenarios and use cases of System for Cross-domain Identity Management (SCIM).
|
@ -159,6 +159,7 @@ module.exports = {
|
||||
"guides/manage/user/reg-create-user",
|
||||
"guides/manage/customize/user-metadata",
|
||||
"guides/manage/customize/user-schema",
|
||||
"guides/manage/user/scim2",
|
||||
],
|
||||
},
|
||||
"guides/manage/terraform-provider",
|
||||
@ -837,6 +838,14 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Provision Users",
|
||||
collapsed: true,
|
||||
items: [
|
||||
'apis/scim2'
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Actions",
|
||||
|
Loading…
x
Reference in New Issue
Block a user