Add and Remove operations not working as expected for PATCH /v3/auth-users

Hi,

Looking at patch-auth-user | SailPoint Developer Community I would expect that:

  • op:add would add the capabilities specified in the value part of the body
  • op:remove would remove the capabilities specified in the value part of the body

I turns out

  • op:add replaces all the existing capabilities (user levels) with the value part of the body
  • op:remove removes all capabilities (user levels) from the user, irrespective of what is in the value part of the body

Is this a bug in the API, or am I just bad at understanding Op values?

Example: The following returns HTTP 200, and removes any capabilites that were there before:

[
  {
    "op": "remove",
    "path": "/capabilities",
    "value": ["this can be anything"]
  }
]

Hi Jason,
If you take a look on RFC

you will see the following

4.1.  add

   The "add" operation performs one of the following functions,
   depending upon what the target location references:

   o  If the target location specifies an array index, a new value is
      inserted into the array at the specified index.

   o  If the target location specifies an object member that does not
      already exist, a new member is added to the object.
o  If the target location specifies an object member that does exist,
      that member's value is replaced.

   The operation object MUST contain a "value" member whose content
   specifies the value to be added.

   For example:

   { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }

   When the operation is applied, the target location MUST reference one
   of:

   o  The root of the target document - whereupon the specified value
      becomes the entire content of the target document.

   o  A member to add to an existing object - whereupon the supplied
      value is added to that object at the indicated location.  If the
      member already exists, it is replaced by the specified value.

   o  An element to add to an existing array - whereupon the supplied
      value is added to the array at the indicated location.  Any
      elements at or above the specified index are shifted one position
      to the right.  The specified index MUST NOT be greater than the
      number of elements in the array.  If the "-" character is used to
      index the end of the array (see [RFC6901]), this has the effect of
      appending the value to the array.

   Because this operation is designed to add to existing objects and
   arrays, its target location will often not exist.  Although the
   pointer's error handling algorithm will thus be invoked, this
   specification defines the error handling behavior for "add" pointers
   to ignore that error and add the value as specified.

   However, the object itself or an array containing it does need to
   exist, and it remains an error for that not to be the case.  For
   example, an "add" with a target location of "/a/b" starting with this
   document:

   { "a": { "foo": 1 } }

   is not an error, because "a" exists, and "b" will be added to its
   value.  It is an error in this document:

   { "q": { "bar": 2 } }

   because "a" does not exist.

and here is similar for remove

4.2.  remove

   The "remove" operation removes the value at the target location.

   The target location MUST exist for the operation to be successful.

   For example:

   { "op": "remove", "path": "/a/b/c" }

   If removing an element from an array, any elements above the
   specified index are shifted one position to the left.

We have a PATCH guide for our APIs. Add and remove are tricky, so I highly encourage you to read the guide for both operations very carefully.

add operation guide

remove operation guide

The TLDR is that to add an item to an array, you must provide the array index in the path. For example, the below payload will add the HELPDESK capability at the beginning of the capabilities array.

[
  {
    "op": "add",
    "path": "/capabilities/0",
    "value": "HELPDESK"
  }
]

Remove works similarly. You must provide the index of the item you want to remove.

[
  {
    "op": "remove",
    "path": "/capabilities/0"
  }
]

If you don’t provide the index in the path, then add will operate like a replace operation, and remove will just remove everything.

You can also see this post for more information about adding and removing capabilities using the auth users API.

1 Like