---
title: 'SCIM Endpoint'
url: 'https://docs.brix.ch/celum_extensions/scim_endpoint'
markdown: 'https://docs.brix.ch/celum_extensions/scim_endpoint.md'
lang: en
date: '2026-10-26'
description: 'Technical documentation for the CELUM Extension "SCIM Endpoint" – Software developed by brix'
taxonomy:
  category:
    - docs
---

[](#) 

  [ Welcome ](https://docs.brix.ch/)     [ CELUM Extensions ](https://docs.brix.ch/celum_extensions)      SCIM Endpoint    

# SCIM Endpoint

![Advanced-UI](https://img.shields.io/static/v1?label=UI&message=Advanced&color=lightgrey)

The SCIM Endpoint plugin is an API for managing users and the groups in CELUM. The plugin implements version 2.0 of the SCIM protocol.

- [System for Cross-domain Identity Management: Core Schema](https://tools.ietf.org/html/rfc7643)
- [System for Cross-domain Identity Management: Protocol](https://tools.ietf.org/html/rfc7644)

> > > This plugin is in sunsetting mode, as local user management will get deprecated with 7.1 (aka 26.7)

#### Table of Contents

- [Properties](#properties)
    - - - [scimEndpoint.license](#scimendpoint-license)
            - [scimEndpoint.tokenVerifier](#scimendpoint-tokenverifie)
            - [scimEndpoint.staticToken](#scimendpoint-statictoken)
            - [scimEndpoint.jwtSecretKey](#scimendpoint-jwtsecretkey)
            - [scimEndpoint.delete](#scimendpoint-delete)
            - [scimEndpoint.notVisibleUser](#scimendpoint-notvisibleus)
            - [scimEndpoint.notDeletableUser](#scimendpoint-notdeletable)
            - [scimEndpoint.userKindDefault](#scimendpoint-userkinddefa)
            - [scimEndpoint.notVisibleGroup](#scimendpoint-notvisiblegr)
            - [scimEndpoint.notDeletableGroup](#scimendpoint-notdeletable-1)
- [Request Header](#request-header)
- [SCIM Resource Endpoints](#scim-resource-endpoints)
    - [Service Provider Configuration Endpoints](#service-provider-configur)
    - [User](#user)
        - [User attributes](#user-attributes)
        - [Example for GET](#example-for-get)
        - [Example for POST (create new user)](#example-for-post-create-n)
    - [Group](#group)
        - [Group attributes](#group-attributes)
        - [Example for GET (full usergroup representation)](#example-for-get-full-user)
        - [Example for POST (create new usergroup)](#example-for-post-create-n-1)
    - [Further Endpoints](#further-endpoints)
- [Implementations](#implementations)
    - [Azure](#azure)
        - [User Mapping](#user-mapping)
        - [Group Mapping](#group-mapping)
        - [Known Limitations](#known-limitations)
- [Compatibility Matrix](#compatibility-matrix)
- [Release Notes](#release-notes)
    - - [1.0.0](#1-0-0)
        - [1.0.3](#1-0-3)
        - [1.2](#1-2)
        - [1.3](#1-3)

## Properties

To be configured in {home}/appserver/conf/custom.properties

##### scimEndpoint.license

> type: String, **required: yes**, default: -

The license key for the plugin (product: scimEndpoint), provided by brix.

##### scimEndpoint.tokenVerifier

> type: bean name, **required: yes**, default: -

Determines which Authentication method is applied (scimStaticTokenVerifier or scimJsonWebTokenVerifier).

##### scimEndpoint.staticToken

> type: String, **required: yes (if applied)**, default: -

Simple static token for scimStaticTokenVerifier.

##### scimEndpoint.jwtSecretKey

> type: String, **required: yes (if applied)**, default: -

The secret key for scimJsonWebTokenVerifier (at least 256 bits!)

##### scimEndpoint.delete

> type: boolean, required: no, default: false

Determines whether a user is deleted or deactivated in case of a DELETE request.

##### scimEndpoint.notVisibleUser

> type: List of long (comma-separated), required: no, default: -

A list of users who will be excluded from CRUD operations.

##### scimEndpoint.notDeletableUser

> type: List of long (comma-separated), required: no, default: -

A list of users who are not deletable.

##### scimEndpoint.userKindDefault

> type: String, required: no, default: readonly

Sets the userKind if no userType is transmitted.

##### scimEndpoint.notVisibleGroup

> type: List of long (comma-separated), required: no, default: -

A list of groups who will be excluded from CRUD operations.

##### scimEndpoint.notDeletableGroup

> type: List of long (comma-separated), required: no, default: -

A list of groups who are not deletable.

## Request Header

To access the SCIM API a **Bearer Token** is required. The API token must be included via an Authentication/Authorization header\*\* with a type of Bearer when calling any of the SCIM methods. Alternatively, a static token can be provided in the token parameter.

The http **Content-Type** header has to be set to **application/scim+json**.

## SCIM Resource Endpoints

The base URL for all calls to the SCIM API is https://example.com/scim/v2. All SCIM methods are branches of this base URL.

The following Endpoints are available:

### Service Provider Configuration Endpoints

**GET /ServiceProviderConfig**

- Returns the SCIM specification features.

**GET /ResourceTypes**

- Returns the types of resources available.

**GET /Schemas**

- Returns information about resource schemas.

### User

**GET POST PUT PATCH DELETE /Users**

- For GET requests a standard set of query parameters is available ( see [Query Resources](https://tools.ietf.org/html/rfc7644#section-3.4.2)). 
    - Since the ID is of type string, sorting to this attribute is limited.
- Since Celum does not have a lastModified date for users, the created date is returned in meta.lastModified.

#### User attributes

The following table maps SCIM attributes to CELUM User attributes.

| CELUM | SCIM | Remarks |
|---|---|---|
| ID | id | required |
| External ID | externalId |  |
| Username | userName | required |
| Password | password |  |
| Last name | name.familyName |  |
| First name | name.givenName |  |
| Middle name | name.middleName |  |
| Deactivated | active | Default value for POST is active. |
| Userkind | userType | Valid values are readonly, editor or readwrite. Defaul value is readonly and can be configured. |
| E-mail | emails\[value\]\[primary\]\[type=work\] |  |
| Phone | phoneNumbers\[value\]\[type=work\] | type is required |
| Mobile | phoneNumbers\[value\]\[type=mobile\] | type is required |
| Fax | phoneNumbers\[value\]\[type=fax\] | type is required |
| Street | addresses\[streetAddress\]\[primary\]\[type=work\] |  |
| Zip | addresses\[postalCode\]\[primary\]\[type=work\] |  |
| City | addresses\[locality\]\[primary\]\[type=work\] |  |
| Country | addresses\[country\]\[primary\]\[type=work\] |  |
| User Groups | groups | Group membership changes MUST be applied via the "Group" Resource |
| Created | meta.created |  |

GET /Schemas/urn:ietf:params:scim:schemas:core:2.0:User returns all user attributes and their characteristics that describe their type and handling.

All attributes must be transmitted in a PUT request. Not required attributes that are missing or empty are usually deleted in Celum. Exceptions:

- Password: will not be deleted
- Deactivated and Userkind: no changes

If multiple emails/addresses are transmitted, one must be marked as primary. Otherwise, no one will be stored in Celum in a POST request and no updated is done in a PUT request.

#### Example for GET

**Full User Representation**

```json
{
  "id": "170",
  "externalId": "externalID",
  "userName": "Test_User_1",
  "name": {
    "familyName": "Mustermann",
    "givenName": "Max",
    "middleName": "D."
  },
  "active": true,
  "emails": [
    {
      "value": "m.mustermann@email.ch",
      "type": "work"
    }
  ],
  "phoneNumbers": [
    {
      "value": "061 266 66 66",
      "type": "work"
    },
    {
      "value": "079 266 66 66",
      "type": "mobile"
    },
    {
      "value": "061 266 66 11",
      "type": "fax"
    }
  ],
  "addresses": [
    {
      "streetAddress": "Musterstrasse 1",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz",
      "type": "work"
    }
  ],
  "groups": [
    {
      "value": "149",
      "$ref": "http://localhost:8881/scim/v2/Groups/149",
      "display": "Admin_Group",
      "type": "Group"
    },
    {
      "value": "7",
      "$ref": "http://localhost:8881/scim/v2/Groups/7",
      "display": "Marketing",
      "type": "Group"
    },
    {
      "value": "126",
      "$ref": "http://localhost:8881/scim/v2/Groups/126",
      "display": "Test_Group_1",
      "type": "Group"
    }
  ],
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "meta": {
    "resourceType": "User",
    "created": "2021-04-14T13:45:31.787Z",
    "lastModified": "2021-04-14T13:45:31.787Z",
    "location": "http://localhost:8881/scim/v2/Users/170"
  }
}
```

#### Example for POST (create new user)

**Full User Representation**

```json
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "externalId": "externalID",
  "userName": "Test_User_1",
  "password": "123456789A!",
  "name": {
    "familyName": "Mustermann",
    "givenName": "Max",
    "middleName": "D."
  },
  "active": true,
  "userType": "editor",
  "emails": [
    {
      "value": "m.mustermann@email.ch",
      "primary": true
    },
    {
      "value": "m.muster@email.ch"
    }
  ],
  "phoneNumbers": [
    {
      "value": "061 266 66 66",
      "type": "work"
    },
    {
      "value": "061 266 66 11",
      "type": "fax"
    },
    {
      "value": "079 266 66 66",
      "type": "mobile"
    }
  ],
  "addresses": [
    {
      "streetAddress": "Musterstrasse 1",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz",
      "primary": true
    },
    {
      "streetAddress": "Musterstrasse 2",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz"
    }
  ]
}
```

**Minimal User Representation**

```json
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "userName": "Test_User_1",
  "name": {
    "familyName": "Mustermann"
  }
}
```

### Group

**GET POST PUT PATCH DELETE /Groups**

- For GET requests a standard set of query parameters is available ( see [Query Resources](https://tools.ietf.org/html/rfc7644#section-3.4.2)). 
    - Since the ID is of type string, sorting to this attribute is limited.
- Since Celum does not have a created or lastModified date for groups, "1970-01-01T00:00:00.000Z" is returned in meta.created and meta.lastModified.

#### Group attributes

The following table maps SCIM attributes to CELUM Usergroup attributes.

| CELUM | SCIM | Remarks |
|---|---|---|
| ID | id | reqiured |
| External ID | externalId |  |
| Name | displayName | required |
| ID | members\[value\] |  |
| Username/Name | members\[display\] |  |
| Discriminator | members\[type\] |  |

GET /Schemas/urn:ietf:params:scim:schemas:core:2.0:Group returns all group attributes and their characteristics that describe their type and handling.

#### Example for GET (full usergroup representation)

```json
{
  "id": "186",
  "externalId": "externalID",
  "displayName": "Test_Group_2",
  "members": [
    {
      "value": "40",
      "$ref": "http://localhost:8881/scim/v2/Users/40",
      "display": "editor2",
      "type": "User"
    },
    {
      "value": "43",
      "$ref": "http://localhost:8881/scim/v2/Users/43",
      "display": "editor3",
      "type": "User"
    },
    {
      "value": "44",
      "$ref": "http://localhost:8881/scim/v2/Users/44",
      "display": "readonly3",
      "type": "User"
    },
    {
      "value": "8",
      "$ref": "http://localhost:8881/scim/v2/Groups/8",
      "display": "World",
      "type": "Group"
    }
  ],
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "meta": {
    "resourceType": "Group",
    "created": "1970-01-01T00:00:00.000Z",
    "lastModified": "1970-01-01T00:00:00.000Z",
    "location": "http://localhost:8881/scim/v2/Groups/186"
  }
}
```

#### Example for POST (create new usergroup)

**Full Usergroup Representation**

```json
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "externalId": "externalID",
  "displayName": "Test_Group_2",
  "members": [
    {
      "value": "40",
      "type": "User"
    },
    {
      "value": "42",
      "type": "User"
    },
    {
      "value": "7",
      "type": "Group"
    }
  ]
}
```

**Minimal Usergroup Representation**

```json
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "displayName": "Test_Group_3"
}
```

### Further Endpoints

**POST /Bulk**

- The SCIM bulk operation enables clients to send a potentially large collection of resource operations in a single request.

**POST \[prefix\]/.search**

- Clients MAY execute queries without passing parameters on the URL by using the HTTP POST verb combined with the " /.search" path extension.

## Implementations

### Azure

> > > The information and implementation details provided here are for guidance only and come without any guarantee. Please note that we do not offer support for Azure.

1. Create an Enterprise Application: *Azure Active Directory --> Enterprise applications --> Create your own application --> Non-gallery*
2. Set Admin Credentials: *Application --> Provisioning --> Update credentials --> Admin Credentials*
    - Provisioning Mode = Automatic
    - Tenant URL (https://example.com/scim/v2)
    - Secret Token (provided by brix)
3. Adapt mappings: *Application --> Provisioning --> Edit attribute mappings --> Mappings*
    - See mapping tables below
    - Configure the settings as needed
    - Change customappsso attributes: *Show advanced options --> Edit attribute list for customappsso* (*optional*)
    - Change mappings (*optional*)
    - Delete all unused customappsso attributes and mappings (*optional*).

> > > The mapping must be deleted before you can edit/delete the customappsso attributes.

4. Set Scope (*optional*): *Application --> Provisioning --> Add scoping filters --> Settings --> Scope*
    - Sync only assigned users and groups
5. Assign users/groups (*optional*): *Application --> Users and groups --> Add user/groups* (groups only available in enterprise/premium azure)

#### User Mapping

| Azure Active Directory Attribute | customappsso Attribute | Type | Remarks |
|---|---|---|---|
| - | id | String | primary key, required |
| userPrincipalName | userName | String | required |
| Switch(\[IsSoftDeleted\], , "False", "True", "True", "False") | active | Boolean |  |
| mail | emails\[type eq "work"\].value | String |  |
| givenName | name.givenName | String |  |
| surname | name.familyName | String |  |
| streetAddress | addresses\[type eq "work"\].streetAddress | String |  |
| city | addresses\[type eq "work"\].locality | String |  |
| telephoneNumber | phoneNumbers\[type eq "work"\].value | String |  |
| mobile | phoneNumbers\[type eq "mobile"\].value | String |  |
| facsimileTelephoneNumber | phoneNumbers\[type eq "fax"\].value | String |  |
| mailNickname | externalId | String |  |
| postalCode | addresses\[type eq "work"\].postalCode | String |  |
| country | addresses\[type eq "work"\].country | String |  |

#### Group Mapping

No changes need to be made to the default mapping for groups.

| Azure Active Directory Attribute | customappsso Attribute | Type | Remarks |
|---|---|---|---|
| - | id | String | primary key, required |
| objectId | externalId | String |  |
| displayName | displayName | String | required |
| members | members | Reference | urn:ietf:params:scim:schemas:core:2.0:Group   urn:ietf:params:scim:schemas:extension:enterprise:2.0:User |

#### Known Limitations

see [Link](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/application-provisioning-config-problem-scim-compatibility)

**Tenant URL**
Use the flags below in the tenant URL of your application in order to change the default SCIM client behavior. `<base-url>/?aadOptscim062020` (e.g. https://example.com/scim/v2/?aadOptscim062020)

**Null attribute can't be provisioned**
Azure AD currently can't provision null attributes. If an attribute is null on the user object, it will be skipped ([Link](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/known-issues#null-attribute-cant-be-provisioned)).

**Remove user from synced group**
If a user is no longer in a synced group, Azure will not send a DELETE, but only a PATCH with active = false. Thus, the user is only deactivated in Celum ([Link](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/customize-application-attributes#:~:text=The%20attribute%20IsSoftDeleted,your%20attribute%20mappings.))

**Delete user**
When a user is deleted, Azure apparently only softDelets it first. This leads to a PATCH/PUT with active = false ([Link](https://stackoverflow.com/questions/42799936/azuread-scim-integration-not-sending-delete-requests#:~:text=If%20a%20user,DELETE%20the%20user.)). Here you have to delete the user permanently so that Azure sends a DELETE request.

**userName softDeletion**
Azure prefixes the userName with the ObjectID during softDeletion. This can lead to the userName being too long for Celum, which is why the user cannot be deactivated.

## Compatibility Matrix

| SCIM Endpoint | CELUM (min. version) |
|---|---|
| 1.0 - 1.1 | 6.4.0 |
| 1.2 | 6.4 (tested with 6.11) |
| 1.3 | 6.20 |

## Release Notes

#### 1.0.0

> Release: 2021-04-23

Initial Version

#### 1.0.3

> Release: 2022-01-28

- default value for lastName
- changed name.familyName to not required
- changed member.type to not required

#### 1.2

> Release: 2024-03-07

added type 'work' to emails and addresses

#### 1.3

> Released 2025-02-19

Compatibility with CELUM 6.20

 [ ](https://docs.brix.ch/celum_extensions/email_ingest) [](https://docs.brix.ch/celum_extensions/asset_review)

---

## Navigation

- Parent: [CELUM Extensions](https://docs.brix.ch/celum_extensions.md)
- Previous: [Email Ingest](https://docs.brix.ch/celum_extensions/email_ingest.md)
- Next: [Asset Review](https://docs.brix.ch/celum_extensions/asset_review.md)
