Skip to content
Last updated

SCIM Patch Operations

SCIM Patch Operations aggregate a collection of operations on a target resource.

SCIM Patching is described in RFC7644 Section 3.5.2.

This guide covers basics and common use cases related to our Firstup users and user groups.

Overview

In context of the Firstup API, a SCIM patch is a way of editing a Firstup platform user or a Firstup user group. These users and user groups are created using SCIM, therefore editing them requires certain operations.

Operation

An operation is a way of adding, changing, replacing or removing data in a user's record or a user group, e.g. change a user's last name.

To perform an operation, you send it as an object in a PATCH endpoint request connected to the relevant user or user group ID.

Patch endpoint examples:

An operation object has three properties:

PropertyDescription
opThe type of operation being performed: add, replace, remove.
pathThe data that needs changing from the operation (e.g. title)
valueWhat you want the data to be changed to (e.g. mrs)

Based on our example of replacing an existing user's title from Miss to Mrs, your patch operation request looks like:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "title",
      "value": "Mrs"
    }
  ]
}

Note: This example shows how to replacing a simple string (root-level property). Continue to read for information on replacing or adding objects, lists and lists of objects.

Targeting Properties

Unlike the above example, not all properties are at the root level.

const examplePaths = [
  { "path": "title" },                             // Root-level property
  { "path": "name:familyName" },                   // Nested property
  { "path": "urn:SocialChorus:1.0:User:managerName" }, // User extension property
]

Patching Strings

To add, replace or remove a string attribute, you must need to include an op, a path and a value.

Replacing Strings

A user's nickname is a string attribute that does not belong to a list or object. To change this:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "nickName",
      "value": "Barry"
    }
  ]
}

Adding strings

To add a nickname to an existing user, change the op to add:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "nickName",
      "value": "Barry"
    }
  ]
}

Remove Strings

To remove a nickname from an existing user, change the op to remove and don't send a value:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "remove",
      "path": "nickName",
    }
  ]
}

Strings Use Case

Patching Lists

Targeting an attribute within a list (array) requires a filter:

  • The list (array) attribute name comes first "listExample"
  • The list attributes are then shown inside square brackets "ListExample": ["item1", "item2"]
  • The SCIM filter expressed supported is equals to, which means you type in the exact value you need. Example, eq \"valuehere\" - the eq is equals to, valuehere is where you type in your required value.

Complex lists will then have a list of objects, like the addresses array. Objects appear in curly brackets {objectExample}

Replacing a List Attribute

Adding the filter after the list property name targets the list attribute.

For example, replacing a misspelled street address within a user's full address. The list is addresses but the stretAddress is a propery within this list.

Address list example:

  "addresses": [
    {
      "streetAddress": "123 Kission St",
      "locality": "San Francisco",
      "region": "CA",
      "postalCode": "94105",
      "country": "US",
      "primary": false,
      "formatted": "123 Mission St, San Francisco, CA, 94105",
      "type": "work"
    }
  ]

To only replace the streetAddress property your patch looks like:

{
  "op": "replace",
  "path": "address[streetAddress eq \"123 Kission St\"].streetAddress",
  "value": "123 Mission St"
}

The OP (operation) is to change the path (the current data) to the entered value by yourself (the new data - here 123 Mission St).

SCIM does not support position-based operations, meaning we can't target the "first" address, or re-order addresses from within SCIM itself. Those types of operations would need to be handled on the client side followed by a value replacement.

Removing List Attributes

To remove a list attribute, change the op from replace to remove and don't include any value:

{
  "op": "remove",
  "path": "address[streetAddress eq \"123 Mission St\"].streetAddress"
}

Adding List Attributes

To add a list to an existing user or user group, your op is add, your path is the blank data field that exists in the user or user group schema (e.g. members), and your value is your list (e.g. a list of members you want adding).

For example, you want to add users to an existing user group:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "members",
      "value": [
        {
          "value": "user1"
        },
        {
          "value": "user2"
        },
        {
          "value": "user3"
        },
        {
          "value": "user4"
        },
        {
          "value": "user5"
        }
      ]
    }
  ]
}

List Use Case

Patching Objects

For properties within objects (nested property), SCIM Paths use a colon as a path separator.

This means if you have an item in an object you wish to change, add in a colon between the object name and the attribute within.

  • The object (nested) attribute name comes first "objectExample"
  • The nested object attributes are then shown inside curly brackets "objectExample": {"item1", "item2"}

Replacing an Object Attribute

To change a user's last name, you need to change the familyName property within the name object:

  "name": {
    "givenName": "Jane",
    "familyName": "Doe"
  },

This example means your path needs to include both the name and familyName attributes. This looks like:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "name:familyName",
      "value": "NewLastName"
    }
  ]
}

Removing an Object Attribute

To remove an object attribute, using the same example, change the op from replace to remove and don't send a value:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "remove",
      "path": "name:familyName"
    }
  ]
}

Adding an Object

Adding an object requires you to add in the object as the path, and then list out any attributes in the value. For example:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "emails",
      "value": [
        {
          "value": "janedoe@email.com",
          "primary": true,
          "type": "work"
        }
      ]
    }
  ]
}

Object Use Case

Pathless Targeting

Including a path property is optional when replacing properties.

If the optional path property is omitted it is assumed the target is the entire resource, e.g., a SCIM User or Group.

In this case the value property's own property names will align with the resource.

For example, replace a user's userName with a path:

{
  "op": "replace", 
  "path": "displayName", 
  "value": "User McUser"
}

Or without a path:

{ 
  "op": "replace",
  "value": {
    "displayName":  "User McUser"
  }
}

Note: Pathless replace replaces the entire object. It is not a merge. Remove operations require a path. Removes are value-less operations.

Use Cases

Here a list of use cases where we're using a patch operation to change specific user details: