🟢
Updated recently
Last updated:

Quick Answer: a SailPoint correlation rule is BeanShell logic that decides which identity an aggregated account belongs to. IIQ compares account attributes (employee ID, email, name) against identity attributes using either built-in correlation logic or your rule. Correlation quality decides the integrity of the entire identity warehouse: every orphan account, every wrongly merged identity, every “who is this user?” audit question traces back to a correlation decision.

What Correlation Must Achieve

Three outcomes, one of which is failure:

  • Match: the account belongs to a known identity — link them.
  • Create: the account is genuinely new — create an identity (for authoritative sources like HR).
  • Orphan: no confident decision — quarantine for review. (The failure mode is pretending confidence: guessing a match and corrupting two records at once.)

The Built-In Logic First, Rules When Needed

Start with IIQ’s standard correlation: attribute-to-attribute matching configured in the application definition (for example, account “employeeId” equals identity “employeeId”). It is fast, auditable and sufficient for clean sources. Write a custom rule when matching needs logic beyond equality — case normalisation, prefix stripping, fallback keys, or multi-attribute scoring. The connectors guide covers where the rule sits in application onboarding.

A Complete Correlation Rule Example

Scenario: HR feeds employee IDs, but the target application sometimes stores them with leading zeros or department prefixes. The rule normalises and matches with a guarded fallback:

import sailpoint.object.Identity;
import sailpoint.object.Link;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;

Logger log = Logger.getLogger("custom.correlation");

// 1. Pull the account's raw employee ID
String rawEmpId = (String) account.getAttribute("employeeId");

if (rawEmpId == null || rawEmpId.trim().isEmpty()) {
    // No key at all: do not guess. Orphan queue it.
    log.warn("Correlation: account " + account.getName()
        + " has no employeeId; leaving orphaned");
    return null;
}

// 2. Normalise: trim, strip leading zeros, drop 'EMP-' prefixes
String empId = rawEmpId.trim();
while (empId.startsWith("0")) {
    empId = empId.substring(1);
}
if (empId.startsWith("EMP-")) {
    empId = empId.substring(4);
}

// 3. Deterministic match on the normalised key
Map filter = new HashMap();
filter.put("employeeId", empId);

Identity match = context.getUniqueObject(Identity.class,
    filter, "links");

if (match != null) {
    log.info("Correlated " + account.getName() + " to " + match.getName());
    return match;
}

// 4. No match: authoritative source? create. Otherwise orphan.
if ("HR".equalsIgnoreCase(application.getName())) {
    // Creating identities is the authoritative source's job
    return null;  // let IIQ's default creation logic handle it
}

log.warn("Correlation: no identity for " + empId
    + " (account " + account.getName() + ")");
return null;

What makes this production-grade: the early null guard, the explicit orphan decision with a log trail, normalisation in one place, and the authoritative-source branch. Compare with the naive version — find identity where displayName equals account name — and you are looking at the difference between clean audits and a quarter of cleanup work. More patterns in the BeanShell examples guide.

Testing Correlation Before It Touches Production

  1. Build the hostile dataset first: duplicates by name, IDs with prefixes, null keys, contractors without IDs, rehires with old links.
  2. Run aggregation in a sandbox with production-shaped volumes — correlation behaves differently at 50 accounts vs 50,000.
  3. Inspect the three buckets: matched, created, orphaned. Sign off each bucket with a count; surprise counts mean surprise behaviour.
  4. Check the reverse direction: identity refresh after correlation — did roles/policies recalculate correctly for the newly linked accounts?
  5. Document the matching contract: which key, what normalisation, what happens on no-match. Auditors ask; future you asks harder.

Correlation Failure Modes at a Glance

Before the cleanup playbook, learn to recognise the failure modes — each has a different symptom signature and a different first move.

Failure mode Symptom you will see First move
Rule too strict (one rigid key) Mass orphans appearing after a feed change or migration Quarantine first; add a guarded fallback key, never a fuzzy guess
Rule too loose (name-based matching) Wrong merges surfacing as shared access reviews Freeze aggregation, unmerge carefully, move to an immutable key
Null or malformed keys on some accounts Intermittent orphans concentrated in new joiners or one region Guard the null path, quarantine, then fix the source feed
Case, prefix or format drift Orphans returning in weekly waves despite fixes Normalise in the build map and the rule, then backfill

Data Quality Upstream: The Cheaper Fix

Experienced IIQ teams push correlation fixes upstream whenever they can, because every normalisation in a rule is a tax paid on every aggregation forever. The upstream moves: a data contract with the HR team that specifies which field is the immutable key, its format, and who to call when it breaks; validation at feed level (reject or flag records with malformed keys before they enter IIQ); and a weekly data-quality report showing key coverage percentage per source — the metric that predicts next month’s orphan problem. When you inherit a project where the HR feed sends three different employee-ID formats, fixing the feed beats compensating in BeanShell — but until that fix lands, your rule has to be the adult in the room. That dual posture — source fix requested, rule defensive meanwhile — is exactly what interviewers want to hear in scenario rounds, because it shows you solve systems, not symptoms.

When Correlation Goes Wrong: The Cleanup Playbook

Wrong merges (two humans as one identity) and mass orphans both happen on real projects. The playbook, in order: freeze further aggregations from that source; quantify damage with a warehouse query (orphan count, suspicious multi-link identities); unmerge carefully — links are data, treat edits as changes; fix the rule and the data at the source where possible; re-run aggregation in waves with sign-offs. One merged-mortician story is enough for any career: two different “S. Kumar” identities correlated into one, and both employees’ access reviews went to the same manager. The fix took an hour; the client’s trust took a quarter.

Training Resources

Correlation labs — including the hostile-dataset exercise — are core to the SailPoint IdentityIQ Certification Training. The architecture guide shows where correlation sits in the platform, and the IIQ roadmap sequences it in the developer track. The IAM training track covers identity matching across other tools.

FAQ

What is a correlation rule in SailPoint IIQ?

BeanShell logic that decides which identity an aggregated account belongs to, returning the matching identity or leaving the account orphaned when no confident match exists. It runs during account aggregation per the application’s correlation configuration.

When should I write a custom correlation rule instead of using built-in matching?

When matching needs normalisation, fallback keys, or conditional logic that attribute-equality cannot express. Otherwise use built-in correlation — it is faster, auditable, and upgrade-safe.

What causes orphan accounts in IIQ?

Missing or malformed matching keys, correlation rules that are too strict, and identities deleted at the authoritative source while accounts persist. Orphans are safest when quarantined deliberately — auto-matching them “to fix the count” is how wrong merges happen. If orphan counts jump suddenly, check the last feed change before touching the rule — data first, code second.

Can a correlation rule create new identities?

Identity creation is governed by the application’s authoritative-status configuration; the rule’s job is matching. For authoritative sources like HR, unmatched accounts feed identity creation per IIQ’s default logic — keep the rule’s create-path clean and predictable.

How do I test a correlation rule safely?

Sandbox aggregation with a hostile dataset: duplicates, null keys, prefix variants, rehires. Sign off matched/created/orphaned counts, then refresh identities and verify role recalculation before pointing the rule at production — and check the source’s key-coverage trend while you are there.