Skip to content

Commit b84a0ca

Browse files
hperlvinckr
andauthored
docs: more detailed SCIM docs (#2123)
* add more SCIM docs * spelling and grammar fixes * document events * chore: capitalization errors * chore: text consistency --------- Co-authored-by: vinckr <[email protected]>
1 parent e30a647 commit b84a0ca

File tree

2 files changed

+159
-28
lines changed

2 files changed

+159
-28
lines changed

docs/kratos/manage-identities/50_scim.mdx

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ SCIM provisioning is only available in Ory Network and via the Ory Enterprise Li
1414
:::
1515

1616
SCIM (System for Cross-domain Identity Management) is a standard for automating the exchange of user identity information between
17-
identity domains or IT systems. It is designed to make it easier to manage user identities in cloud-based applications and
17+
identity domains or IT systems. It is designed to simplify the management of user identities in cloud-based applications and
1818
services. SCIM provides a common schema for representing user identities and a RESTful API for managing them. This allows
19-
organizations to automate the provisioning and de-provisioning of user accounts across multiple systems, reducing the
20-
administrative burden and improving security.
19+
organizations to automate the provisioning and de-provisioning of user accounts across multiple systems, reducing administrative
20+
burden and improving security.
2121

22-
In the Ory Network, SCIM is available at the organization level. This means that within one project, you can have multiple
22+
In Ory Network, SCIM is available at the organization level. This means that within one project, you can have multiple
2323
organizations with different SCIM configurations. Each organization can have its own SCIM settings, including the ability to
2424
enable or disable SCIM, set the base URL for SCIM endpoints, and configure authentication methods. This allows organizations to
2525
tailor their SCIM implementation to meet their specific needs and requirements.
2626

27-
Identities that are provisioned through the SCIM API are automatically created in the Ory Network and added to that SCIM server's
28-
organization. The provisioned identities can then log in through any of the organization's configured SSO methods.
27+
Identities provisioned through the SCIM API are automatically created in Ory Network and added to that SCIM server's organization.
28+
The provisioned identities can then log in through any of the organization's configured SSO methods.
2929

3030
```mdx-code-block
3131
import Mermaid from "@site/src/theme/Mermaid"
@@ -60,11 +60,23 @@ SCIM client's settings.
6060

6161
- **Client ID**: Enter an identifier for your SCIM client. This identifier will be part of the URL the client uses to access the
6262
Ory Network SCIM server. It should be unique within your project.
63-
- **Label**: Enter a human-readable label for your SCIM client. the SCIM server.
64-
- **Authorization header secret**: Enter a secret in the client authenticaiton's **secret** field. This secret will be used to
63+
- **Label**: Enter a human-readable label for your SCIM client.
64+
- **Authorization header secret**: Enter a secret in the client authentication's **secret** field. This secret will be used to
6565
authenticate requests to the SCIM server. Clients need to specify this in the `Authorization` header of their requests.
6666
- **Data mapping**: When the client creates or updates a user, the supplied data will be applied to the identity based on this
67-
data mapping.
67+
data mapping. See below for more details.
68+
69+
### Data mapping
70+
71+
The data mapping is a Jsonnet script that defines how the data the SCIM client sends should be mapped to the identity in the Ory
72+
Network. This mapping will be applied any time the SCIM client creates or updates a user (`POST`, `PATCH`, or `PUT`), and the
73+
identity will be updated accordingly. However, the mapping is unidirectional. For example, if the user updates an identity trait
74+
that was previously set by the SCIM client, the SCIM client will not be able to retrieve the updated value.
75+
76+
In the context of the Jsonnet script, the SCIM user data is available as `std.extVar('scim')`. For the available attributes, refer
77+
to the [SCIM user resource schema](https://datatracker.ietf.org/doc/html/rfc7643#section-4.1) or the documentation below.
78+
79+
The script should return a JSON object as defined in the [Jsonnet reference](../reference/jsonnet#output).
6880

6981
### Use the SCIM client
7082

@@ -88,13 +100,92 @@ The following endpoints are available:
88100
- `PATCH /Groups/{id}`: Partially update a specific group by ID.
89101
- `DELETE /Groups/{id}`: Delete a specific group by ID.
90102

91-
### Known limitations
92-
93-
- For querying users with `GET /Users`, the SCIM server only supports the `eq` operator for filtering, and only with the
103+
### SCIM resource schemas
104+
105+
For programmatic discovery of the SCIM resource schemas, you can use the `GET /Schemas` endpoint. This will return a list of all
106+
available schemas.
107+
108+
### SCIM user resource schema
109+
110+
Ory Network fully supports the standard SCIM user resource schema as defined in the
111+
[SCIM RFC](https://datatracker.ietf.org/doc/html/rfc7643#section-4.1). In detail, the following attributes are supported:
112+
113+
| Name | Type | Remarks |
114+
| ----------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115+
| id | UUID | Read-only, this is the identity ID. |
116+
| externalId | string | Optional, an ID set by the SCIM client. |
117+
| userName | string | Required, unique identifier for the user. Typically used as the login identifier. |
118+
| name | object | Contains sub-attributes `formatted`, `familyName`, `givenName`, `middleName`, `honorificPrefix`, and `honorificSuffix`. |
119+
| displayName | string | |
120+
| nickName | string | |
121+
| profileUrl | string | |
122+
| title | string | |
123+
| userType | string | |
124+
| preferredLanguage | string | |
125+
| locale | string | |
126+
| timeZone | string | If set, must be a valid time zone. |
127+
| active | bool | If unset or false, the user will not be able to log in. |
128+
| password | string | If set, the user will be able to log in with this password. The password is never returned in any SCIM response. |
129+
| emails | array | List of email addresses. Each email can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` email can be set. |
130+
| phoneNumbers | array | List of phone numbers. Each number can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` number can be set. |
131+
| ims | array | List of instant messaging accounts. Each account can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` account can be set. |
132+
| photos | array | List of photos. Each photo can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` photo can be set. |
133+
| addresses | array | List of addresses. Each address can have a `formatted` (string), `streetAddress` (string), `locality` (string), `region` (string), `postalCode` (string), `country` (string), and `type` (string). |
134+
| groups | array | Read-only, a list of groups the user is a member of. Each group can have a `value` (string), `display` (string), and `type` (string). To modify, set the `members` property on the `groups` resource. |
135+
| entitlements | array | List of entitlements. Each entitlement can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` entitlement can be set. |
136+
| roles | array | List of roles. Each role can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` role can be set. |
137+
| x509Certificates | array | List of X.509 certificates. Each certificate can have a `value` (string), `display` (string), `primary` (boolean), and `type` (string). At most one `primary=true` certificate can be set. |
138+
139+
### SCIM group resource schema
140+
141+
Ory Network fully supports the standard SCIM group resource schema as defined in the
142+
[SCIM RFC](https://datatracker.ietf.org/doc/html/rfc7643#section-4.2). In detail, the following attributes are supported:
143+
144+
| Name | Type | Remarks |
145+
| ----------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
146+
| id | UUID | Read-only, this is the group ID. |
147+
| externalId | string | Optional, an ID set by the SCIM client. If set, this ID must be unique in the context of the organization. |
148+
| displayName | string | Required, the name of the group. |
149+
| members | array | List of members. Each member can have a `value` (string), `display` (string), and `type` (string). `value` is either an identity ID (when `type` equals `"User"`) or a group ID (when `type` equals `"Group"`). |
150+
151+
### Group memberships
152+
153+
The SCIM server supports group memberships. To update group memberships, use the `members` property on the `Groups` resource.
154+
Groups also support nested sub-groups. However, in the user resource, only the direct group memberships are included.
155+
156+
## Events
157+
158+
Ory Network emits events for all SCIM operations that modify data. These events allow you to track and respond to changes in your
159+
identity ecosystem.
160+
161+
| SCIM Action | Events Emitted | Description |
162+
| --------------------- | ------------------------------ | ------------------------------------------------------------------------ |
163+
| `POST /Users` | IdentityCreated | Emitted when a new identity is provisioned |
164+
| `PUT /Users/{id}` | IdentityUpdated | Emitted when an identity is updated |
165+
| `PATCH /Users/{id}` | IdentityUpdated | Emitted when an identity is partially updated |
166+
| `DELETE /Users/{id}` | IdentityDeleted | Emitted when an identity is deleted |
167+
| `POST /Groups` | GroupCreated | Emitted when a new group is created |
168+
| `PUT /Groups/{id}` | GroupUpdated + IdentityUpdated | Emitted when a group is updated, for the group and all members |
169+
| `PATCH /Groups/{id}` | GroupUpdated + IdentityUpdated | Emitted when a group is partially updated, for the group and all members |
170+
| `DELETE /Groups/{id}` | GroupDeleted + IdentityUpdated | Emitted when a group is deleted, for the group and all members |
171+
172+
### Event attributes
173+
174+
| Event Type | Attribute | Description |
175+
| -------------------------------- | ---------------- | ---------------------------------------------------------------- |
176+
| All events | `ScimClient` | Contains the ID of the SCIM client that made the request |
177+
| IdentityCreated, IdentityUpdated | `IdentityActive` | Boolean indicating if the identity is active (`true` or `false`) |
178+
179+
These events provide visibility into all SCIM-related changes and can be used for auditing, automation, or integration with other
180+
systems in your organization.
181+
182+
## Known limitations
183+
184+
- When querying users with `GET /Users`, the SCIM server only supports the `eq` operator for filtering, and only with the
94185
`userName` attribute. Other operators like `ne`, `co`, `sw`, and `ew` are not supported.
95-
- For querying groups with `GET /Groups`, the SCIM server only supports the `eq` operator for filtering, and only with the
186+
- When querying groups with `GET /Groups`, the SCIM server only supports the `eq` operator for filtering, and only with the
96187
`displayName` attribute. Other operators like `ne`, `co`, `sw`, and `ew` are not supported.
97188
- For both user and group query endpoints, `startIndex` must be lower than 5000, and `count` must be lower than 1000.
98-
- If the user already exists within the project or organization the provisioning may fail with a 409 conflict error. This is
189+
- If the user already exists within the project or organization, the provisioning may fail with a 409 conflict error. This is
99190
because the SCIM server cannot modify existing users that have not been provisioned via SCIM. In this case, you need to manually
100191
delete the user first.

docs/kratos/reference/jsonnet.mdx

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,84 @@
11
---
22
id: jsonnet
3-
title: Data Mapping with Jsonnet
3+
title: Data mapping with Jsonnet
44
---
55

6-
Some modules like the [OpenID Connect and OAuth2 Method](../social-signin/overview) support [Jsonnet](https://jsonnet.org),
7-
allowing you to write code that modifies your identity's data and load it into Ory Kratos.
6+
Some modules, like the [OpenID Connect and OAuth2 Method](../social-signin/overview), support [Jsonnet](https://jsonnet.org),
7+
allowing you to write code that modifies your identity's data and loads it into Ory Kratos.
88

9-
We highly recommend checking out the official [learning Jsonnet tutorial](https://jsonnet.org/learning/tutorial.html).
9+
We highly recommend checking out the official [Learning Jsonnet Tutorial](https://jsonnet.org/learning/tutorial.html).
1010

11-
## Formatting Jsonnet Code
11+
## Input and output
12+
13+
Jsonnet is a data-templating language that allows you to define identity traits and metadata based on input data from external
14+
sources.
15+
16+
### Input
17+
18+
The input for Jsonnet is typically provided as an external variable using `std.extVar`. For example:
19+
20+
- For OpenID Connect (OIDC), the input is available in `std.extVar('claims')`.
21+
- For SCIM, the input is available in `std.extVar('scim')`.
22+
23+
The specific structure of the input object depends on the data provided by the OIDC claims or SCIM payload.
24+
25+
In your Jsonnet script, assign the input to a local variable:
26+
27+
```jsonnet
28+
local claims = std.extVar('claims'); // For OIDC
29+
// or
30+
local scim = std.extVar('scim'); // For SCIM
31+
```
32+
33+
### Output
34+
35+
The output of the Jsonnet code must conform to the following structure:
36+
37+
```jsonnet
38+
{
39+
identity: {
40+
traits: {}, // Custom traits for the identity
41+
metadata_public: {}, // Public metadata visible to the user
42+
metadata_admin: {}, // Admin metadata visible only to administrators
43+
verified_addresses: [{ // Addresses listed here will be marked as verified
44+
value: string, // Verified address value (e.g., the email address)
45+
via: "email" // Verification method (e.g., "email")
46+
}]
47+
}
48+
}
49+
```
50+
51+
## Formatting Jsonnet code
1252

1353
Format Jsonnet code snippets using:
1454

1555
```sh
1656
kratos help jsonnet format
1757

18-
# for example:
58+
# For example:
1959
kratos jsonnet format --write path/to/files/*.jsonnet
2060
```
2161

22-
## Linting Jsonnet Code
62+
## Linting Jsonnet code
2363

2464
Lint Jsonnet code snippets using:
2565

2666
```sh
2767
kratos help jsonnet lint
2868

29-
# for example:
69+
# For example:
3070
kratos jsonnet lint path/to/files/*.jsonnet
3171
```
3272

33-
The command will exit with an exit code of `1` and print all found lint errors to stderr if the code snippet has lint issues.
73+
The command will exit with an exit code of `1` and print all found lint errors to stderr if the code snippet contains lint issues.
3474

35-
## Tips & Tricks
75+
## Tips & tricks
3676

3777
The purpose of this section is to provide you with examples for common use cases.
3878

3979
### Optionality
4080

41-
When you're unsure that a field will be set in the `claims` variable use the following to make the trait field also optional:
81+
When you're unsure whether a field will be set in the `claims` variable, use the following to make the trait field optional:
4282

4383
```jsonnet
4484
local claims = std.extVar('claims');
@@ -59,7 +99,7 @@ Set defaults for the `claims` variable:
5999

60100
```jsonnet
61101
local claims = {
62-
website: 'i am the default website value'
102+
website: 'I am the default website value'
63103
} + std.extVar('claims');
64104
65105
{
@@ -71,10 +111,10 @@ local claims = {
71111
}
72112
```
73113

74-
### Raising Errors
114+
### Raising errors
75115

76116
You can raise errors in the Jsonnet code. Keep in mind that these will be shown as system errors, not validation errors, and that
77-
the user will end up at the Error UI!
117+
the user will end up on the Error UI!
78118

79119
```jsonnet
80120
local claims = std.extVar('claims');

0 commit comments

Comments
 (0)