Historical-identities/:id/access-items returns duplicate entries

What problem are you observing?

What is the correct behavior?

What product feature is this related to?

ISC UI / API

What are the steps to reproduce the issue?

Do you have any other information about your environment that may help?

No.

I am observing similar behavior. Although the identity I selected doesn’t have any duplicate entitlements, there are three entitlements with a null id, causing the UI to report 19 entitlements but only show 17. My response body is as follows:

[
    {
        "id": "439ede5a1cd342d09a924e696f177f69",
        "accessType": "entitlement",
        "displayName": "User",
        "sourceName": "airtable v4",
        "attribute": "entitlements",
        "value": "user",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "c6dc37bf508149b28ce5b7d90ca4bbf9",
        "standalone": false,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": null,
        "accessType": "entitlement",
        "displayName": "sp:aic-dashboard-write",
        "sourceName": "IdentityNow",
        "attribute": "assignedGroups",
        "value": "sp:aic-dashboard-write",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808475b4334b0175e1dff1b563a4",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c91808475b4334b0175e1dff20463a7",
        "accessType": "entitlement",
        "displayName": "Administrator",
        "sourceName": "IdentityNow",
        "attribute": "assignedGroups",
        "value": "ORG_ADMIN",
        "type": "ENTITLEMENT",
        "description": "Full administrative access to IdentityNow",
        "sourceId": "2c91808475b4334b0175e1dff1b563a4",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c91808475b4334b0175e1dff22263a8",
        "accessType": "entitlement",
        "displayName": "Helpdesk",
        "sourceName": "IdentityNow",
        "attribute": "assignedGroups",
        "value": "HELPDESK",
        "type": "ENTITLEMENT",
        "description": "Helpdesk access to IdentityNow",
        "sourceId": "2c91808475b4334b0175e1dff1b563a4",
        "standalone": false,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd593a22",
        "accessType": "entitlement",
        "displayName": "true",
        "sourceName": "Discourse - DevRel",
        "attribute": "moderator",
        "value": "true",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472ccb03a14",
        "accessType": "entitlement",
        "displayName": "true",
        "sourceName": "Discourse - DevRel",
        "attribute": "admin",
        "value": "true",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cce73a16",
        "accessType": "entitlement",
        "displayName": "4",
        "sourceName": "Discourse - DevRel",
        "attribute": "trust_level",
        "value": "4",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": false,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd703a25",
        "accessType": "entitlement",
        "displayName": "41",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "41",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd0e3a1a",
        "accessType": "entitlement",
        "displayName": "1.1",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "1",
        "type": "ENTITLEMENT",
        "description": "this is a description.",
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd843a2a",
        "accessType": "entitlement",
        "displayName": "2",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "2",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd233a1d",
        "accessType": "entitlement",
        "displayName": "3",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "3",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd383a1f",
        "accessType": "entitlement",
        "displayName": "10",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "10",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd503a20",
        "accessType": "entitlement",
        "displayName": "11",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "11",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd613a23",
        "accessType": "entitlement",
        "displayName": "12",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "12",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": null,
        "accessType": "entitlement",
        "displayName": "13",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "13",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": null,
        "accessType": "entitlement",
        "displayName": "54",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "54",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "2c9180867c7f4efb017c8472cd9e3a2d",
        "accessType": "entitlement",
        "displayName": "14",
        "sourceName": "Discourse - DevRel",
        "attribute": "groups",
        "value": "14",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2c91808a7b5adbb6017b63c91b2d0f4f",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "70e5e63ca6824af9a5dc616ad08c3849",
        "accessType": "entitlement",
        "displayName": "user",
        "sourceName": "airtable-v5v1",
        "attribute": "entitlements",
        "value": "user",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "2f2718f6bb024cafacfafd1f28e5f415",
        "standalone": true,
        "privileged": false,
        "cloudGoverned": false
    },
    {
        "id": "80b80626aa354385b68d6fee9726efd8",
        "accessType": "entitlement",
        "displayName": "user",
        "sourceName": "airtable-v5-renamed",
        "attribute": "entitlements",
        "value": "user",
        "type": "ENTITLEMENT",
        "description": null,
        "sourceId": "b569e8001537420bb5521f83c2e3119f",
        "standalone": false,
        "privileged": false,
        "cloudGoverned": false
    }
]

And my UI is showing this

The issue seems to be split among the UI and the API, so this must go through support triage. If you haven’t already, please submit a support ticket with the details from this post.

It the API response is fixed, the UI doesn’t have to change anything.

Is it allowed “by design” for the API to provide such data? If not, this should be fixed without the involvement of the UI.

It is not clear at this time if it is just the API that it as fault. Your response returned duplicate entitlement IDs, but mine did not. It just happened that several of the entitlements had a null ID, which is also not great. The case could be made that the UI should not be filtering out duplicate IDs, and it should return all instances. However, this will be for triage to figure out.

1 Like

Assuming I am calling the API myself (in a script), is the API allowed to provide duplicate entries?

I’m not certain of the implementation details of this API and why it would return duplicates in the first place. This may be by design or it may be a bug. If it is by design, then the UI will need to make some adjustments. There are too many questions to answer and potentially more than one team involved for me to surface this issue. It will need to go through the support triage process.

1 Like

If you can not say if an endpoint is allowed to return duplicate entries, do we have to ask SailPoint Support for each endpoint explicitly to know if it is allowed to return duplicate entries?

For example https://developer.sailpoint.com/docs/api/beta/list-accounts doesn’t explicitly say that it won’t return duplicate accounts. My expectation was that the APIs will provide unique elements, but now I can’t assume this behavior anymore, right?

I have been in contact with SailPoint Support multiple times on duplicate results or incorrect counters appearing either in API or UI:

CS0245728 - Duplicate Attributes in the Account Schema for SCIM 2.0 SaaS source
CS0236955 - Followup of CS0245728
CS0251455 - GET v3/sources count incorrect and duplicate results
CS0258279 - Followup of CS0251455
CS0249576 - Duplicate email templates
CS0254439 - Second followup of CS0245728
CS0254463 - Duplicate attributes in HR source.
CS0294469 - Wrong source counter
CS0197216 - Role appearing twice in list API
CS0300922 - Followup of CS0197216

I am not saying you shouldn’t assume anymore that the APIs only return unique results, but I do have some code in my scripts to scan certain outputs from SailPoint APIs for things like this.

For your specific API. Could it be that this person “has this entitlement twice”, because this person has multiple accounts on the same source, two of which have this entitlement? I also once encountered that I could do a PATCH operation to add an entitlement to an access profile, where the path was /entitlements/-, and it did not check on the SailPoint servers if the entitlement already was part of the access profile and so it got added twice. As a consequence I started performing this check in my scripts myself, so I don’t know if this issue still exists. It was already a couple of years ago.

For the case from @colin_mckibben, I wonder if this was triggered by entitlements that were originally assigned or requested and later got detected as deleted due to an entitlement aggregation or source reset? Or any other operation that would benefit in having functionality similar like “ON DELETE CASCADE” in databases, to prevent having corrupt or incomplete object references.

Kind regards,
Angelo

1 Like