Please standardize the way IDN objects reference one another

What problem are you observing?

Just within a single object type (Identity Profile), there are three different ways other objects are referenced.

There’s the “proper” reference, with “coordinates”:

"owner": {
    "id": "987654327d404a6198665dab08123456",
    "name": "OWNER.GUY",
    "type": "IDENTITY"
},

There’s the “id but just kidding it’s a name” reference:

"transformDefinition": {
    "attributes": {
        "id": "Transform Name",
        "input": {

And there’s the “id and name but non-standard” reference:

"sourceId": "987680878029f6820180123412345678",
"sourceName": "HR"

Notably, the last two are both within a single attribute’s Transform Definition.

What is the correct behavior?

Is this a bug? I’m not sure. It’s certainly a quality-of-life issue for API users, specifically API users who need to migrate between different IDN tenants.

I’d prefer the first format, as it makes it easy to decide which parts of an object (when using an SDK) are references that may need to be replaced on migration.

What product feature is this related to?

SaaS Configuration, in this case, but general API.

What are the steps to reproduce the issue?

Just export an Identity Profile with a couple of transform mappings.

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

Nothing special. This is more of an API spec issue.

8 Likes

I found a fourth type of reference! In an ACCESS_PROFILE, the owner.name is a display name.

"owner": {
    "id": "fc3eb3b57d404a6198665dab08ed8684",
    "name": "User Name (Admin)",
    "type": "IDENTITY"
}

The reference is correct on a SOURCE from the same tenant:

"owner": {
    "id": "fc3eb3b57d404a6198665dab08ed8684",
    "name": "ADMIN-UNAME",
    "type": "IDENTITY"
},
1 Like

I found a fifth reference type on saved searches:

    "owner": {
        "type": "IDENTITY",
        "id": "da9bdc9a36d145a48d27eac0075c5c05"
    },
    "ownerId": "da9bdc9a36d145a48d27eac0075c5c05",

Yes! this was extremely frustrating to me when I encountered that too! Name is not the identity name but rather the display name or preferred name!! So then need extra API calls to look up their real name…

According to SailPoint standards convention, a reference will have:

{
  "type": "IDENTITY",
  "id": "fc3eb3b57d404a6198665dab08ed8684",
  "name": "John Doe"
}

The type points out the type of object and is required and has to be set from a standard object enum. The id is the object’s GUID; great for APIs, bad for UX. The name is an optional display name; often included for UX. There can be other fields added to the reference object, like email but that is non-standard and very uncommon.

When you see things like ownerId or ownerName these are considered ‘soft references’ and usually come from older micro-services that pre-date the reference convention. There can be other technical reasons why we may not have a reference (e.g., multiple values), but in general we should be trying to follow these conventions where possible. Especially for versioned APIs.

In my personal opinion, I am in favor of more HATEOAS principles when it comes to handling references. I would love for SailPoint APIs to be self-describing and offer links to other SailPoint APIs natively. This would make consumption and usage of APIs by product, implementers, and developers much easier; it helps streamline the amount of client-side code needed.

1 Like

Bringing this back to life as I just found another weird thing here.

POST /v3/search against identities will return the name as the actual identity name that was generated based on the Account Name from the authoritative source schema. This is what I would expect to happen.

Search also seems to work with the displayName?

When you use the GET /beta/identities endpoint, name is returned as the identity’s display name.

This endpoint does not work with the actual identity name

Very confusing, especially when doing lookups for migrating objects. Also doing a lookup on a display name doesn’t feel great.

UPDATE: Turns out name is truly just mapped to displayName it seems. I actually changed my identity profile mapping from an ID number to a transform to calculate first + last and it actually updated name after I refreshed identities in that profile, so now I have two identities with the same name.

I think alias is the only attribute that doesn’t change after an identity is created (which is essentially name from IIQ), but unfortunately I would have to get an identity from one tenant via ID first (from a source owner ref for example), get their alias attribute, then perform the alias lookup in the next tenant.

2 Likes

I agree - the search API is fantastic, and Elastic is a super powerful tool. It could stand some better documentation, though. It doesn’t always agree, either in syntax or in object content, with the rest of the system. I realize that’s because it’s been exported and indexed into Elastic, but it would be nice to see HOW.