Compare 2 Attributes using Search

Is there a way to compare 2 Identity Attributes to see if they are equal? Using either /search or /search/aggregate built into IDN, I want to be able to find all users where Attribute A and Attribute B are not equal.

I have done this before using a transform, but that requires setting the 2 attributes in the transform so if you need another set, this requires another transform.

The other way would be to have a script that gets all of the users then parses them locally.

I myself can’t figure out how to do this with a search query, and I don’t think it’s possible to do it via aggregation since this would be like an inner-join. I asked around internally and got the same response. It seems the only way to accomplish this is to do a search to get all of the identities and then do the attribute comparison processing locally.

If you don’t mind my asking, can you elaborate on your use case? I’m thinking this type of report could be baked into a CLI, but I need to understand the goal better.

In the past I have used this to compare attributes before turning on Attribute Sync, so this was an Identity Attribute with the Account Attribute. I have also replaced the “identityAttribute” with a reference if that is how the attribute is configured. Then using Search, I look for this new value where

NOT attribute.name:Synced

{
    "id": "id",
    "name": "Name",
    "type": "conditional",
    "attributes": {
        "expression": "$identityAttribute eq $accountAttribute",
        "positiveCondition": "Synced",
        "negativeCondition": "$identityAttribute|$accountAttribute",
        "identityAttribute": {
            "type": "firstValid",
            "attributes": {
                "values": [
                    {
                        "type": "accountAttribute",
                        "attributes": {
                            "sourceName": "Auth Source",
                            "attributeName": "AccountAttribute"
                        }
                    },
                    {
                        "type": "static",
                        "attributes": {
                            "value": "NONE"
                        }
                    }
                ]
            }
        },
        "accountAttribute": {
            "type": "firstValid",
            "attributes": {
                "values": [
                    {
                        "type": "accountAttribute",
                        "attributes": {
                            "sourceName": "Downstream Source",
                            "attributeName": "AccountAttribute"
                        }
                    },
                    {
                        "type": "static",
                        "attributes": {
                            "value": "NONE"
                        }
                    }
                ]
            }
        }
    },
    "internal": false
}

The advantage to this is this stays up to date as changes occur but does not exactly account for the cases where the user does not have the downstream account.

The other use case for this is when making updates to a transform. Seeing what users the value has changed on to validate the changes are correct compared to their old values.

Looking at this, it appears you are comparing two account attributes, not two identity attributes. Technically, the account attribute from the authoritative source would become the identity attribute (pending any transforms), in which case you are comparing an identity attribute with an account attribute.

Am I correct in stating that this is really trying to compare two account attributes from separate sources?

Technically yes. I did not want to pull in the identityAttribute type, but this is effectively the same comparison. In the cases where the Identity Attribute had a transform, I would reference the transform and compare with the Downstream Account Attribute.

Gotcha. I tried to see if a search aggregation would work, but it did not. Our elastic search implementation is very limited (for performance reasons), and is only really tuned to do basic searching of data. The only way I can see you solving this is by using search to download all of the identity data and then doing local processing.