Issue with SCIM 2.0 PATCH

Which IIQ version are you inquiring about?

8.4p2

Share all details about your problem, including any error messages you may have received.

Hi all,

We are currently trying to provision user emails via IIQ SCIM 2.0 connector. Here’s the scenario we observed:

  • When we create a user, the email is successfully added to the identity link. This works because IIQ uses POST and includes the full emails object from the provisioning policy (emails.primary.work.value).
  • However, when we update the email via “Update Identity”, the email attribute disappears from the link and becomes empty.

Problem:

  • During PATCH, IIQ only sends the email value.
  • The SCIM server requires the type and primary attributes as part of the emails object. Since these are missing in the PATCH, the email is removed or ignored.

Attempted Workarounds:

  • We tried using a Before Provisioning Rule to update the JSON object and inject the full emails array before PATCH, but it was not successful.

Questions / Alternatives:

  1. Is there another reliable way to ensure IIQ sends the complete emails object (value, type, primary) in PATCH?
  2. Should we inform the customer to make type and primary optional or not required on the SCIM server to avoid this issue?

Any advice, best practices, or alternative solutions would be highly appreciated.

@Tarek_ICC_AT I have not faced this issue. I have debug on this issue. My observation is

IdentityIQ sends partial email data during updates, but the SCIM server expects the full email object, so the update fails.

Hi Nandana, Thank you for checking. This is exactly what I described below, IdentityIQ sends partial email data, but the SCIM server expects the full email object, which causes the failure:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "emails",
      "value": [
        {
          "value": "new.email@example.com",
         
        }
      ]
    }
  ]
}

PATCH operation should usually support updating the attributes alone, without dependency on other attributes.

It is worth to check with vendor if the type and primary attributes need to be mandatory for a PATCH use case.

I could relate with similar problem that we had, which made us re-configure the connector as WebService connector by specifying the SCIM API for each operation. That would definitely mean additional initial development effort, but most of the SCIM operations should be straight forward. In our case we added the additional attribute dependencies by modifying the requestBody of update operation in a Webservice before operation rule.

2 Likes

Hi @uday_kilambi ,

Thank you for your answer.

We wanted to go with a web service connector, but the customer wants all connectors to be SCIM, not web services.

The reason I am asking here is to check whether there is a possibility similar to web services, where we can use a Before Operation rule in the SCIM connector. I tried to update the JSON object in the Before Provisioning rule, but it is not possible.

The second option would be to ask the customer to update the attribute configuration and make the attributes type and primary not required.

Hi @Tarek_ICC_AT

I can relate with that, SCIM connector is preferred due to its low-code approach. But, it doesn’t support modification of the request body before its execution (like the before operation rule).

Adding the additional attributes to the plan in Before provisioning doesn’t help here if the other values are already on the account, as they would get filtered eventually.

However, I believe you can achieve it with the below approach. Please consider my assumptions before considering the approach.

Assumption:

  1. Type and Primary are declared as part of account schema
  2. Existing values of Type and Primary are populated as part of account aggregation
  3. No changes are expected to be updated for Type and Primary attributes, rather they are always constant that needs to be populated during email update.

Steps for alternative try:

  1. Update the Type and Primary attributes to null/empty using a customization rule for all the accounts as part of account aggregation. This way the links/accounts in SailPoint would never have a value in these attributes.
  2. Your before provisioning plan should work now. You can add these additional attributes to the plan whenever you detect a change in email or (lets say during account creation as well). This time the values doesn’t get filtered out as they are not same as their previous values are null/empty on the account in SailPoint

Hi @uday_kilambi ,

thanks again for your approach.

I tried your solution, but after updating the email via Identity Update , the email attribute disappears from the application link . In Postman, I can also see that the emails[] array in the PATCH request is empty.

Here is what I have done so far:

  1. Added the two attributes emails.primary and emails.type to the account schema .
  2. Added these attributes to the Create Provisioning Policy .
  3. Implemented the Account Aggregation Customization Rule (see the code below)
  4. Added a Before Provisioning Rule to populate emails.value , emails.type , and emails.primary .(see the code below)

After updating the email:

  • I can see that emails.type and emails.primary have new values in the IdentityRequest .
  • However, the email is not updated in the application link , and the emails attribute is completely missing from the link.
  • In the SCIM request (verified via Postman), the emails[] in json object is sent as empty.

It seems that although the attributes are present in the IdentityRequest, they are still being filtered out during provisioning, which results in the email being removed instead of updated.

Could you please advise what might be missing here, or if there is another recommended way to ensure the full emails object (value, type, primary) is preserved during PATCH?

Code BeforeProvisoningRule:

import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.tools.Util;
import java.util.*;

if (plan != null) {

    List accountRequests = plan.getAccountRequests();

    if (!Util.isEmpty(accountRequests)) {

        for (Object arObj : accountRequests) {

            AccountRequest ar = (AccountRequest) arObj;

            // Only for CREATE or MODIFY
            if (AccountRequest.Operation.Create.equals(ar.getOperation()) ||
                AccountRequest.Operation.Modify.equals(ar.getOperation())) {

                // Add or override attributes
                ar.add(new AttributeRequest(
                    "emails.primary",
                    ProvisioningPlan.Operation.Set,
                    "true"
                ));

                ar.add(new AttributeRequest(
                    "emails.type",
                    ProvisioningPlan.Operation.Set,
                    "work"
                ));
            }
        }
    }
}

return plan;

code customizationRule

import java.util.*;
import sailpoint.object.Attributes;

List accounts = (List) object.getAttribute("account");

if (accounts != null) {

    for (Object acctObj : accounts) {

        Attributes account = (Attributes) acctObj;

        account.put("emails.primary", null);
        account.put("emails.type", null);
    }
}

return object;

Thanks in advance for your help.

Hi @Tarek_ICC_AT

The SCIM connector doesn’t give you a “before operation” hook to rewrite the PATCH body, so a BeforeProvisioning rule usually won’t help if the connector normalizes/filters the request.

First thing: double-check the schema attribute names. For “work + primary email”, SailPoint-style SCIM mappings typically use names like emails.work.primary.value (not emails.primary / emails.type).

If the SCIM server requires type + primary to be resent on every PATCH, that’s non-friendly SCIM behavior. A common PATCH pattern is updating the sub-attribute via a filtered path (ex: emails[type eq “work”].value) so the server keeps type/primary.

If the target server can’t be changed, the practical fix is using Web Services/custom for updates (so you can send the full emails object), even if creation stays on SCIM.

1 Like

I agree with @amrdodani , emails.work.primary.value is what you should be using , that is what we use to update emails on sync attributes refresh and it does not clear other emails object attributes. Also if target app is not SCIM friendly then you have to do it via something custom like web services connector.

1 Like

Hi @Tarek_ICC_AT <

As mentioned by @amrdodani , you should declare the schema attributes with the right pattern. However, as stated earlier, please note this is an alternative approach to try and make it work with the existing SCIM connector, it is always best to use for a Webservice connector to leverage the OOTB connector rules.

1 Like

Hi @amrdodani ,

thanks for your answer.

Yes, if you check my answer above, I used the attribute emails.primary.work.value in my Create Provisioning Policy.
The problem is that the target application is not fully SCIM-compliant. When IIQ sends a PATCH request to change only emails.primary.work.value, the target application requires both type and primary to be present in the emails object, because the JSON structure of emails looks like this:

  "emails": [
                {
                    "primary": true,
                    "type": "work",
                    "value": "danijel.micic@btc-ag.ch"
                }

That’s why I was looking for a workaround to make it work. However, the issue is on the target application side, because type and primary are mandatory attributes. Therefore, it’s better to use a Web Service connector, as you and the other experts suggested.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.