Directory Sync Conflict Resolution at Scale in Okta

Directory Sync Conflict Resolution at Scale in Okta

A plain-English guide to what happens when two systems disagree about the same person: where sync conflicts come from, how Okta imports, matches and applies data, how to decide who wins, and how to detect, resolve, and prevent conflicts when you manage tens of thousands of identities across many directories.

Every identity system tells a story about each person: their name, their job, their manager, their groups, whether they still work here. The trouble starts when two systems tell different stories at the same time. The human resources system says Priya moved to Finance on Monday. The company directory still says she is in Sales. A second directory, left over from an acquisition, spells her surname differently. A script that someone wrote three years ago keeps changing her title back. Which story is right, and how does the sign-in platform decide?

That question is the heart of directory sync conflict resolution. With a few hundred people, conflicts are rare and someone simply fixes them by hand. With tens of thousands of people, many directories, and imports running around the clock, conflicts become a constant background hum, and a poor strategy turns the hum into outages, lockouts, and quiet security gaps. This guide teaches the subject from zero. You will learn the vocabulary, how Okta pulls in and applies directory data, the different kinds of conflict, how to decide who wins, and how to detect, resolve, and prevent problems when volume grows. The companies and numbers in the examples are invented for teaching.

1What a Sync Conflict Really Is

A sync conflict is simply a disagreement between two sources of information about the same thing. Understanding it clearly makes everything else easier.

The plain definition

Okta keeps a profile for every person. That profile is filled in from one or more outside sources, such as Active Directory, another directory service, or a human resources system. Each source sends its own version of the facts. When two sources send different values for the same fact, or when a source sends something that does not fit what Okta already holds, you have a conflict. Something has to decide which value is kept.

Notice that a conflict is not always an error in the technical sense. Nothing crashes. No red warning appears. The system happily picks one value and moves on. The danger is exactly that quietness: a wrong choice made silently, thousands of times, can leave people with the wrong access or no access at all.

Why scale changes the game

  • More sources. Each extra directory or feed multiplies the ways two stories can differ.
  • More frequency. Imports run every hour or even more often, so a bad rule repeats itself many times a day.
  • More people. A mistake that touches one percent of users is a nuisance at 200 people and a crisis at 50,000.
  • More owners. Different teams own different sources and may change them without telling the identity team.
  • Less visibility. Nobody can eyeball tens of thousands of profiles, so problems hide until someone complains.
Everyday Analogy

Imagine a village where the post office, the school, and the clinic each keep a list of residents. When one family moves, each list is updated by a different clerk on a different day. For a while the three lists disagree. In a small village, everybody knows the truth anyway. In a city of a million, the lists must follow clear rules about whose list wins, or letters, school places, and appointments go to the wrong doors.

i
Tip

Throughout this guide, ask the same three questions about every kind of conflict: what disagrees, who should win, and how will we notice when it goes wrong. Those three questions are the whole discipline in miniature.

2The Vocabulary You Need

A handful of words carry most of the meaning in this topic. Learn them once and the rest reads easily.

Core

Source of truth

The system that is trusted to be right about a particular fact. Different facts can have different sources of truth.

Core

Profile

The record Okta keeps for a person, made of many attributes such as name, email, department, and manager.

Core

Attribute

One named fact on a profile, such as a job title or a phone number.

Flow

Import

Pulling people and their facts from an outside source into Okta.

Flow

Push

Sending changes from Okta out to another system, such as a directory or an application.

Flow

Mastering

Declaring which source is allowed to control which attributes of a profile.

Match

Matching

Deciding whether an incoming record is the same person as someone Okta already knows.

Match

Linking

Joining a source record to an existing Okta profile so they behave as one identity.

Health

Drift

The slow growth of differences between systems that were once in agreement.

Health

Reconciliation

Comparing two systems on purpose to find and fix differences.

Safety

Idempotent

An operation that gives the same result whether it runs once or many times.

Safety

Quarantine

Holding a questionable change aside for review instead of applying it.

Everyday Analogy

Think of a group project where several people edit one shared document. Each person owns certain sections. Importing is copying someone’s edits in, pushing is sending your edits out, and mastering is the agreement about who may change which section. Without that agreement, edits overwrite one another.

One more word deserves attention: stable identifier. This is a value that never changes for a person or an account even when everything else does. Names change at marriage, emails change at rebrands, and departments change monthly. A stable identifier, such as an employee number or a directory’s internal account identifier, is what lets a system keep recognizing the same person through all of that change. Almost every good conflict strategy leans on stable identifiers.

3Where Conflicts Come From

Conflicts have ordinary, human causes. Knowing the usual suspects tells you where to look first.

The common sources

  • Multiple directories. Head office, acquired companies, regional teams, and old migrations each keep their own copy of a person.
  • An HR system plus directories. HR knows job facts, directories know sign-in facts, and both sometimes try to describe the same thing.
  • Manual edits. An administrator fixes a typo in one place and forgets the others.
  • Scripts and tools. Old automation keeps writing values nobody remembers authorizing.
  • Mergers and migrations. Accounts are copied between systems and briefly exist twice.
  • Timing gaps. A change reaches one system hours before it reaches another.
  • Data quality. Spelling variants, extra spaces, reused employee numbers, and shared mailboxes.
  • Product behavior. Import settings, matching rules, and push options that interact in ways no one planned.
CauseTypical symptomWhere to look first
Two directories hold the same personDuplicate users or a profile that flips between valuesMatching rules and source priority
HR and directory both write titlesTitle changes back after every importAttribute mastering
Manual edit in one systemValue reverts at next syncWho owns the attribute
Old scriptUnexplained changes at odd hoursAudit trail of who changed what
Reused employee numberNew hire inherits a former employee’s accessIdentity key design
Slow replicationBrief lockouts or stale dataTiming and ordering
Everyday Analogy

When two mapmakers copy from different old maps, their new maps disagree in the same places every time, near the roads that were rebuilt. Conflicts cluster around change, so the busiest areas of your organization, such as reorganizations and mergers, are where to expect them.

4The Architecture of Directory Sync in Okta

To resolve conflicts, you first need a picture of how data travels into Okta and back out.

The cast of characters

  • Sources. Directories such as Active Directory or LDAP, and human resources systems. They hold the original facts.
  • Connectors and agents. Small programs, usually installed inside your network, that read the source and talk to Okta over outbound connections.
  • The Okta profile. The unified record that applications and policies actually use.
  • Mappings. Rules that translate a source’s attribute names and formats into Okta’s profile fields and back.
  • Applications and targets. Where Okta sends identity data onward, sometimes including back into a directory.
flowchart LR
    AD1["Directory A"] --> AG1["Agent A"]
    AD2["Directory B"] --> AG2["Agent B"]
    HR["HR system"] --> CON["HR connector"]
    AG1 --> IMP["Okta import engine"]
    AG2 --> IMP
    CON --> IMP
    IMP --> MAT["Matching"]
    MAT --> MAP["Mappings and source priority"]
    MAP --> PRO["Okta user profile"]
    PRO --> APP["Applications and policies"]
    PRO -->|"Push"| AD1
    
Fig 4.1 — Data from several sources passes through matching and mappings into one Okta profile, which feeds applications and can push back

Read the picture left to right. Sources hand their records to Okta through agents or connectors. The import engine receives them, matching decides which Okta person each record belongs to, and mappings with source priority decide which values land in the profile. The finished profile is what applications and policies see. In some designs, Okta then pushes changes back out, which creates a second direction of traffic and a second place for conflicts to arise.

Everyday Analogy

A newsroom receives wire reports from several agencies. An editor decides which reports describe the same story, which agency to trust for which details, and then publishes one article. Agents are the wires, matching is the editor deciding it is the same story, and mappings with priority decide whose facts appear in print.

5How an Import Works Inside

Every conflict is born during an import or a push. Here is what happens during an import, step by step, in plain language.

1

Read from the source

The agent asks the directory for the people in scope and brings back their attributes. A full import reads everyone. An incremental import reads only what changed since last time.

2

Stage the records

Okta holds the incoming records in a waiting area and compares them with what it already knows. Nothing has changed in the real profiles yet.

3

Match each record

For each incoming record, Okta applies matching rules to find an existing person. The result is a confirmed match, a partial match that needs a decision, or no match, which means a new person.

4

Apply mappings

Attribute values are translated and, where several sources provide the same attribute, source priority decides which value is kept.

5

Apply lifecycle actions

New people can be created, existing people updated, and people missing from the source can be deactivated, depending on the settings you chose.

6

Record the outcome

Okta logs what it created, updated, skipped, or flagged, which is the evidence you will later use to investigate conflicts.

Full versus incremental

A full import is a complete photograph. It is slower, but it can notice people who disappeared. An incremental import is a list of recent edits. It is fast and gentle, but it only knows about changes it was told about. If an incremental feed misses a change, perhaps because a replication hiccup hid it, the difference stays hidden until a full import catches it. Healthy designs combine both: frequent incrementals for freshness, periodic fulls for truth.

stateDiagram-v2
    [*] --> Reading
    Reading --> Staged: "records received"
    Staged --> Matching
    Matching --> Mapping: "match found or new person"
    Matching --> NeedsReview: "ambiguous match"
    Mapping --> Applying
    Applying --> Logged
    NeedsReview --> Logged
    Logged --> [*]
    
Fig 5.1 — An import moves records from reading through staging, matching, mapping, and applying, with ambiguous matches set aside for review
Everyday Analogy

A full import is a yearly stocktake where every shelf is counted. An incremental import is a daily note of what was sold. The daily notes keep you current, but only the stocktake can reveal an item that quietly vanished without a note.

6Following One Attribute Through the Pipeline

The best way to feel a conflict is to follow a single fact, such as a job title, as it moves through the system.

Suppose Priya’s job title is “Sales Manager” everywhere. On Monday, HR promotes her and records “Finance Manager”. The HR connector delivers the new title to Okta within the hour. Okta updates the profile. Applications see the new title.

Now add a complication. The corporate directory still holds “Sales Manager” because a directory administrator updates titles only quarterly. At the next directory import, the old title arrives. Whether Okta overwrites the new title with the old one depends entirely on the rule you set. If the directory has equal or higher priority for titles, the promotion is silently reversed. Priya’s profile shows “Sales Manager” again, and a policy that grants Finance tools by title quietly removes her access.

sequenceDiagram
    participant HR as HR system
    participant OK as Okta profile
    participant DIR as Directory
    HR->>OK: "Title is Finance Manager"
    Note over OK: "Profile updated"
    DIR->>OK: "Title is Sales Manager"
    alt "Directory has higher priority"
        Note over OK: "Title reverted to Sales Manager"
    else "HR has higher priority"
        Note over OK: "Directory value ignored"
    end
    
Fig 6.1 — The same stale directory value either undoes a promotion or is ignored, depending on source priority

The lesson is that conflict outcomes are decided by configuration, not by luck and not by which update arrived most recently. Good teams treat priority as a deliberate, documented decision, made attribute by attribute.

!
Watch Out

If a downstream policy or application rule depends on an attribute such as department or title, then a wrong value is not just cosmetic. It silently changes who can do what. Always ask which rules depend on an attribute before deciding how conflicts for it are handled.

Everyday Analogy

Two clerks each hold a card with your address. When you move, you tell clerk one. If clerk two’s card is later treated as the master, your mail goes to the old house, even though you did the right thing. What matters is not who is right but which card the postman trusts.

7A Map of Conflict Types

Conflicts fall into a few families. Naming the family tells you which tool to reach for.

FamilyWhat disagreesExampleMain tool
Identity keyTwo people claim the same sign-in name or keyTwo employees both become “asmith”Unique username format
MatchingWhether two records are one personSame person in two directories imported twiceMatching rules on strong keys
AttributeThe value of one fieldDifferent job titlesSource priority per attribute
GroupNames, nesting, and membershipTwo groups called “Admins”Prefixes and ownership
LifecycleWhether a person is activeDisabled in one directory, active in anotherDeactivation policy
CredentialWhich password is currentReset in two placesOne password authority
TimingWhich change came firstRehire arrives before the leaver recordOrdering and checks
Write-backOkta and directory change the same fieldEdit loopOne direction per attribute
flowchart TD
    C["Sync conflict"] --> K["Identity key"]
    C --> M["Matching"]
    C --> A["Attribute"]
    C --> G["Group"]
    C --> L["Lifecycle"]
    C --> P["Credential"]
    C --> T["Timing"]
    C --> W["Write-back"]
    
Fig 7.1 — Eight families of conflict, each handled in its own chapter
Everyday Analogy

A doctor does not treat every illness the same way. First she sorts symptoms into families, such as infection, injury, or allergy, and each family has its own treatments. A conflict taxonomy plays the same role: sort first, then treat.

8Identity Key Conflicts: Names That Collide

The most basic conflict is two different people wanting the same sign-in name.

Why collisions are inevitable

Names are not unique. In a company of fifty thousand, there are many people named John Smith, and short formats that use first initial and surname will collide constantly. Each directory may have solved this locally, with one adding a number to the second Smith and another adding a middle initial. When their users all flow into Okta, collisions appear that neither directory could have seen alone.

What goes wrong

  • A second person with the same username is rejected, and their import fails or sits unfinished.
  • Worse, a system may treat the second record as an update to the first, so one person’s details overwrite another’s.
  • A new hire is given the name of a former employee, and inherits old access or old email.

How to prevent them

  • Pick a username format that is unique by construction, such as including an employee number or the full email address of a unique mailbox.
  • Audit all directories for overlapping names before the first big import, and fix them at the source.
  • Never reuse an identifier after someone leaves, or reserve retired names for a long quiet period.
  • Keep the stable account identifier as the real key, and treat the visible name as a label.
flowchart TD
    N["Incoming record: asmith"] --> E{"Name already in Okta?"}
    E -- "No" --> CR["Create new user"]
    E -- "Yes" --> S{"Same stable identifier?"}
    S -- "Yes" --> UP["Update existing user"]
    S -- "No" --> QU["Collision: hold for review"]
    
Fig 8.1 — A safe import compares the stable identifier, not just the visible name, before updating or creating
i
Tip

Test your username format on a list of real names from all directories before going live. Count how many collisions it produces. If the answer is more than zero, adjust the format now, while no one is affected.

Everyday Analogy

Two students named Sam Lee enroll in a school. If the school files them both under “Lee, S.”, one report card goes to the wrong family. A student number makes the confusion impossible, and the name becomes just a friendly label.

9Matching Conflicts: Wrong Merges and Missed Merges

Matching decides whether two records are the same human being. It can fail in two opposite directions, and both hurt.

Two ways to be wrong

Wrong merge

  • Two different people are joined into one profile.
  • One person sees the other’s access, mail, or data.
  • A security incident hiding as a data problem.
  • Hard to notice, because the merged profile looks tidy.

Missed merge

  • One person ends up with two profiles.
  • Policies and reviews apply twice, or only to one half.
  • Access is split between accounts, confusing audits.
  • Easy to notice, because duplicates show up in lists.

Of the two, the wrong merge is more dangerous, so a careful design leans toward missing a merge rather than making a false one. A duplicate can be cleaned up later at leisure. A false merge can expose data the moment it happens.

Choosing good matching keys

  • Strong keys. Employee number, a government-independent unique person identifier from HR, or a verified corporate email.
  • Weak keys. First name, last name, department, or phone number. These are fine as supporting evidence, never as the only basis.
  • Combined rules. Match when a strong key agrees and a second attribute does not contradict it.
  • Sample before switching on. Review the proposed matches for a few hundred people before allowing automatic linking.
quadrantChart
    title Matching risk by key strength
    x-axis Weak key --> Strong key
    y-axis Rare data --> Common data
    quadrant-1 Safe and useful
    quadrant-2 Needs a second check
    quadrant-3 Avoid
    quadrant-4 Safe but incomplete
    Employee number: [0.9, 0.8]
    Corporate email: [0.75, 0.7]
    Full name: [0.2, 0.9]
    Phone number: [0.3, 0.3]
    
Fig 9.1 — Strong keys that exist for most people are the safest basis for matching, while names alone should never decide
Everyday Analogy

A bank clerk who sees two accounts for “R. Kumar” does not merge them because the names look alike. She asks for a tax number or a signed form. Names are a hint, and a unique number is proof.

10Attribute Conflicts: Two Writers, One Field

When two sources provide the same attribute, something must choose. If nothing does, the value flips back and forth.

The flip-flop symptom

The classic sign is an attribute that changes at every import. The HR feed writes “Finance”, then the directory writes “Sales”, then HR writes “Finance” again, hour after hour. Each write looks legitimate to the system. Logs fill with updates. Downstream applications receive change notifications constantly, and rules based on the attribute turn on and off like a flickering light.

Common attribute conflict patterns

PatternWhat you seeTypical fix
Equal-priority writersValue flips at every importGive one source higher priority
Format mismatch“Dr. Rao” versus “RAO, Dr”Normalize with a mapping expression
Code versus label“FIN” versus “Finance”Translate codes to labels in one place
Empty overwriteA blank value erases a real oneIgnore empty values from weaker sources
Stale sourceOld value restores itselfFix the stale source or lower its priority
Multi-value fieldsLists merged or replaced unexpectedlyDecide whether to merge or replace
!
Watch Out

Empty values are a quiet danger. If a weaker source has no manager for someone and the system treats “no value” as a real value, it can erase the correct manager that another source supplied. Treat blanks from non-master sources as “no opinion”, not as “delete”.

flowchart TD
    V["Incoming value"] --> B{"Is it blank?"}
    B -- "Yes, from weaker source" --> IG["Ignore it"]
    B -- "No" --> P{"Source has priority for this attribute?"}
    P -- "Yes" --> AP["Apply value"]
    P -- "No" --> SK["Skip and keep current"]
    
Fig 10.1 — A simple decision path that stops blanks and lower-priority writers from overwriting good data
Everyday Analogy

Two housemates each adjust the thermostat when they feel too hot or cold. The temperature swings all day. The cure is not a better thermostat; it is a house rule that says who controls it.

A worked illustration

Consider a mobile phone number. HR holds a company mobile number, the directory holds whatever the employee last typed into a self-service page, and a facilities system holds a desk phone. If all three write the same field with equal priority, the number changes every time a different import finishes first. A better design keeps three separate attributes: a work mobile owned by HR, a personal contact number owned by the employee, and a desk phone owned by facilities. Many attribute conflicts vanish once you notice that two sources were never describing the same fact, only facts with the same label. Before ranking sources, ask whether you are really looking at one attribute or several that have been squeezed under one name.

Another useful habit is to give every attribute a short written definition, such as “the number a manager should call in an emergency”. Definitions expose hidden disagreements long before data does, because two teams that both believe they own “phone” will quickly discover they mean different things.

11Profile Mastering and Source Priority

The central tool for attribute conflicts is deciding, in advance, which source owns which fact.

The principle: one owner per attribute

The cleanest designs give every attribute exactly one owner. Business facts, such as title, department, manager, start date, and employment status, are usually owned by the HR system, because HR is where those facts legitimately change. Technical facts, such as the sign-in name, the directory identifier, and group membership for infrastructure access, are owned by the directory that issues them. Contact details can be owned by whichever system people actually update, often the directory or a self-service portal.

AttributeSuggested ownerReason
Job titleHR systemChanges through formal HR events
Department and cost centerHR systemTied to organization structure
ManagerHR systemReporting lines are an HR fact
Employment status and datesHR systemDrives joiner, mover, leaver flows
Sign-in nameIssuing directoryMust match the real account
Directory group membershipDirectoryControls infrastructure access
Mobile numberUser self-service or directoryChanges outside HR

When one owner is not possible

Sometimes two sources must both contribute, such as a person who exists in two directories. Then use ranked priority: the first source wins when it has a value, the second fills in when it does not. Write the ranking down, share it with the owners of every source, and review it whenever a source is added or retired.

flowchart LR
    HRS["HR system"] -->|"Priority 1: business facts"| PRF["Okta profile"]
    DIRA["Main directory"] -->|"Priority 2: sign-in facts"| PRF
    DIRB["Acquired directory"] -->|"Priority 3: fills gaps only"| PRF
    
Fig 11.1 — Each source is ranked, and lower-priority sources only fill gaps instead of overwriting
Decide the owner before the data arrives, not after it collides.
Everyday Analogy

In a hospital, the lab owns blood results, the pharmacy owns medicine lists, and reception owns contact details. A nurse would never ask reception for a blood count. Clear ownership prevents arguments about whose record is right.

12Group Conflicts: Names, Nesting, and Membership

Groups look simple, but they carry more conflict potential than people do, because they combine names, members, and nesting.

The usual troubles

  • Same name, different groups. Two directories each have “Engineers”. Imported together, they look like one group, or they collide.
  • Nested groups. Groups inside groups may be flattened or ignored, changing who is really a member.
  • Cross-domain members. A group in one domain holds people from another, and the importing agent cannot always see them.
  • Two masters. Membership is edited both in the directory and in Okta, so changes cancel each other.
  • Huge groups. Groups with tens of thousands of members take long to import and push, and partial failures become likely.

Resolution approaches

  • Give imported groups a prefix that names the source, so the names can never collide.
  • Decide for each group whether the directory or Okta is the master, and never both.
  • Prefer rules-based groups in Okta for access that depends on attributes, and keep directory groups for infrastructure.
  • Test nested and cross-domain behavior with sample groups before importing the real ones.
  • Split enormous groups into smaller purposeful ones.
flowchart TD
    G1["Directory A: Engineers"] --> PA["Okta group: A-Engineers"]
    G2["Directory B: Engineers"] --> PB["Okta group: B-Engineers"]
    PA --> RULE["Rules combine members for access"]
    PB --> RULE
    
Fig 12.1 — Prefixes keep same-named groups separate, and a rule combines them where a single audience is wanted
Everyday Analogy

Two sports clubs in neighboring towns are both called “The Eagles”. A league that merges their member lists without noting the town will mix up the teams. Adding the town to the name keeps them apart.

13Lifecycle Conflicts: Active, Disabled, or Gone?

Few conflicts are as costly as disagreeing about whether someone still works here.

Typical disagreements

  • HR marks someone as terminated, but their account in a second directory is still enabled.
  • A directory account is disabled temporarily during leave, and Okta deactivates the person permanently.
  • A person is rehired, and an old deactivated profile competes with a brand new one.
  • An import runs with the wrong scope and proposes to deactivate thousands of people at once.

Principles that keep lifecycle safe

  • Let HR own employment status whenever an HR system exists, and treat directory flags as secondary.
  • Treat a missing record carefully. A person absent from one import may have moved, not left.
  • Prefer suspension over deletion for the first period after an apparent departure.
  • Cap bulk actions. Stop and ask when an import would deactivate more than a small percentage of people.
  • Reconcile across all directories so no leaver stays enabled somewhere.
stateDiagram-v2
    [*] --> Active
    Active --> OnLeave: "leave recorded"
    OnLeave --> Active: "return"
    Active --> Suspended: "departure signal"
    Suspended --> Active: "rehire or mistake corrected"
    Suspended --> Deactivated: "grace period ends"
    Deactivated --> [*]
    
Fig 13.1 — A suspended stage between active and deactivated gives time to catch mistakes
!
Watch Out

The most dangerous lifecycle conflict is the quiet one: a leaver disabled in the main system but forgotten in a smaller, older directory. That account has no owner, no monitoring, and often a password that never changes. Reconcile every directory against HR on a schedule.

Everyday Analogy

When a hotel guest checks out, the front desk, housekeeping, and the key system must all agree. A card key that still opens the door a week later is the kind of leftover that causes real harm.

14Credential Conflicts: Whose Password Counts?

Passwords can be held, checked, or reset in more than one place. When they disagree, people simply cannot sign in.

Two basic models

  • Delegated authentication. Okta passes the password to the directory, which says yes or no. The directory is the only authority, so there is nothing to disagree with.
  • Password synchronization. Okta stores its own protected copy, updated whenever the directory password changes. Two copies exist, so mismatches are possible.

How credential conflicts appear

  • A person resets their password in Okta but the directory still holds the old one.
  • A directory password is changed by a help desk, and the sync to Okta is delayed.
  • Policies differ: the directory demands twelve characters and the cloud accepts eight.
  • An account is locked in one system while the other keeps allowing attempts.

Resolution

Choose one password authority per population, and make the other systems follow it. Align password rules between Okta and the directory. Send password resets to the authority, never around it. Where delegated authentication is used, remember that sign-in now depends on the directory being reachable, so resilience of that path matters.

sequenceDiagram
    participant U as User
    participant OK as Okta
    participant AG as Agent
    participant DC as Directory
    U->>OK: "Sign in with password"
    OK->>AG: "Verify this password"
    AG->>DC: "Check credentials"
    DC-->>AG: "Accepted"
    AG-->>OK: "Accepted"
    OK-->>U: "Signed in"
    
Fig 14.1 — With delegated authentication the directory alone decides, so no second password can disagree
Everyday Analogy

If a building has two security desks that each keep a list of approved visitors, a visitor approved at one desk may be turned away at the other. Having a single desk that keeps the list, and the other asking it, removes the argument.

15Timing and Ordering Conflicts

Even when every rule is right, changes can arrive in the wrong order. Time itself becomes a source of conflict.

Where timing hurts

  • Replication delay. A change made in one domain controller has not yet reached the one the agent reads from.
  • Import schedules. A directory import and an HR import run minutes apart, and the later one carries older data.
  • Rehire before leaver. A rehire record arrives before the earlier termination has been processed.
  • Move during import. A person is moved between organizational units while an import is reading, so they appear twice or not at all for one cycle.
  • Clock differences. Servers disagree about the current time, so “latest change wins” picks the wrong change.

Defenses

  • Keep clocks synchronized across all servers involved.
  • Schedule imports so that the highest-priority source finishes last, or, better, use priority instead of arrival order.
  • Read from a consistent, healthy directory controller close to the agent.
  • Make updates safe to repeat, so a late arrival corrects itself on the next cycle.
  • Prefer eventual convergence: design so that a wrong value fixes itself within a cycle rather than lingering.
sequenceDiagram
    participant HR as HR system
    participant OK as Okta
    participant DIR as Directory
    HR->>OK: "Rehire recorded at 09:00"
    DIR->>OK: "Account still disabled at 09:05"
    Note over OK: "Without priority, the older status wins"
    DIR->>OK: "Account enabled at 10:00"
    Note over OK: "Correct state at next cycle"
    
Fig 15.1 — An out-of-order arrival briefly shows the wrong state, and only priority or a later cycle repairs it
Everyday Analogy

When a letter and a later phone call about the same appointment reach you in the wrong order, you must decide which to believe. A rule such as “the phone call from the doctor’s office always wins” removes the guesswork, no matter which arrives first.

Time zones, daylight changes, and clock trust

Large organizations span time zones, and some systems record local time while others record universal time. A change stamped at nine in the morning in one region and eight in the evening elsewhere may be the same instant or a day apart. If any rule compares timestamps, such as latest change wins, make sure every source is converted to one standard time first. Daylight saving changes add a further trap, because an hour of the year occurs twice and another does not occur at all, so scheduled imports can run twice or be skipped on those nights.

The safest approach is to avoid relying on timestamps for important decisions. Use priority for ownership, use stable identifiers for identity, and use time only to decide when to look again. Where time is unavoidable, keep a single trusted clock source across servers and record offsets in every log.

16Write-Back Conflicts: When Okta Changes the Source

Sync normally flows into Okta, but sometimes Okta pushes changes back to a directory. This creates a second direction, and with it the risk of loops.

Why write-back exists

Many organizations still run applications that read from the directory. If Okta manages groups or attributes centrally, those applications need the changes. So Okta writes to the directory, which then becomes both a source and a target of the same data.

The loop problem

Imagine an attribute that is imported from the directory and also pushed back. Okta changes the value, the directory stores it, the next import brings it back, Okta sees a “change” and pushes again, and so on. Best case, it wastes resources. Worst case, two slightly different transformations fight each other forever, and the value drifts or flips.

Rules that prevent loops

  • Make each attribute flow in only one direction.
  • Do not import an attribute that you also push, or mark one direction as authoritative.
  • Use narrow write permissions so the push can only touch what it should.
  • Keep privileged accounts and groups out of both import and push.
  • Watch the audit logs for attributes that change repeatedly in short periods.
flowchart LR
    DIR["Directory"] -->|"Import"| OK["Okta"]
    OK -->|"Push"| DIR
    DIR -.->|"Loop risk if same attribute"| OK
    
Fig 16.1 — If one attribute travels both ways, each side keeps reacting to the other’s change
Everyday Analogy

Two people who each correct the other’s spelling in a shared note can edit the same word back and forth forever. Letting only one of them own the word ends the argument.

17Detecting Conflicts: Drift and Reconciliation

You cannot resolve what you cannot see. Detection turns silent disagreements into visible, countable work.

Two detection styles

  • Event-based. Watch each import and push for signs of trouble: records skipped, matches held for review, attributes changing repeatedly, users proposed for deactivation.
  • Comparison-based. On a schedule, compare sources with Okta and with each other, and list the differences. This is reconciliation.

What to compare

ComparisonWhat a difference means
HR active list versus enabled directory accountsLeavers still enabled, or workers without accounts
Directory A versus directory B by employee numberPeople with accounts in both, candidates for linking
Okta profile versus master source, per attributeDrift, or an unowned writer
Okta groups versus directory groupsMembership drift and push failures
Count of users per source over timeSudden jumps that suggest scope mistakes
flowchart TD
    S1["Export from source A"] --> CMP["Comparison job"]
    S2["Export from Okta"] --> CMP
    CMP --> D["List of differences"]
    D --> T{"Known and expected?"}
    T -- "Yes" --> OK["Record and ignore"]
    T -- "No" --> Q["Open a ticket with owner"]
    
Fig 17.1 — A scheduled comparison produces a difference list, and only unexpected differences become work items
i
Tip

Track the number of differences over time, not just the list. A flat, small number means healthy. A slow climb means drift is winning. A sudden spike means a recent change broke something.

Everyday Analogy

A shop that counts its cash register against the day’s receipts every evening catches a missing note the same day. A shop that counts once a year will never find out when or why it vanished.

18Resolution Strategies: Choosing Who Wins

Once a conflict is seen, a rule must decide. There are only a handful of basic strategies, and each suits different facts.

Rule

Source priority

The higher-ranked source always wins. Predictable and easy to explain. Best for attributes with a clear owner.

Rule

Latest change wins

Whichever change is newest is kept. Simple, but fragile when clocks or delays distort the order.

Rule

Fill the gaps

Take the first non-empty value in a ranked list. Good for contact details with many possible sources.

Human

Manual review

A person decides. Slow, but right for rare, risky cases such as ambiguous matches.

Safety

Quarantine

Hold the change aside and keep the old value until reviewed. Protects against mass damage.

Safety

Reject and report

Refuse the incoming change and log it. Good for data that breaks a rule, such as a malformed identifier.

Matching strategy to fact

Kind of factBest strategyWhy
Employment statusSource priority to HR with a suspension stepClear owner, high impact
Job title and departmentSource priority to HRFormal events only
Contact detailsFill the gapsMany legitimate sources
Ambiguous person matchManual review or quarantineWrong merges are risky
Bulk deactivationQuarantine above a limitProtects from scope mistakes
Malformed dataReject and reportDo not spread bad values
flowchart TD
    CF["Conflict detected"] --> R{"Clear owner for this fact?"}
    R -- "Yes" --> PR["Apply source priority"]
    R -- "No" --> I{"Risky if wrong?"}
    I -- "Yes" --> HU["Quarantine for review"]
    I -- "No" --> FG["Fill the gaps from ranked sources"]
    
Fig 18.1 — A short decision path chooses between priority, review, and gap filling
Everyday Analogy

A referee in a game has a rulebook for common calls, takes a quick look at the video for close ones, and stops the game when a serious injury is possible. Different situations get different levels of care.

19Designing a Written Conflict Policy

The best conflict strategy lives on paper, agreed by the people who own each source, before the first import.

What the policy contains

  • The list of all sources, with an owner and a contact for each.
  • For every attribute, the owning source and the fallback order.
  • The identity key and the matching rules, with examples of edge cases.
  • Group ownership rules and naming prefixes.
  • Lifecycle rules, including grace periods and bulk action limits.
  • Who reviews quarantined items, how fast, and how decisions are recorded.
  • How and when the policy itself may change.
DECISION 1Accepted

HR owns employment facts

Title, department, manager, and status come from the HR system. Directory values for these fields are ignored once the HR record exists. Reason: formal events in HR are the only legitimate trigger for these changes.

DECISION 2Accepted

Employee number is the matching key

Accounts are linked across directories only when the employee numbers agree and a second attribute does not contradict. Name-only matches are never automatic. Reason: false merges are costly.

DECISION 3Accepted

Bulk deactivation is capped

An import that would deactivate more than two percent of people in a source is held for human approval. Reason: scope mistakes are far more likely than real mass departures.

flowchart LR
    OWN["Source owners agree"] --> POL["Written policy"]
    POL --> CFG["Okta configuration"]
    CFG --> MON["Monitoring and reports"]
    MON --> REV["Periodic review"]
    REV --> POL
    
Fig 19.1 — The policy drives configuration and monitoring, and review keeps the policy current
Everyday Analogy

A neighborhood agreement on shared fences says who repairs which stretch and how costs are split. When a storm knocks one down, nobody argues. The agreement was written on a calm day for a stormy one.

20Scale: Volume, Rate Limits, and Batching

When the number of identities grows, the mechanics of moving data become a conflict source of their own.

What changes at scale

  • Imports take longer. A full import of a very large directory can run for a long time, and the next scheduled one may start before it ends.
  • Rate limits matter. Okta and the directories both limit how fast requests are accepted. Heavy imports, pushes, and automation compete for the same budget.
  • Partial failures are normal. Out of a million operations, a few will fail, and the system must carry on gracefully.
  • Peaks occur. Start of year, reorganizations, and acquisitions send thousands of changes at once.

Techniques

  • Scope imports tightly, so only people who need Okta are read.
  • Prefer incremental imports for freshness and schedule full imports outside business peaks.
  • Stagger directories so they do not all import at the same minute.
  • Throttle automation that calls Okta, and make it back off politely when told to slow down.
  • Batch changes in sensible sizes and avoid enormous one-shot jobs.
  • Split enormous groups and reduce attributes that change constantly.
SymptomLikely causeResponse
Import still running when the next startsToo frequent or too broadLengthen interval, narrow scope
Throttling messagesToo many requests at onceStagger and back off
Updates arrive late in applicationsQueues behind big jobsMove bulk work to quiet hours
Some records fail every nightBad data in a few recordsFix at source, report the list
gantt
    title A staggered import day
    dateFormat HH:mm
    axisFormat %H:%M
    section Incremental
    Directory A :a1, 00:00, 10m
    Directory B :a2, 00:15, 10m
    HR feed :a3, 00:30, 10m
    section Full
    Directory A full :b1, 02:00, 60m
    Directory B full :b2, 03:30, 45m
    
Fig 20.1 — Staggering imports and putting full ones in quiet hours keeps loads from piling up
Everyday Analogy

A city does not let every delivery truck enter the market at six in the morning. Slots are staggered so the gates do not jam. Imports, like trucks, need schedules once the traffic grows.

Thinking in budgets

A helpful way to plan for scale is to treat capacity as a budget that several activities share. Imports spend some of it, pushes to applications spend some, administrators using the console spend some, and automation scripts spend some. When the budget runs out, requests are slowed or refused, and the activity that suffers is often the one you can least afford to delay, such as a new hire needing access on their first morning. List every consumer of capacity, estimate the busiest hour, and leave headroom for surprises. When a consumer is not urgent, schedule it away from the busiest hour. When it is urgent, protect it by reducing less important consumers.

Remember also that a change which seems tiny can multiply. Adding one attribute to the mapping of a directory with fifty thousand people means fifty thousand more values to compare and, if they differ, fifty thousand updates flowing onward to every connected application. Estimate the multiplier before you press the button.

21Scale: Many Directories, Regions, and Agents

Large organizations rarely have one directory. Each additional one multiplies the conflict surface.

Layout choices

  • One Okta connection per directory or forest. Clear boundaries, separate settings, easier troubleshooting.
  • At least two agents per connection. One agent failing should not stop the import, but two agents with different directory views can also create inconsistent reads, so keep them near healthy, well-replicated controllers.
  • Regional placement. Place agents close to the directories they read, to cut delays and timeouts.

Cross-directory consistency

Every attribute mapping must be defined consistently across directories, or the same person will look different depending on which directory supplied the record. Create a shared mapping standard, and use the same naming, formats, and codes. Where directories differ in structure, translate to a common shape during import instead of at every consumer.

flowchart LR
    subgraph EU["Europe"]
      DE["Directory EU"] --> AE1["Agent 1"]
      DE --> AE2["Agent 2"]
    end
    subgraph US["Americas"]
      DU["Directory US"] --> AU1["Agent 1"]
      DU --> AU2["Agent 2"]
    end
    AE1 --> OK["Okta"]
    AE2 --> OK
    AU1 --> OK
    AU2 --> OK
    
Fig 21.1 — Each regional directory has its own pair of nearby agents feeding the same Okta organization
i
Tip

Keep a single table that lists, for every attribute, how each directory supplies it and how it is translated. When a conflict appears, that table is the first place to look, and it prevents new directories from inventing new formats.

Everyday Analogy

A multinational company with offices in many countries needs one chart of accounts, even if each office keeps local books. Without a shared structure, head office cannot add up the results.

22Idempotency, Retries, and Partial Failure

At scale, failures are routine. The question is whether a failure leaves a mess or heals by itself.

Idempotent by design

An operation is idempotent when doing it twice has the same effect as doing it once. “Set the department to Finance” is idempotent. “Add one to the counter” is not. Sync should be built from idempotent steps, so that when an import is interrupted and run again, the people already updated stay the same and only the unfinished ones change.

Handling failure

  • Retry with patience. Temporary failures such as timeouts should be retried after a growing delay, not hammered.
  • Isolate bad records. One malformed person must not block ten thousand good ones.
  • Report persistent failures. If the same record fails repeatedly, someone must see it and fix the data.
  • Avoid half-finished states. Where a change has two parts, such as moving someone and updating their groups, check both parts afterward.
  • Prefer convergence. The next cycle should repair anything the last cycle missed.
flowchart TD
    OP["Operation"] --> RES{"Succeeded?"}
    RES -- "Yes" --> DONE["Record success"]
    RES -- "Temporary failure" --> WAIT["Wait, then retry"]
    WAIT --> OP
    RES -- "Permanent failure" --> REP["Report record and continue"]
    
Fig 22.1 — Temporary failures retry with a delay, while permanent ones are reported without blocking the rest
Everyday Analogy

A postal worker who finds a locked gate tries again later, leaves a notice for an address that does not exist, and keeps delivering the rest of the route. The route as a whole is never held hostage by one door.

23Safety Rails: Caps, Previews, and Quarantine

The goal of safety rails is simple: a bad rule should hurt a few people, not everyone.

1

Preview before applying

Where possible, look at what an import would do before it does it. Check counts of creates, updates, and deactivations.

2

Cap bulk changes

Set limits on how many users one run may deactivate or modify. Anything larger waits for a human.

3

Quarantine the unusual

Hold ambiguous matches, mass changes, and malformed records in a review queue while the old values stay in place.

4

Pilot new rules

Apply a new rule to one small group first. Compare results with expectations before widening.

5

Keep a kill switch

Know in advance how to pause an import or a push quickly, and who is allowed to do it.

6

Keep a way back

Record the settings before a change and be able to restore them. Keep exports so affected users can be restored.

flowchart LR
    IMP["Import result"] --> CHK{"Within limits?"}
    CHK -- "Yes" --> APL["Apply"]
    CHK -- "No" --> HLD["Hold in quarantine"]
    HLD --> HUM["Human review"]
    HUM --> APL
    HUM --> RJ["Reject and fix source"]
    
Fig 23.1 — Results inside the limits flow through, and results outside the limits wait for a person
!
Watch Out

A safety rail that nobody tests is just a hopeful sentence in a document. Rehearse the kill switch and the restore steps on a quiet day, with the people who would use them in an emergency.

Everyday Analogy

Electrical systems use fuses and circuit breakers so that a fault in one room trips one switch instead of burning the house. Caps and quarantine are fuses for your identity data.

24Security Considerations

Sync conflicts are not only an operations problem. They can be used to gain access, or they can accidentally hand it out.

How conflicts become security problems

  • Account takeover by matching. If an attacker can create a directory account with an email that matches a privileged person, a weak match rule could link it to that person’s profile.
  • Reused identifiers. A new hire given a former employee’s identifier may inherit their access.
  • Stale leavers. Accounts left enabled in forgotten directories are favorite targets.
  • Attribute-based privilege. If a rule grants access by department, then anyone who can edit department in any source can change their own access.
  • Overpowered sync accounts. A service account with too many rights can write anywhere if it is stolen.
  • Hidden writers. Old scripts and tools that change profiles without anyone watching.

Protective habits

  • Match on strong keys that ordinary people cannot choose themselves.
  • Keep privileged and administrator accounts out of automatic matching and group push.
  • Give sync service accounts only the rights they use, and monitor them closely.
  • Limit who can edit attributes that drive access, in every source.
  • Alert on changes to matching rules, mappings, priorities, and agent registration.
  • Review hidden writers and retire or document every one.
flowchart TD
    ATT["Attacker edits a source attribute"] --> RULE{"Does a rule trust that attribute?"}
    RULE -- "Yes" --> ACC["Gains access through the rule"]
    RULE -- "No" --> BLK["No effect"]
    ACC --> DET["Detected by change alert"]
    
Fig 24.1 — Any attribute that drives access is also an attack surface, so changes to it need controls and alerts
Everyday Analogy

If a club lets anyone who claims to be a “senior member” into the lounge, then the claim itself becomes the key. Whoever can write the claim controls the door.

25Monitoring and Alerting

Monitoring is the early warning system for conflicts. The aim is to hear about trouble from a dashboard rather than from a frustrated executive.

What to watch

SignalWhat it tells youAlert when
Connected agents per directoryWhether sync and sign-in paths are healthyFewer than two are connected
Import duration and completionWhether imports finish before the next beginsDuration climbs steadily or an import fails
Created, updated, deactivated counts per importWhether a run behaves normallyCounts far above the recent average
Records held for reviewBacklog of unresolved ambiguityQueue grows or items age beyond target
Attributes changed repeatedlyFlip-flop between two writersThe same field changes many times a day
Duplicate profile candidatesMissed mergesNew duplicates appear after an import
Reconciliation difference countOverall driftNumber rises week after week
Configuration changesWho altered matching, mappings, or priorityAny change outside an approved window
Sync service account activityPossible misuse or lockoutLockout or sign-in from an unexpected place

Good alerts versus noisy alerts

An alert is only useful if someone acts on it. Every alert should name what happened, why it matters, who owns it, and what to look at first. Alerts that fire daily and are always ignored teach the team to ignore all alerts. Start with a small number of alerts that matter, tune them until they are rare and meaningful, and then add more.

flowchart LR
    LOG["Import and audit logs"] --> RULES["Alert rules"]
    AGT["Agent health"] --> RULES
    REC["Reconciliation results"] --> RULES
    RULES --> PAGE["Page on-call for urgent"]
    RULES --> TKT["Ticket for routine"]
    RULES --> DASH["Dashboard for trends"]
    
Fig 25.1 — Different signals feed alert rules that route urgent items to a person, routine ones to a queue, and trends to a dashboard
Everyday Analogy

A car dashboard shows only a few lights: oil, temperature, battery. If it flashed a hundred warnings for every small vibration, the driver would cover it with tape. Choose the few warnings that truly deserve a glance and make each one mean something.

Baselines and seasons

An alert threshold is only meaningful against a baseline. Collect a few weeks of normal numbers for imports: how many people are created, updated, and deactivated on an ordinary day, and how long runs take. Then express alerts relative to that baseline, for example when the number of proposed deactivations exceeds three times the recent average. Remember seasons: the first week of a new year, graduation months, and reorganization quarters all produce legitimate spikes. Mark these in your calendar so the team can tell an expected surge from a mistake, and so that alerts are tuned instead of silenced.

Finally, test the alerts. Occasionally create a harmless fake condition in a test setup and confirm that the right person is notified within the expected time. An alert that has never been seen to fire is an assumption, not a control.

26Troubleshooting a Conflict Step by Step

When a report arrives, such as “my title keeps changing” or “I have two accounts”, a steady routine beats guesswork.

1

Identify the family

Is it a name collision, a matching issue, an attribute dispute, a group issue, a lifecycle disagreement, a password problem, a timing issue, or a write-back loop? Use the map from earlier to sort the symptom.

2

Look at the person

Find their Okta profile and each source record. Compare stable identifiers, values, and timestamps side by side.

3

Read the history

Check audit logs to see who or what changed the value and when. This often reveals a hidden writer or a repeating pattern.

4

Check the policy

Ask what the written policy says should win. If the system behaved differently, the configuration is wrong. If it matched the policy, the policy may need to change.

5

Fix the cause, then the case

Correct the underlying rule or source first, so the problem does not return, then repair the affected profile.

6

Look for siblings

If one person had the problem, others probably do too. Search for the same pattern across the population and fix them together.

flowchart TD
    RP["User reports a problem"] --> FAM["Sort into a conflict family"]
    FAM --> CMP["Compare Okta profile with each source"]
    CMP --> HIS["Read audit history"]
    HIS --> POL{"Matches written policy?"}
    POL -- "No" --> CFG["Fix configuration"]
    POL -- "Yes" --> REV["Review the policy itself"]
    CFG --> SIB["Search for similar cases"]
    REV --> SIB
    
Fig 26.1 — A repeatable routine moves from symptom to cause to fix, and then looks for others affected
i
Tip

Write down each solved case in a short shared note: the symptom, the cause, and the fix. After a few months this note becomes a library that makes new cases faster and teaches new team members what to expect.

Everyday Analogy

A good mechanic does not replace parts at random. She listens, checks the history, tests one thing at a time, and then asks whether other cars of the same model have the same fault. Fixing the one car without asking the last question leaves the next breakdown waiting.

27The Operating Model: Roles, Queues, and Response Times

Technology alone does not resolve conflicts. People with clear roles do, and at scale the roles need to be written down.

Roles

Owner

Source owner

Responsible for the quality of one source, such as the HR system or a directory. Fixes data at its origin.

Owner

Identity platform team

Owns Okta configuration, matching, mappings, and agents, and keeps the written policy up to date.

Review

Conflict reviewers

Handle quarantined items, ambiguous matches, and unusual cases within an agreed time.

Support

Help desk

First contact for users. Has a short guide for common conflicts and knows when to escalate.

Oversight

Security and audit

Reviews privileged exceptions, access-driving attributes, and the record of manual decisions.

Queues and response targets

Type of itemExampleSuggested response goal
UrgentMass deactivation proposed, suspected false merge of privileged accountsWithin the hour
HighLeaver still enabled in a directory, sign-in blocked for a groupSame business day
NormalAmbiguous match, duplicate profile, attribute disputeWithin two business days
LowCosmetic format differencesBatch weekly

Response goals are an agreement, not a law of nature. The right numbers depend on your size and risk appetite. What matters is that they exist, that the queue is visible, and that old items are noticed. A quarantine that nobody reads is the same as having no safety rail at all, because the held change blocks real people while it waits.

flowchart TD
    ITEM["Conflict item"] --> SEV{"Severity"}
    SEV -- "Urgent" --> ONC["On-call identity engineer"]
    SEV -- "High or normal" --> REVQ["Reviewer queue"]
    SEV -- "Low" --> BAT["Weekly batch"]
    ONC --> RES["Resolve and record decision"]
    REVQ --> RES
    BAT --> RES
    
Fig 27.1 — Items are routed by severity to the right person, and every resolution is recorded
Everyday Analogy

A hospital emergency room sorts patients as they arrive: life-threatening cases go straight in, minor ones wait. Without sorting, the person with a headache blocks the person having a heart attack.

28Change Management and Testing

Most severe conflicts are caused by changes: a new mapping, a new source, a new rule. Handling change well prevents most trouble.

Changes that deserve extra care

  • Adding or removing an organizational unit from import scope.
  • Changing matching rules or the username format.
  • Changing source priority or attribute mappings.
  • Turning on deactivation, write-back, or group push.
  • Connecting a new directory or HR source.
  • Changing the sync service account or its rights.

A test set that finds problems

Test personWhat it proves
Two people with the same short nameUsername format is truly unique
One person with accounts in two directoriesMatching links correctly
Two similar people who are differentMatching refuses a false merge
Person with blank fields in one sourceBlanks do not erase good data
Person moved between unitsMoves do not look like leavers
Disabled, expired, and locked accountsLifecycle rules behave
Rehired former employeeNo clash between old and new profile
Member of nested and large groupsGroup behavior and size limits

A safe sequence

Describe the change and how to undo it. Test in a non-production setup with the test people above. Preview in production if the feature allows it. Pilot with a small group and compare results with expectations. Roll out in stages, watching the monitoring signals from the earlier chapter. Keep the previous settings recorded and the way back rehearsed.

flowchart LR
    DESC["Describe change and rollback"] --> TST["Test with test people"]
    TST --> PRE["Preview in production"]
    PRE --> PIL["Pilot small group"]
    PIL --> ROL["Staged rollout"]
    ROL --> OBS["Observe signals"]
    
Fig 28.1 — Each change travels through description, testing, preview, pilot, and staged rollout before it reaches everyone
!
Watch Out

Do not combine several risky changes in one window. If you change scope, matching, and priority together and something breaks, you will not know which one did it, and undoing all three loses the good work too.

Everyday Analogy

A pilot runs a checklist before takeoff, tests controls one at a time, and does not experiment with new equipment during a storm. The checklist is dull and effective because the cost of failure is high.

29Mergers and Migrations: Conflicts at Their Peak

No situation produces more conflicts than combining two companies or moving from one directory to another. The best defense is preparation.

Why the peak is so high

  • Two complete populations arrive together, with overlapping names, emails, and employee numbers.
  • Some people hold accounts on both sides, and some roles are duplicated.
  • Naming conventions, group structures, and attribute formats all differ.
  • Pressure to finish quickly tempts teams to skip tests.
  • The people who understood the old systems may have left.

A calm approach

1

Inventory both sides

Export people, groups, and attributes from the new source and list owners.

2

Analyze overlaps

Count collisions in names, emails, and numbers. Decide the username format and matching keys from the evidence.

3

Clean at the source

Fix typos, duplicates, and reused identifiers before import, not after.

4

Import with actions off

Bring people in without lifecycle actions, review proposed matches, and resolve ambiguities by hand.

5

Turn on features gradually

Enable group import, then updates, then deactivation, each after a quiet period of review.

6

Retire the old source slowly

Keep it read-only for a time, reconcile, and remove only when nothing depends on it.

gantt
    title A merger integration outline
    dateFormat YYYY-MM-DD
    axisFormat %b
    section Preparation
    Inventory and overlap analysis :p1, 2026-01-05, 21d
    Source cleanup :p2, after p1, 21d
    section Integration
    Import with actions off :i1, after p2, 14d
    Match review and pilot :i2, after i1, 21d
    Enable lifecycle actions :i3, after i2, 14d
    section Retirement
    Read-only and reconcile :r1, after i3, 30d
    
Fig 29.1 — Preparation and cleanup take as long as integration itself, and retirement comes last and slowly
Everyday Analogy

Two families moving into one house first decide where the furniture goes, sort out duplicate items, and label boxes. Moving everything in at once and sorting later leads to arguments and lost belongings.

People problems inside the technical problem

Integration projects often stumble on people more than on data. Two teams that used to compete may disagree about whose naming convention survives, whose directory is the master, and whose administrators keep their rights. Technical rules that quietly pick winners can feel like personal verdicts. Involve both sides in writing the ownership policy, explain the reasons behind each choice, and keep a record of exceptions. When a decision is based on evidence, such as a collision count or a data quality score, it is far easier to accept than one that seems to come from nowhere.

Plan also for the users. People whose usernames change need clear notice, a transition period if possible, and a place to ask questions. A well-run technical migration that surprises the users still feels like a failure to them.

30Failure Scenarios and Recovery

A short list of failures accounts for most of the bad days. Knowing them in advance makes them far less frightening.

FailureSymptomRecoveryPrevention
Import deactivates many usersMass sign-in failures soon after a runPause imports, reactivate people, correct scopeCaps, previews, quiet-period scope changes
False merge of two peopleOne person sees another’s accessUnlink, correct data, review the access grantedStrong keys, sample review
Flip-flopping attributeConstant change events, unstable accessSet priority, stop the second writerOne owner per attribute
Write-back loopValues drift in both systemsStop the push, repair valuesOne direction per attribute
All agents for a directory downSync and delegated sign-in stopRestore an agent, check network and accountTwo or more agents, staggered patching
Source feed sends bad dataBlank or wrong values appear widelyQuarantine the feed, restore from exportValidation and thresholds on incoming data
Old source retired too earlyRemaining users lose accessReconnect the source, relinkRead-only period and dependency checks

A recovery rhythm

  • Stop the bleeding. Pause the import or push that is causing damage. A pause is cheap and reversible.
  • Protect emergency access. Use a tightly controlled break-glass account that does not depend on the directory.
  • Communicate early. Tell support teams and affected users what is happening and when to expect an update.
  • Find the cause. Check recent changes first, since most incidents follow a change.
  • Repair and verify. Fix the cause, restore affected people, and verify with real users.
  • Learn. Write down the cause and add the alert or check that would have caught it sooner.
flowchart TD
    INC["Incident"] --> STOP["Pause the suspect import or push"]
    STOP --> ACC["Confirm emergency access works"]
    ACC --> COM["Communicate status"]
    COM --> CAU["Find recent change or cause"]
    CAU --> FIX["Repair and verify"]
    FIX --> LRN["Record lessons and add checks"]
    
Fig 30.1 — Pause first, protect access, communicate, then diagnose, repair, and learn
Everyday Analogy

When a pipe bursts, the first act is turning off the water at the main valve, not mopping the floor. Pausing the sync is that valve. Cleaning up is easy once the flood has stopped.

31Design Patterns That Work

These approaches have repeatedly proved themselves. Adapt them to your own situation.

PATTERN 1Recommended

One owner per attribute

Every attribute has a single authoritative source, written in the policy. Other sources may fill gaps but never overwrite. This removes flip-flopping at its root.

PATTERN 2Recommended

Stable identifiers as the real key

Identity is anchored to an immutable identifier, and names and emails are treated as labels that may change. Renames, moves, and rebrands then never create a new person.

PATTERN 3Recommended

Prefer missing a merge over a false merge

Matching is tuned toward caution. Ambiguous cases go to a review queue, and duplicates are cleaned up later at leisure.

PATTERN 4Recommended

Suspend before deactivating

A departure signal first suspends access and starts a grace period. Only when the period ends without correction does deactivation occur.

PATTERN 5Recommended

Fuses on every bulk action

Caps, previews, and quarantine are standard on any rule that can touch many people at once.

PATTERN 6Recommended

Reconcile on a schedule

Automatic comparison of HR, directories, and Okta runs regularly, and the number of differences is a tracked health measure.

PATTERN 7Recommended

One direction per attribute

No attribute is both imported and pushed. Where Okta manages a value for a legacy application, the directory is a target only for that attribute.

flowchart TD
    SRC["Many sources"] --> OWN["One owner per attribute"]
    OWN --> KEY["Stable identifiers as keys"]
    KEY --> MAT["Cautious matching"]
    MAT --> RAIL["Caps and quarantine"]
    RAIL --> PROF["Clean Okta profile"]
    PROF --> REC["Scheduled reconciliation"]
    REC --> OWN
    
Fig 31.1 — The patterns reinforce one another in a loop of ownership, identification, caution, protection, and checking
Decide who wins before the data disagrees.
Everyday Analogy

A well-run kitchen has a single head chef for each station, labels on every container, and a rule to throw out anything unmarked. The rules are not clever, but they stop mistakes from reaching the table.

32Anti-Patterns to Avoid

These habits look convenient and cause lasting trouble. Learn to recognize them early, especially in inherited setups.

Anti-patterns

  • Last writer wins by accident. No priority is set, so whichever import ran last decides.
  • Matching on names. Different people merged because they share a name.
  • Blanks as deletes. A weaker source with an empty field erases a correct value.
  • Unlimited deactivation. A scope mistake empties the company overnight.
  • Both-way attributes. The same field imported and pushed, creating loops.
  • Hidden writers. Scripts that change profiles with no owner or record.
  • Quarantine with no reader. Held items pile up and block real people.
  • Reconciling only the main directory. Leavers survive in smaller ones.
  • Fixing cases, not causes. The same ticket returns every month.
  • Untested rollback. The way back is discovered to be broken during the incident.

Better habits

  • Explicit priority. One owner per attribute, written down.
  • Strong-key matching. Employee number plus a second check.
  • Blanks mean no opinion. Empty values from non-owners are ignored.
  • Capped bulk actions. Previews and approval above a threshold.
  • One direction per attribute. Import or push, never both.
  • Known writers only. Every automation documented and monitored.
  • Staffed review queue. Age of oldest item is watched.
  • Reconcile every directory. HR compared with all of them.
  • Root cause fixes. Search for siblings and prevent repeats.
  • Rehearsed recovery. Kill switch and restore tested on quiet days.
Anti-patternWhat it causesQuick fix
No source priorityValues flip with each importRank sources per attribute
Name-only matchingFalse merges, data exposureMatch on employee number plus check
Blank overwritesMissing managers and titlesIgnore blanks from weaker sources
Uncapped deactivationMass lockoutsAdd a percentage cap and approval step
Hidden automationUnexplained changesInventory writers and use audit logs
!
Watch Out

The most dangerous anti-pattern is the one that has run quietly for years. A setup that has never failed feels safe, but it may simply never have met the condition that breaks it. Review old configurations as if they were new, because the people and data around them have changed.

Everyday Analogy

A house with old wiring may glow happily for decades. The danger is not what it does every day but what it does on the evening when every appliance runs at once. Anti-patterns hide until the load arrives.

33Trade-Offs, Best Practices, and Common Mistakes

Every choice gives something up. Naming the trade-offs makes decisions deliberate and defensible.

The main trade-offs

ChoiceGainCostLean toward it when
Strict single owner per attributePredictability, no flip-floppingOwner mistakes spread, slower fixes outside ownerClear authoritative system exists
Ranked sources with gap fillingResilience, fewer empty fieldsHarder to explain where a value came fromSeveral partial sources, such as contact details
Latest change winsSimplicityFragile with clock or delay problemsLow-risk, self-service attributes
Cautious matching with reviewSafe from false mergesReview workload and some duplicatesPrivileged or sensitive populations
Automatic matching on strong keysSpeed and low effortBad source data spreads quicklyClean, well-maintained keys
Quick deactivationFaster closing of accessMore false lockoutsHigh-risk environments with good data
Suspend then deactivateTime to catch errorsShort delay before final removalMost organizations
Frequent importsFresh dataMore load, more chances to apply bad data fastRapidly changing populations
Push to directoryLegacy applications stay currentWrite rights and loop riskApplications cannot yet use Okta directly

Best practices

  • Draw every source, its owner, and its data flows before configuring anything.
  • Write the conflict policy and get each source owner to agree to it.
  • Audit overlaps in names, emails, and numbers across all sources first.
  • Choose unique usernames and stable identifier keys.
  • Rank sources per attribute and ignore blanks from non-owners.
  • Prefix imported groups and decide group direction explicitly.
  • Start with lifecycle actions off, preview, pilot, and roll out in stages.
  • Cap bulk actions and keep a rehearsed kill switch.
  • Monitor agents, import counts, review queues, and configuration changes.
  • Reconcile all sources on a schedule and track the difference count.

Common mistakes

  • Assuming imports from different directories will not collide.
  • Treating a missing record as a leaver without a grace step.
  • Forgetting that a moved account may look like a new one.
  • Combining several risky changes in one window.
  • Leaving the review queue unstaffed.
  • Letting people who can edit access-driving attributes go unmonitored.
  • Ignoring clocks and time zones across systems.
quadrantChart
    title Choosing a resolution strategy
    x-axis Low impact if wrong --> High impact if wrong
    y-axis Clear owner exists --> No clear owner
    quadrant-1 Human review
    quadrant-2 Gap filling with checks
    quadrant-3 Latest change or gap filling
    quadrant-4 Strict priority with caps
    Contact details: [0.2, 0.7]
    Self-service nickname: [0.1, 0.3]
    Job title: [0.6, 0.15]
    Employment status: [0.9, 0.1]
    Ambiguous person match: [0.9, 0.9]
    
Fig 33.1 — The higher the impact of being wrong, the stricter the strategy, and the less clear the owner, the more people should be involved

This picture is a way of thinking, not a measurement. Low-impact facts with no clear owner can use flexible rules. High-impact facts with a clear owner should use strict priority with caps. High-impact facts with no clear owner deserve human attention, because that combination is where wrong guesses become incidents.

Everyday Analogy

A traveler packs differently for a day trip and a month abroad. Light trips allow improvisation, while serious ones need lists and backups. Match the care you take to the cost of being wrong.

34Governance, Metrics, and Continuous Improvement

A conflict program improves only if you measure it. A few simple numbers tell you whether things are getting better or worse.

Measures worth tracking

MeasureWhy it mattersHealthy direction
Reconciliation differencesOverall drift between systemsFlat or falling
Items in the review queue and oldest ageWhether safety rails are staffedSmall and short
Duplicate profile candidatesMissed merges and data qualityFalling
Attributes with repeated changesHidden flip-flop conflictsNear zero
Leavers still enabled anywhereReal security exposureZero, quickly corrected
Incidents caused by sync changesQuality of change managementFalling
Time to resolve by severityOperating model healthMeets targets

The improvement loop

  • Review monthly. Look at the measures and the top causes of conflicts. One chart of the biggest cause per month is often enough.
  • Fix the sources. Many conflicts trace to bad data that source owners can clean permanently. Share the list with them.
  • Update the policy. When a new kind of case appears twice, add a rule for it.
  • Retire old rules. Remove mappings, scripts, and exceptions that no longer serve a purpose.
  • Share what you learn. Publish short notes so support, security, and source owners see patterns.
flowchart LR
    MEA["Measure"] --> ANA["Find top causes"]
    ANA --> FIX["Fix sources and rules"]
    FIX --> POL["Update policy"]
    POL --> MEA
    
Fig 34.1 — Measuring, analyzing, fixing, and updating the policy forms a loop that steadily removes conflicts
i
Tip

Celebrate a falling conflict count with the source owners who made it fall. Data quality is a shared effort, and teams that see their work valued keep improving their part.

Everyday Analogy

A gardener who walks the beds every week and pulls the first weeds never faces a jungle. A gardener who visits once a year faces a weekend of labor. Regular small attention beats occasional heroic cleanup.

35Worked Example: Northwind Logistics

To bring everything together, here is an invented company and a complete conflict strategy. The company, numbers, and names are made up for teaching.

The company

Northwind Logistics is a fictional freight company with 42,000 employees and contractors. It has a main corporate directory, two acquired companies with their own directories, a regional directory for warehouse staff that has never been fully cleaned, and a cloud HR system. Five years of mergers left it with 3,100 people who have accounts in more than one directory, an unknown number of orphaned accounts, and a help desk that receives about 400 identity tickets a month, a quarter of which are “my details keep changing” or “I have two accounts”.

42,000
People in scope
4
Directories
3,100
Multi-directory people
400
Identity tickets a month

The strategy

AreaDecision
Attribute ownershipHR owns title, department, manager, status. Directories own sign-in names and infrastructure groups.
MatchingEmployee number plus corporate email domain check. Name-only never automatic. Ambiguous cases to a review queue.
UsernamesEmail-style names with company element, generated once and never reused.
GroupsSource prefixes, rules-based groups in Okta for access, no push to the warehouse directory except one reviewed group.
LifecycleHR status drives; suspend for ten days, then deactivate; cap of two percent per run.
ScaleStaggered incremental imports every thirty minutes; full imports at night; two agents per directory in the same region.
MonitoringAlerts for fewer than two agents, big import counts, repeating attributes, and aging review items.
ReconciliationWeekly HR versus all directories, with a published difference count.
flowchart LR
    HR["HR system"] -->|"Owns business facts"| OK["Okta profile"]
    D1["Corporate directory"] -->|"Sign-in facts"| OK
    D2["Acquired directory 1"] -->|"Sign-in facts, prefixed groups"| OK
    D3["Acquired directory 2"] -->|"Sign-in facts, prefixed groups"| OK
    D4["Warehouse directory"] -->|"Read mostly, cleaned first"| OK
    OK --> Q["Review queue and caps"]
    OK --> APP["Applications"]
    
Fig 35.1 — Four directories and HR feed one Okta profile, with ownership rules, a review queue, and caps in the path

How the first six months went

The overlap audit found 3,100 multi-directory people, of whom 140 had employee numbers that disagreed between directories because of typing errors. HR corrected them, and automatic linking then worked for nearly everyone. About 60 cases stayed in the review queue and were resolved by hand in two weeks. Source priority ended the flip-flopping of titles, and the count of attributes changing repeatedly fell from hundreds to a handful in the first month.

In month two, an administrator moved a warehouse organizational unit into a new container, and an import proposed to deactivate 1,900 people. The two percent cap held the run, an alert reached the on-call engineer within minutes, and the scope was corrected before any account was touched. In month four, reconciliation found 210 leavers still enabled in the warehouse directory, which was cleaned and added to the weekly report. By month six, identity tickets about conflicts had fallen from about one hundred a month to about twenty.

Result

Northwind now treats conflicts as a measured, owned process. The most valuable work was not clever technology. It was agreeing who owns each fact, choosing strong keys, cleaning sources, and adding fuses to every bulk action.

Everyday Analogy

A city merging four old phone books into one first agrees which book is trusted for which kind of entry, then corrects the obvious errors, and only then prints. The printing is the easy part.

36Frequently Asked Questions

Short answers to questions that come up often. Okta features, limits, and menu names change over time, and some depend on your plan, so confirm exact details in the current Okta documentation.

1

What is a directory sync conflict?

It is a disagreement between two sources about the same fact, or a record that does not fit what Okta already holds. Something has to decide which value or identity is kept.

2

Does the latest change always win?

Not unless you design it that way. Outcomes depend on source priority, mappings, and matching rules. Relying on arrival order is fragile, so explicit priority is safer for important attributes.

3

Why does an attribute keep changing back?

Usually two sources write it with equal priority, or a stale source restores an old value. Give one source ownership, or lower the priority of the stale one.

4

How do I avoid merging two different people?

Match on strong keys such as employee number, add a second check, never rely on names alone, and review a sample of proposed matches before enabling automatic linking.

5

What if one person has accounts in several directories?

Link them to one Okta profile using reliable matching, and decide which directory supplies which attributes. Treat the extra accounts as additional sign-in sources for the same person.

6

Should blank values overwrite existing ones?

Generally no, unless the source is the owner and blank truly means removal. Treat blanks from non-owners as no opinion.

7

How do I stop a bad import from locking out thousands?

Preview where possible, cap bulk deactivation per run, change scope in quiet periods, alert on large proposed changes, and keep a rehearsed way to pause imports.

8

How should I handle groups with the same name in different directories?

Prefix imported groups with the source name, and use rules in Okta to combine audiences where needed.

9

Is it safe to push groups or attributes back to a directory?

It can be, with narrow write rights, one direction per attribute, and privileged accounts excluded. Without these, loops and unwanted changes become likely.

10

Who should own employment status?

The HR system, whenever one exists. Directories then follow, with a suspension step and reconciliation to catch leftovers.

11

How often should I reconcile?

Weekly is a common starting point for large estates, and daily for high-risk checks such as leavers still enabled. Choose a rhythm that matches your risk and capacity.

12

How do I know if a conflict is a security issue?

Ask whether the attribute or match drives access, whether privileged accounts are involved, and whether a person could have chosen the conflicting value themselves. If yes, treat it as security.

13

What should I do first in an existing messy estate?

Inventory sources and writers, run an overlap and drift report, fix the highest-risk problems such as leavers and false merges, then write the ownership policy.

14

Do I need a person reviewing conflicts?

Yes for ambiguous matches and unusual bulk changes. Automation handles the common cases, and humans handle the cases where being wrong is expensive.

15

Where should I start?

Draw your sources, audit overlaps, decide owners and matching keys, set caps and monitoring, then connect one source at a time with lifecycle actions off.

37Summary and Key Takeaways

Resolving directory sync conflicts at scale is mostly about clear ownership, careful identification, and safe change.

Key Takeaways

  • Conflicts are decided by configuration. Source priority, mappings, and matching rules choose the outcome, so make them explicit and written down.
  • Give every attribute one owner. HR for business facts, directories for sign-in facts, and gap filling only where no owner exists.
  • Identify people by stable keys. Use unique usernames and strong matching keys, and prefer a missed merge over a false merge.
  • Add fuses to bulk actions. Previews, caps, quarantine, a kill switch, and a rehearsed way back keep mistakes small.
  • Detect before users do. Monitor agents and import counts, and reconcile all sources on a schedule so drift is visible.
  • Operate with roles and queues. Source owners, reviewers, and on-call engineers need clear duties and response targets.
  • Improve continuously. Measure, fix sources, update the policy, and retire old rules, because conflicts cluster around change.
i
Final Note

Okta changes features, limits, and menu names over time, and some capabilities depend on your plan. Use this post to understand the ideas, and confirm exact steps and requirements in your own admin console and the current Okta documentation before building.

Many sources, one agreed story, and a safe way to fix it when they disagree.