Identity Security Cloud BP Rule – Recommended Way to Access Attributes from Another Source

Hi Team,

Just to provide some background, I’m currently writing a BP rule that contains several if/else conditions.

The rule primarily accesses Identity attributes, but I also need to retrieve an attribute (e.g. TESTATTRI) from another source (e.g. TEST SOURCE).

Since we’re using Identity Security Cloud (IdentityNow), what would be the safest and recommended approach?

Option 1:

Account testAccount = idn.getFirstAccount(identity, "TEST SOURCE");
String testValue = StringUtils.lowerCase(
    StringUtils.trimToEmpty(
        idn.getAccountAttribute(testAccount, "TESTATTRI")
    )
);

Or should I instead use:

identity.getLinks()

and then iterate through the links, for example:

if ("TEST SOURCE".equalsIgnoreCase(link.getApplicationName())) {
    testLink = link;
} and then get attribute via testLink.getAttribute("TESTATTRI")

and retrieve the attribute from the matching link?

If there is another more reliable or recommended approach considering we got ISC, I’d appreciate your advice.

Thanks!

Using idn.getFirstAccount() is more readable and avoids manually looping through all links just to find the correct account. For example:

Account account = idn.getFirstAccount(identity, "TEST SOURCE");
if (account != null) {
    String testValue = StringUtils.lowerCase(
        StringUtils.trimToEmpty(
            idn.getAccountAttribute(account, "TESTATTRI")
        )
    );
}

The identity.getLinks() approach can still work, especially if you need to process multiple accounts or apply custom selection logic. However, if you’re simply retrieving an attribute from a single source, idn.getFirstAccount() is cleaner and easier to maintain.

Thanks for your help @Gopi2000 this helps,

Also, on the same topic, this BP rule contains several if/else conditions and references attributes from other sources.

I’m considering moving this logic into an Identity attribute using transformations, and then simply referencing that Identity attribute from the BP rule.

The main advantage I see is maintainability. If the logic needs to change in the future, we can update the transformation ourselves without having to modify the BP rule or wait for SailPoint support.

My only concern is whether introducing an Identity attribute with transformations for this purpose would have any noticeable performance impact compared to keeping the logic directly within the BP rule.

I’d be interested to hear your thoughts or if anyone has experience with this approach.

I think using an Identity Attribute with transforms is a good approach if the logic may be reused or changed in the future. It keeps the BP rule simpler and makes maintenance easier since only the transform needs to be updated.

From a performance perspective, the impact is generally minimal for straightforward transforms, so I’d prioritize maintainability unless the logic is extremely complex.

I think even IdnRuleUtil.getSourceAttributeBySourceName(java.lang.String sourceName, java.lang.String attributeName) might give the value direct as opposed to getFirstAccount method

e.g

String completion = idn.getSourceAttributeBySourceName(“TEST SOURCE”,“TESTATTRI”);

nothing clearly indicating which one prefer over other, considering ISQ as the platform

idn.getSourceAttributeBySourceName() seems simpler if you only need a single attribute from a source. I’m also curious if SailPoint recommends one approach over the other for ISC or if there’s any performance difference.

Hello Lalitha, I think I spotted a couple of things in your code that might be worth checking.

In your Option 1 code, I think the parameter order is reversed. idn.getFirstAccount() takes (String applicationName, String identityName) in that order (Java docs). Your code passes (identity, "TEST SOURCE"), which I think flips the parameters and passes an object where a String is expected.

Another thing, identity is not a direct input in a BP rule. The BP rule inputs are log, idn, plan, application, and integration. You would want to pull the identity from the plan, and it’s worth using the fully qualified class name to avoid the namespace conflict between sailpoint.object.Identity and sailpoint.rule.Identity.

The corrected version would look something like this:

sailpoint.object.Identity identity = plan.getIdentity();
Account testAccount = idn.getFirstAccount("TEST SOURCE", identity.getName());

String testValue = null;
if (testAccount != null) {
    testValue = StringUtils.lowerCase(
        StringUtils.trimToEmpty(
            idn.getAccountAttribute(testAccount, "TESTATTRI")
        )
    );
}

I also added a null check on testAccount to your code. Since your rule has several if/else branches, not every identity may have an account on TEST SOURCE, so that should help avoid any unexpected errors.

For your use case, I would go with idn.getFirstAccount() + idn.getAccountAttribute(). It uses the IdnRuleUtil wrapper SailPoint built specifically for cloud rules, and I think it’s the cleaner path for pulling one attribute from one source.

identity.getLinks() works too, but that route is probably more useful when you need custom matching logic across multiple accounts on the same source. For what you’re doing here, it might be extra looping without much benefit.

Regarding getSourceAttributeBySourceName() that you mentioned, I would be careful with that one. Per the Java docs, it reads a source/application-level config attribute (like a property on the source itself), not an account attribute tied to a specific identity. So idn.getSourceAttributeBySourceName("TEST SOURCE", "TESTATTRI") would not return what you are looking for. I think getAccountAttribute() is the right one for your case.

Agree, you are correct also great pickup

Sounds like a promising answer, I will try it out and update it here with the outcome or if any other doubts if any

Hi @punna0001

I implemented the complete enable/disable logic within the BP rule, as per your suggestion.

As I mentioned earlier, the reason for moving this logic into the BP rule is that the enable/disable decision depends on more than just the Lifecycle State (LCS). It also requires evaluating an attribute (e.g. attribute_01) from another trusted source account.

However, it still doesn’t appear to be working. From what I can see, the BP rule attached to the target source (e.g. source1) is not being triggered.

My suspicion is that the BP rule is not firing because, in this scenario, there is no Lifecycle State change—only a change to the trusted source attribute (attribute_01), which is referenced in the BP rule condition.

Additionally, attribute_01 is not mapped to the target source account. It is only used as part of the decision-making logic to determine whether the target account should be enabled or disabled.

If my understanding is correct, I’m curious how this type of requirement can be achieved.

One option I considered was encapsulating the logic in an Identity attribute and then referencing that Identity attribute from the BP rule. However, I decided against that approach because the Identity attribute would only be used for this particular target source, and for many Lifecycle States this source is not even included in the Identity Profile. Even if I exposed such an Identity attribute, I’m still unsure whether its update would cause the BP rule to be triggered.

Could you shed some light on how this scenario should be handled, or whether there is a recommended approach for implementing this type of logic?

I agree with using idn.getFirstAccount() for the single-account use case. One additional thing I’d consider is what happens if the source can contain multiple accounts for the same identity. In that case, relying on getFirstAccount() assumes the returned account is always the one you want. If duplicates are possible, iterating through identity.getLinks() with explicit selection criteria may be more predictable. Otherwise, for the common one-account-per-source scenario, getFirstAccount() definitely keeps the code simpler and easier to maintain.

Another small benefit of getFirstAccount() is that it makes the intent of the code immediately clear, you expect a single account from that source. I’d just make sure to handle the null case before reading attributes, since not every identity is guaranteed to have an account on that source.

Thanks, in our case we don’t have duplicates so that we are covered…

However I have explained slightly different issue above w.r.t firing of the BP rule, is where my current issue is inside logic seems to be good

Hello Lalitha,

Yes, I think your understanding is right.

A BP rule will not fire just because attribute_01 changed on another source. The BP rule only runs when ISC is already sending a provisioning plan to that target source. So if there is no LCS change, role/access change, attribute sync, or any other provisioning event for source1, the BP rule will not get a chance to execute.

Also, mapping attribute_01 into an Identity attribute can help with decision logic, but that alone still does not guarantee the BP rule will run. It would need to result in some provisioning action for the target source.

For this kind of requirement, I would probably handle the trigger outside the BP rule. For example, use a Workflow triggered by the trusted source account update or by an Identity attribute change, evaluate attribute_01, then enable or disable the account on source1.

I would keep the BP rule only for modifying a provisioning plan that is already happening. I would not rely on it as the trigger mechanism for this use case.

Thanks Dilshod, agreed.

My suggestion was based on the common one-account-per-source scenario. In that case, getFirstAccount() keeps the logic simple and readable. But yes, if the source can have multiple accounts for the same identity, I would not blindly rely on the first returned account. In that case, it is better to add explicit selection logic and pick the correct account based on native identity, account status, or another stable account attribute.

And yes, the null check is definitely needed before reading TESTATTRI, since not every identity may have an account on that trusted source.

I agree. Using getFirstAccount() makes the intent much clearer when we expect only one account from the source. And yes, handling the null case before accessing the account attributes is definitely important. Thanks for pointing that out!

Hi @punna0001

Thanks for your reply. Yes, we’re on the same page. Since the BP rule is not being triggered, I’m unable to achieve the desired outcome.

Unfortunately, we don’t have the Workflow module available in our tenancy either.

As an alternative, I’m considering handling this outside of the BP rule, possibly using Event Triggers. I could subscribe to the Account Updated event with the appropriate filters, invoke an external service, and then enable or disable the account using the SailPoint API.

My concern with this approach is the following:

If I manage the account enable/disable state externally (for this specific scenario only), rather than through the BP rule or Identity Profile, what happens when the scheduled Identity Refresh runs in SailPoint? Will the refresh preserve the account state that was set through the API, or will it reconcile the account back to its original state based on the provisioning policies and overwrite my change?

​​​

​​​​​​​​​​​

Yes, that approach makes sense if Workflow is not available.

I would just separate two things here:

If you disable/enable the account through the SailPoint account API, a daily identity refresh by itself should not automatically revert it just because the refresh ran. Identity processing re-evaluates access profiles, roles, and lifecycle state assignments, but account enable/disable is acted on during an actual LCS transition, not re-enforced on every refresh cycle.

But it can be changed again later if some other SailPoint configuration still drives the opposite state for that same source. For example, lifecycle state account settings, birthright role/access profile logic, attribute sync, or any other provisioning event that sends a new plan to source1.

So I would check whether source1 is configured under any LCS enable/disable account settings, or whether any active role/access profile is expected to keep that account enabled. If nothing else in ISC is enforcing the opposite state, your external Event Trigger + API approach should hold.

Also, if you are using the Account Updated event, I would make sure the trigger is filtered tightly to the trusted source and the specific attribute change. Without proper filters, it will fire for unrelated account updates too.

@lalithajay
Be aware that source names in rules differ from the names you see in the UI!

Previously, you would reference a source like this:

String Source = "MySource [source]";
Account MyAccount = idn.getAccountByDisplayName(Source, "Yan Coelho");

However, all newly created sources now have a specific ID (you can find it in the events — for example, look at the creation event of the source and check the target value):

String Source = "MySource [source-12345678]";
Account MyAccount = idn.getAccountByDisplayName(Source, "Yan Coelho");

Unannounced Change in Source Technical Name Format Impacting BP Rules - Identity Security Cloud (ISC) / ISC Discussion and Questions - SailPoint Developer Community