Bi-Directional Sync Conflict Resolution in Okta
When two systems can both change the same person's record, someone has to decide who wins. A first-principles guide to how data moves between Okta and the systems around it, why it collides, and how to design rules so that collisions are rare, visible, and settled the same way every time.
Cedarwood Healthcare Group runs 7,000 staff across clinics and hospitals. On Monday morning, Dr. Mehta’s phone number is changed in the human resources system. On the same morning, Dr. Mehta updates it herself in an application that is connected to Okta. Two different numbers now exist for one person, each entered correctly, each at about the same time. A few minutes later, each system sends its version to the other. Which number is right? If nobody decided in advance, the answer depends on luck, and the system may even bounce the two numbers back and forth all day.
This is a sync conflict, and it is one of the most common causes of quiet, hard-to-explain problems in identity projects. Wrong email addresses, managers that flip between two names, accounts that come back to life after being switched off, and groups that gain and lose members for no visible reason are all symptoms of the same disease: two-way data flow without clear rules.
This guide teaches the subject from zero. We define what synchronization and conflicts are, look at the pieces Okta provides for moving and owning data, and then go inside to see how a change travels, where timing gets tricky, and what strategies exist for settling disagreements. After that we cover design choices, loops, duplicates, deletions, groups, passwords, detection, human review, failure handling, scale, security, monitoring, testing, trade-offs, and common traps. No earlier knowledge is assumed. Okta feature names, defaults, and limits change over time, so treat the product details here as guidance and confirm them in the current official documentation before building.
1Why Two-Way Sync Is Hard
Copying data in one direction is easy. Copying it in both directions invites arguments, and computers argue without ever noticing.
One-Way Is Calm
In a one-way flow, one system is the boss and the other follows. The human resources system says Dr. Mehta’s number is one thing, and the directory simply accepts it. If someone edits the follower, the next update from the boss overwrites the edit. Nobody has to decide anything, because the answer is built into the direction of the arrow.
Two-Way Is Busy
In a two-way flow, both sides can change data, and both sides send their changes to each other. That is useful. A person can fix their own phone number in a self-service application, and the fix reaches the directory. But it creates new questions. What if both sides changed the same field before either update arrived? What if the update from one side makes the other side send an update back, which makes the first side send another, forever? What if one side deleted the person and the other side just edited them?
Flip-flopping values
A field changes back and forth between two values every few minutes.
Lost edits
A person fixes their data and finds the old value back the next morning.
Zombie accounts
A deactivated person is reactivated by a stray update from another system.
Duplicate people
The same person appears twice because two systems created them separately.
Silent drift
Two systems slowly disagree about many people and nobody notices until an audit.
Two people editing the same paper document, each at their own desk, will each send the other their copy. Without a rule such as “the manager’s version wins,” or a way to compare the pages, the office ends up with two papers and an argument. Sync conflict resolution is that rule, written down before the argument starts.
The best conflict is the one that cannot happen. Most of this guide is about designing data ownership so that conflicts are rare, and only then about settling the ones that remain.
2What Bi-Directional Sync Is, and Is Not
Words like sync, import, and push are used loosely. Let us make them precise.
What It Is
Synchronization means keeping the same facts about the same thing consistent in two places. Bi-directional means changes can start on either side and travel to the other. In an Okta project, this usually means that some information about people flows into Okta from a source such as a human resources system, a directory, or an application, and some information flows out from Okta to those applications. When both directions carry the same kind of information, you have a two-way relationship, and you need rules.
What It Is Not
- It is not a database transaction. Two systems connected over the internet cannot change at the exact same instant. There is always a gap, and the gap is where conflicts live.
- It is not guaranteed to be instant. Imports can run on a schedule, pushes can be delayed, and queues can back up.
- It is not always field-for-field. Systems name and shape the same fact differently, and mappings translate between them.
- It is not automatic wisdom. The tools move data. They do not know which side is right unless you tell them.
Words Used in Okta Projects
| Word | Plain meaning |
|---|---|
| Import (inbound) | Bringing people and attributes from an outside system into Okta |
| Push or provisioning (outbound) | Sending people, attribute changes, or groups from Okta to an application |
| Profile mastering | Declaring which source owns the facts about a person |
| Attribute mapping | The table that says which field in one system matches which field in another |
| Reconciliation | Comparing both sides and fixing differences |
| Source of truth | The system whose value wins when there is a disagreement |
Two shops sharing one price list by phone calls will sometimes have different prices at the same moment, because a call takes time. Synchronization is the habit of calling often and agreeing who sets the price. It is never a magic window that shows both shops the same sheet at the same instant.
3Core Concepts: The Vocabulary of Conflict
A dozen terms carry most of the conversation. Each is explained with an example from Cedarwood.
Record
All the facts about one person in one system. Dr. Mehta’s record in the directory differs from her record in the scheduling app.
Attribute
One fact in the record, such as phone number, title, or manager.
Conflict
Two systems hold different values for the same attribute of the same person, and both changed since they last agreed.
Master or authoritative source
The system trusted to be right for a given attribute. Human resources may be master for title, while the person is master for a preferred display name.
Last writer wins
A rule that keeps whichever change happened most recently. Simple, but it can discard good changes.
Echo or loop
A change sent to a system comes straight back as if it were a new change, and is sent again, forever.
Idempotent
An operation that gives the same result if repeated. Setting phone to a given number is idempotent. Adding 1 to a counter is not.
Eventual consistency
The promise that systems will agree after a while if changes stop, but not at every moment.
Drift
Slow, unnoticed divergence between systems that should match.
Tombstone
A marker saying a record was deleted, so that other systems do not recreate it by mistake.
Two diaries keeping the same family calendar will disagree when each owner scribbles a change without telling the other. The conflict is not the scribble. It is the gap in time and knowledge between two valid scribbles.
A disagreement is not a conflict unless both sides changed. If only one side changed, the other simply needs to catch up. Treating every difference as a conflict creates endless pointless alerts.
4The Kinds of Conflict
Not all conflicts look alike. Naming them helps you pick the right remedy for each.
| Kind | What happens | Example at Cedarwood |
|---|---|---|
| Update versus update | Both sides change the same attribute | HR and the person both change the phone number |
| Update versus delete | One side edits, the other removes the record | HR deactivates a nurse while an app updates her title |
| Create versus create | Both sides create the same person independently | A contractor appears in the directory and in the app on the same day |
| Echo or loop | A change bounces between systems | Display name is reformatted by each side |
| Format mismatch | The same value looks different on each side | Phone with and without country code |
| Membership conflict | Group membership differs and both sides add or remove | An app adds a user to a group that Okta rules removed |
| Status conflict | Active versus inactive disagreement | Okta suspends an account while the app reactivates it |
| Key conflict | Identifiers that should be unique collide | Two people with the same email address |
| Ordering conflict | Updates arrive in the wrong order | Old title arrives after new title |
Real Conflicts and Fake Ones
Format mismatch and ordering problems are often mistaken for real conflicts. Fixing the mapping, such as storing phone numbers in one agreed format, removes a whole category of noise. Only once the noise is gone can you see the real conflicts: two people or two systems making different decisions.
A doctor sorts coughs into cold, allergy, and infection before choosing a remedy. A single cough syrup for all of them would cure few and harm some. Sorting conflicts into kinds lets each get the right treatment.
5Okta’s Building Blocks for Data Movement
Before settling conflicts, we need to know the parts Okta provides for bringing data in and pushing it out.
| Block | What it does | Direction |
|---|---|---|
| Universal Directory | Okta’s central store of user profiles and attributes | Center |
| Profile sources | Systems that supply and own profile data, such as a human resources system or a directory | Inbound |
| Import | Pulls users and attributes from an application into Okta, on a schedule or on demand | Inbound |
| Profile mastering and priority | Lets Okta decide which source wins for each attribute when several sources feed the same user | Inbound |
| Provisioning to apps | Creates, updates, and deactivates accounts in applications | Outbound |
| Push groups | Mirrors Okta group membership into applications | Outbound |
| Attribute mappings | Translate fields between Okta and each application, in each direction | Both |
| SCIM | A standard language many applications use for provisioning requests | Both |
| Workflows and hooks | Automation that reacts to events, useful for detection and repair | Both |
| System Log | The record of what happened and when | Evidence |
Exact feature names, which applications support which features, and the edition you need vary. Confirm the capabilities of your integrations in the integration’s own documentation. A connector that supports pushing profile changes may not support importing them, and the reverse is also common. That mismatch alone can produce one-way flows you did not intend.
The Two Roles of an Application
An application connected to Okta can play two roles at once. It can be a target, receiving accounts and updates from Okta. And it can be a source, supplying people and attributes into Okta. When an application plays both roles for the same attributes, you have created a two-way flow, whether you meant to or not.
flowchart LR
HR["HR system: source"] -->|"import"| UD["Okta Universal Directory"]
DIR["Directory: source"] -->|"import"| UD
UD -->|"provision and push"| APP1["Application A: target"]
UD -->|"provision and push"| APP2["Application B: target"]
APP2 -->|"import: also a source"| UD
A town’s main post office receives letters from many neighborhoods and sends letters back out. When one neighborhood both sends and receives the same kind of letter, the post office needs clear rules about which letters take priority.
6Profile Sourcing and Mastering
The single most effective conflict-prevention tool is deciding, attribute by attribute, who owns each fact.
The Idea of Mastering
Okta allows a profile source, such as a human resources system or a directory, to be the master of a user’s profile. When a source masters a profile, its values flow into Okta and overwrite local edits for the attributes it controls. Okta also supports scenarios with more than one source for the same user, where a priority order decides which source wins for each attribute. Details such as attribute-level control and how many sources are allowed depend on version and settings, so verify them in current documentation.
Ownership by Attribute, Not by System
Many teams try to pick one system as master of everything. That rarely fits real life. Human resources is the best source for legal name, job title, manager, and department. The person is the best source for a preferred nickname, a mobile number for alerts, and a profile photo. An application may be the best source for a license role it manages itself. Assigning ownership per attribute turns one big argument into a small table of calm decisions.
| Attribute | Best owner | Reason |
|---|---|---|
| Legal name | HR system | Official, audited |
| Job title, department, manager | HR system | Changes through approved workflows |
| Employment status and dates | HR system | Drives joiner and leaver handling |
| Work email and username | Okta | Created by identity rules, must be unique |
| Preferred name | The person | Personal choice, low risk |
| Personal contact numbers | The person | Only they know their current number |
| Application-specific role | The application or Okta groups, but never both | Depends on design |
| Group membership for access | Okta rules | Governance depends on one controlled source |
In a school, the office keeps the official register of names and grades, but the pupil chooses their own favorite color on the class chart. Nobody argues, because everyone knows who owns which line.
Write the ownership table first, before touching any configuration. It is the most valuable page in the whole project, and it takes an afternoon.
7Architecture and Components
Let us name the parts that cooperate when a change travels through an Okta-based sync design.
Systems of record
Human resources, directories, and applications that hold facts about people. Each has its own data model and its own rules.
Connectors
The adapters that talk to each system, using standards such as SCIM or vendor interfaces. They carry limits, such as what they can read or write.
Mappings
Rules that translate fields between systems and say which direction each field flows.
Universal Directory
The central profile store, where the merged result of all sources lives.
Mastering and priority rules
The settings that decide who wins when more than one source supplies the same attribute.
Automation
Flows and event handlers that detect disagreements, repair simple ones, and raise tickets for hard ones.
Logs and monitoring
Records of every import, push, and failure, streamed to a place where people can search and alert on them.
flowchart TD
HR["HR system"] --> C1["Connector in"]
APP["Application with self-service edits"] --> C2["Connector in"]
C1 --> MP["Mastering and priority rules"]
C2 --> MP
MP --> UD["Universal Directory: merged profile"]
UD --> MAP["Outbound mappings"]
MAP --> C3["Connector out"]
C3 --> APP
UD --> LOG["System Log"]
LOG --> MON["Monitoring and alerts"]
MON --> AUTO["Detection and repair flows"]
AUTO --> UD
A newspaper has reporters, an editor who decides which version of a story runs, a printing press, and a corrections desk that watches for mistakes. Mastering rules are the editor, and the corrections desk is the detection and repair automation.
8Internal Working: How Import and Push Behave
To resolve conflicts you must know how each direction really behaves, including its delays and quirks.
Import: Pulling Facts In
An import reads the user list and attributes from a source and compares them with what Okta already holds. Imports can be run on a schedule or started by hand, and some sources can also send change notifications. During an import, Okta must decide which incoming person matches which existing person, using matching rules such as username or email. People who match are updated, people who do not match may be created or held for review, and people who have disappeared from the source may be deactivated, depending on settings. Behavior varies by integration, so read the integration’s notes.
- Full versus incremental. A full import compares everything and can take a long time on large directories. An incremental import looks only at recent changes and is faster, but depends on the source reporting changes reliably.
- Matching. A loose match joins the wrong people. A strict match creates duplicates. Choose the field that is truly unique.
- Confirmation. Some setups hold new or unmatched users for an administrator to confirm. This is a gentle form of conflict handling.
Push: Sending Changes Out
When a profile changes in Okta, the platform can send the change to each assigned application. Each change becomes a request to the application, and the application answers success or failure. If the application is slow or unavailable, the request is retried or recorded as a failure that an administrator must handle. A push can also be triggered by someone changing the attribute mapping, which causes bulk updates for many users.
The Hidden Loop
If an application is both a push target and an import source for the same attribute, a push from Okta changes the application, and the next import reads that change back as if it were new. If the value is not byte-for-byte identical, such as a trailing space or a different capitalization added by the application, Okta sees a change, may push again, and the loop begins.
Two clerks each copy new entries from the other’s ledger. If one clerk writes the date in a different style, the other sees a “new” entry, copies it back with a tweak, and so on. They are both being diligent, and that diligence is the problem.
9Data Flow and Lifecycle of a Change
Follow Dr. Mehta’s phone number through a well-designed system, and then through a badly designed one.
sequenceDiagram
participant P as Dr. Mehta
participant A as Scheduling app
participant O as Okta
participant H as HR system
P->>A: Updates mobile number
A-->>O: Change detected at next import
O->>O: Check owner of mobile number
O->>O: Owner is the person, accept change
O->>A: Confirm no push needed, value already matches
H->>O: Sends HR record with old mobile number
O->>O: HR is not owner of mobile number, ignore field
O->>O: Log decision with both values
Stages of a Change
| Stage | What happens | Where conflicts can arise |
|---|---|---|
| Origin | Someone or something edits a value | Two origins at once |
| Detection | The change is noticed by import or notification | Delay, so other edits sneak in |
| Matching | The record is tied to the correct person | Wrong or duplicate matches |
| Decision | Ownership and priority rules choose a winner | Missing or unclear rules |
| Storage | The winning value is saved in the central profile | Format changes causing false differences |
| Propagation | The new value is pushed to other systems | Echo back to the origin |
| Confirmation | Each system acknowledges or fails | Partial success leaves systems apart |
| Audit | The event is logged | Missing context makes later diagnosis hard |
A Badly Designed Flow
In the poor version, nobody owns the phone number. The scheduling app’s edit is imported, then overwritten by the next human resources feed, which carries the old number. The person edits again, and again it is overwritten. Her edits seem to vanish. The cause is not a bug in any tool. It is an unanswered question about ownership.
A relay race hands the baton at set points. If two runners both think they hold it, or neither does, the team loses. Each stage in the lifecycle is a handover, and conflicts hide in the handovers.
10Consistency Models in Plain Words
Computer scientists have names for the different promises a system can make about agreement. Knowing three of them helps you choose the right promise for each attribute.
Strong consistency
Everyone sees the same value at the same time. It is expensive and rarely possible across separate products connected over the internet.
Eventual consistency
Systems may differ for a while but will agree once changes stop. This is the normal promise in identity projects.
Read-your-own-writes
A person who makes a change sees their own change at once, even if others see it later. It makes self-service feel responsive.
Choosing a Promise per Attribute
Because strong consistency is rarely available, the practical question is how long a gap you can tolerate, and what you do about it. For termination and sensitive groups, the gap must be minutes, so you use fast triggers and alerts. For phone numbers, a day is fine. Say so in the ownership table, next to each attribute, and then measure whether you meet it.
When a teacher updates the notice board, pupils in the same hallway see it instantly, while a pupil at home learns it at the next phone call. The board was changed once, but the news arrives at different times. What matters is that it eventually arrives, and that the important notices travel fastest.
11Time, Order and Eventual Consistency
Time is the villain of most sync stories. Clocks disagree, messages arrive late, and the order of arrival may not match the order of events.
Why “Most Recent” Is Slippery
A rule like “the newest change wins” sounds fair, but newest by what clock? The clock of the application, of Okta, or of the person’s phone? Clocks drift by seconds or even minutes. Systems may record the time of the edit, or only the time the edit was noticed by an import, which can be hours later. A change made yesterday and detected today may look newer than a change made this morning and detected an hour ago.
Order of Arrival
Messages that leave in order can arrive out of order when retried or sent through different routes. If an update “title: Manager” is delayed and arrives after “title: Director,” the system may regress. Defenses include version numbers, change timestamps from the source system itself, and comparing the incoming value with the current one before overwriting.
Accepting Eventual Consistency
A mature design accepts that systems will briefly disagree, defines how long is acceptable, and sets alarms for when the gap is too long. This is called an eventual consistency window. For a phone number, hours may be fine. For a termination, minutes matter.
| Attribute type | Acceptable delay | Why |
|---|---|---|
| Employment termination | Minutes | Security risk if access lingers |
| Group membership for sensitive systems | Minutes to an hour | Access control depends on it |
| Job title, department | Hours | Low immediate risk |
| Personal phone, photo | A day | Convenience only |
Starlight you see tonight left the star long ago. Distant messages describe the past. A sync design must ask, “How old can my picture of the other system be before it harms me?” and then keep within that age.
Avoid “last writer wins” for anything that matters unless you trust the timestamps. Clock mistakes silently decide the winner, and the loser never knows.
12Native Features, Automation or Custom Code?
When a conflict needs special handling, you can often choose between three tools. Picking the lightest one that does the job keeps the system understandable.
| Option | Best for | Watch out for |
|---|---|---|
| Native settings: mastering, mappings, directions | Ownership, priority, and one-way flows | Limited to what the product exposes |
| Visual automation such as Workflows | Detection, notification, small repairs, queue creation | Flows must be owned, tested, and capped |
| Custom code or an integration platform | Complex merging rules, unusual systems | Maintenance cost, security review, and hidden logic |
A Simple Rule
Start with native settings. If they cannot express the rule, use automation for detection and small repairs. Reach for custom code only when the first two fail, and then keep the code small, tested, and documented. Every layer you add is another place where a conflict can hide, and another thing someone must understand when you move on.
When fixing a leaking tap, you try tightening it, then replacing the washer, and only last, replace the whole fitting. Reaching for the largest tool first costs more and breaks more.
13Conflict Resolution Strategies
When a real conflict happens, there are only a few honest ways to settle it. Each has strengths and costs.
| Strategy | How it works | Strength | Weakness |
|---|---|---|---|
| Source of truth wins | A named system always wins for an attribute | Predictable, easy to explain | Ignores good edits from the other side |
| Priority list | Several sources ranked; the highest available wins | Handles multiple feeds | List must be maintained |
| Last writer wins | Newest change wins | Simple, no setup | Depends on trustworthy time |
| Field-level merge | Each attribute decided on its own | Keeps the most good data | More rules to design |
| Reject and alert | Neither side wins; a human decides | Safe for risky data | Slow, creates work |
| Block edits on one side | Make the attribute read-only where it should not be edited | Prevents the conflict entirely | May annoy users |
| Versioned compare | Apply update only if the version matches what was last seen | Detects stale updates | Needs systems that support versions |
A Ladder of Preference
Prevent
Make the attribute editable in only one place. No conflict is possible.
Assign an owner
If both sides must edit, name the system that wins for each attribute.
Detect stale writes
Use versions or change times from the source to avoid applying old updates.
Escalate to a human
For risky attributes where neither rule is trustworthy, stop and ask.
Fall back to last writer
Only for low-risk attributes, and only with trusted timestamps.
Families settle who decides the holiday destination in different ways: one parent always chooses, they take turns, they ask the kids, or they flip a coin. A good family picks a method and sticks to it, because the method matters more than any single outcome.
14Choosing Winners Attribute by Attribute
Let us put the strategies to work on a real table of attributes.
| Attribute | Strategy | Details |
|---|---|---|
| Employment status | Source of truth: HR only | No other system may reactivate or deactivate a person. App-side changes are ignored and logged. |
| Manager | Source of truth: HR only | Approvals and reviews depend on it. Read-only elsewhere. |
| Job title | Source of truth: HR, with display override | Apps may show a friendlier title but cannot change the official one. |
| Email address | Source of truth: Okta | Created by naming rules and unique checks. Apps read it only. |
| Mobile phone | Person owns, last writer wins among self-service apps | Low risk. Normalize format before comparing. |
| Preferred name | Person owns | Edits from the person’s own app accepted. |
| Office location | Priority list: HR, then facilities app | Facilities fills the gap if HR is empty. |
| Role inside one application | Reject and alert on disagreement | Access impact, so a human reviews. |
| Group membership for access | Source of truth: Okta rules | Apps cannot add themselves to access groups. |
Cedarwood’s decision record
Cedarwood put the table in a shared document with an owner for each row, a date, and a reason. When a clinic manager later asked why her edit to a nurse’s title kept disappearing, the support team pointed to the row, explained that titles come from human resources, and told her how to request a change there. The conversation took two minutes instead of two meetings.
When you make an attribute read-only on one side, tell users where to go to change it. A locked field without a signpost feels like a bug.
A library has one catalog for books and another for borrowing records. Nobody asks which catalog is “right” overall. The question is which catalog is right for which fact, and that is cleanly answerable.
15A Quick Decision Guide for New Conflicts
When a new kind of disagreement appears, ask the same short list of questions in the same order. The answers point to the remedy.
Did both sides really change?
If only one did, the other should catch up. Fix delay or detection, not the rule.
Are the values truly different?
If they differ only in format, add normalization and the conflict disappears.
Does the attribute affect access or status?
If yes, use a single owner and, if unsure, a human review. Never last writer.
Can one side be made read-only?
If yes, do it and signpost where to edit. This removes the conflict at the source.
Are timestamps trustworthy?
If yes and the data is low risk, last writer may be acceptable. If not, name an owner.
How often will this happen?
Rare and risky goes to a queue. Frequent and safe deserves an automatic rule.
flowchart TD
Q1{"Did both sides change?"} -->|"No"| CATCH["Let the other side catch up"]
Q1 -->|"Yes"| Q2{"Differ only in format?"}
Q2 -->|"Yes"| NORM["Normalize and ignore"]
Q2 -->|"No"| Q3{"Affects access or status?"}
Q3 -->|"Yes"| OWN["Owner wins or human review"]
Q3 -->|"No"| Q4{"Trusted timestamps?"}
Q4 -->|"Yes"| LW["Last writer wins"]
Q4 -->|"No"| OWN2["Owner wins"]
A nurse at triage asks the same few questions of every patient: breathing, bleeding, pain. The order keeps important signs from being missed and gets the right person to the right room quickly.
16Loops and Echoes
Loops are the most embarrassing kind of sync failure. They burn through rate limits, fill logs, and make values dance for days.
How a Loop Forms
flowchart LR
O["Okta sets display name to Dr. A Mehta"] --> P["Push to application"]
P --> AP["Application stores it as DR. A MEHTA"]
AP --> I["Import reads DR. A MEHTA"]
I --> D{"Different from Okta value?"}
D -->|"Yes, by case"| O2["Okta updates to DR. A MEHTA"]
O2 --> P
Ways to Break Loops
- One direction per attribute. If an attribute is pushed out, do not import it back, and the reverse. The simplest cure.
- Normalize before comparing. Trim spaces, fix case, and standardize formats such as phone numbers before deciding that two values differ.
- Compare before writing. Skip the write if the new value equals the current one after normalization.
- Mark the origin. If a change came from the sync itself, do not treat it as a human edit.
- Limit rates. Cap how often one attribute of one person may change per hour, and alert when the cap is hit.
- Watch logs for repeats. The same user and attribute appearing again and again in a short time is the signature of a loop.
A microphone placed too close to its own speaker screeches, because the sound feeds back and grows. The cure is to separate the paths. Loops in sync are feedback, and the cure is the same: separate the input path from the output path.
A loop across thousands of users can exhaust API limits and make unrelated provisioning fail. Treat any sign of repeated updates as an incident, not a curiosity.
17Matching, Duplicates and Identity Linking
You cannot resolve a conflict about a person until you agree which person it is.
The Matching Problem
When a new record arrives from a source, Okta must decide whether it describes someone it already knows. If the match key is the email address, then a person whose email changed after marriage looks like a stranger, and a duplicate is born. If the match key is a human resources employee number that never changes, matching is steady. Good keys are unique, stable, and present everywhere.
| Key | Stable? | Unique? | Verdict |
|---|---|---|---|
| Employee number from HR | Yes | Yes | Best primary key |
| Username | Mostly | Yes | Acceptable if rarely changed |
| Email address | Changes on name changes | Usually | Risky as the only key |
| Full name | Changes | No | Never use alone |
| Application-specific ID | Yes inside that app | Yes | Good for linking to that one app |
Typical Duplicate Problems
- Create versus create. The same contractor is created in two systems. When both import, two Okta users may result.
- Rehires. A person returns with a new employee number. Decide whether to reactivate the old identity or create a new one, and record the rule.
- Name changes. If the key is derived from the name, the person splits into two.
- Test and shared accounts. They collide with real people’s emails.
Linking Identities
Give every person a stable internal ID that all systems store, even if names and emails change. Keep a link table or an attribute holding each application’s own ID. When a new record arrives, match on the stable ID first. A confirmation step for ambiguous matches prevents silent mistakes.
A school identifies pupils by a roll number, not by name, because many children share names and names change. The roll number is the thread that ties every record to the right child.
18Human Resources Systems and the Joiner, Mover, Leaver Cycle
The human resources system is usually the most trusted source of who works for the company. It also creates the trickiest timing conflicts.
Joiners
People are often entered in the human resources system weeks before their first day. If the feed creates the account immediately, a person may have access before they have joined. Many designs use the start date to decide when an account is created or activated. Conflicts arise when the start date is changed late, or when the person is created by another process first, for example a contractor-to-employee conversion.
Movers
When a person changes department or manager, several systems must follow. The manager change can reach Okta before the department change. For a short time the person has a new manager and an old department, which can trigger odd group rules. Design group rules to tolerate short partial states, or wait for both attributes to settle.
Leavers
Terminations may be future-dated, backdated, or reversed. A backdated termination tells Okta that someone left yesterday, and the system must act now. A reversed termination, when a leaver is rehired the same week, tries to reactivate an account that may already have been cleaned up. Each case needs a written rule.
Future-dated start
Create early but keep inactive until the start date. Block sign-in until then.
Backdated leave
Act immediately and review what the person did since the stated date.
Rehire
Decide whether to reuse the old identity. Reusing keeps history but can bring back stale access.
Leave of absence
Treat as a distinct status, usually with suspended sign-in but preserved account.
Concurrent jobs
One person with two roles must not appear as two employees, nor lose access when one role ends.
A theater issues backstage passes by cast list. The list changes up to the last minute: someone joins late, someone drops out, someone swaps roles. The doorman needs one up-to-date list and a rule for what to do when the list changes mid-show.
19Directories as Sources: Active Directory and LDAP
Many companies keep a classic directory at the center of their world. When Okta joins it, a two-way relationship appears whether anyone planned it or not.
How the Pieces Relate
A directory such as Active Directory stores user accounts, group memberships, and passwords for a company network. Okta can connect to it through a lightweight program, often called an agent, that runs inside the company network. The agent imports users and groups into Okta and can also send certain changes back, such as password changes or group updates, depending on how you configure it. Which attributes go which way is set in mappings, and the options depend on version, so confirm in current documentation.
Where Conflicts Appear
- Attributes edited in both places. An administrator fixes a department in the directory tools while someone else fixes it in Okta. The next import or push overwrites one of them.
- Organizational units and filters. A user moved to a different container may fall outside the import scope, and Okta sees them as gone.
- Group membership. Group changes made directly in the directory may fight with Okta group rules that mirror the same groups.
- Passwords. If the directory owns passwords and Okta also lets users reset them, resets must flow back or be blocked, or the two systems will hold different passwords.
- Naming rules. The directory may require unique account names in a pattern, and Okta may generate a different pattern, leading to two identities for one person.
| Choice | Directory is master | Okta is master |
|---|---|---|
| Where edits are made | Directory tools | Okta, or the human resources system |
| Direction of profile data | Directory to Okta | Okta to directory |
| Passwords | Verified by the directory | Verified by Okta |
| Best for | Companies with heavy legacy dependence on the directory | Companies moving toward cloud identity |
| Main risk | Okta cannot fix data on its own | Legacy tools may edit the directory directly |
An old city hall and a new digital portal both keep birth records. If both accept corrections, clerks must decide which one wins. Many cities solve it by letting only one of them take corrections, and letting the other mirror it.
20Deletes, Deactivations and Reactivations
Removing a person is the most dangerous change in any sync. A wrong delete loses data. A missed delete leaves access open.
The Hard Cases
Update versus deactivate
HR deactivates a person while an app updates their profile. Deactivation must win, and the update must not revive the account.
Missing from an import
A person absent from one import file may be gone, or the file may be incomplete. Treat sudden mass absences as a fault, not as a firing wave.
Reactivation by a stray update
An app that treats any update as “this person is active” can bring a leaver back to life.
Rehire
A returning employee may match an old, deactivated record. Decide in advance how to handle it.
Safer Rules
- One owner of status. Only the human resources system, or a documented process, may change employment status.
- Deactivate, do not delete. Deactivation can be reversed and keeps history. Delete later, on a schedule, after a retention period.
- Safety brakes on mass changes. If an import would deactivate more than a set percentage of users, stop and ask a human.
- Tombstones. Record that a person was removed, so that a stale feed does not recreate them.
- Block reactivation from apps. Application-side activation should not change Okta status.
flowchart TD
CH["Incoming change: deactivate user"] --> OWN{"From the status owner?"}
OWN -->|"No"| IGN["Ignore and log"]
OWN -->|"Yes"| MASS{"More than the safety limit at once?"}
MASS -->|"Yes"| HOLD["Hold and alert human"]
MASS -->|"No"| DEA["Deactivate in Okta"]
DEA --> PUSH["Push deactivation to apps"]
PUSH --> TOMB["Record tombstone"]
A hospital does not shred a patient’s chart the day they leave. It marks the chart closed and archives it. Closing is reversible and safe, and shredding comes much later and only by policy.
21SCIM Behavior: Updates, Conflicts and Error Codes
Many applications speak a common language called SCIM when Okta provisions accounts. Knowing a few details of that language explains many puzzling failures.
What SCIM Is
SCIM stands for System for Cross-domain Identity Management. It is a standard way for a service to accept requests such as “create this user,” “change this user’s title,” and “remove this user.” Using a standard means Okta can connect to many applications with the same pattern. Support varies between applications, so read each integration’s notes.
Details That Matter for Conflicts
| Detail | What it means | Conflict effect |
|---|---|---|
| Full replace versus partial update | A full replace sends the entire record. A partial update sends only changed fields. | A full replace can erase fields that Okta does not know about, deleting local edits |
| Unique identifier collisions | The application refuses to create a user whose key already exists | Create-versus-create conflicts appear as errors |
| Conflict response | Services may answer with a conflict code when a rule is violated | Signals duplicates; needs matching, not blind retry |
| External identifier | An ID that Okta stores to link its record with the app’s record | Lost or changed IDs break linking |
| Multi-valued fields | Fields that hold lists, such as several phone numbers | Updating one entry may replace the list |
| Active flag | Whether the account is enabled | Mishandled flags are a common cause of unintended reactivation |
Reading Errors Calmly
When a push fails, the System Log usually records the application’s reply. A “user already exists” reply suggests a duplicate that needs linking. A “not found” reply suggests the account was deleted on the application side. A “forbidden” reply suggests the connector’s permission has changed. Treat each as information about a disagreement between systems, and fix the cause instead of retrying forever.
Before using an integration widely, test what it does with attributes Okta does not send. Some applications keep them, and others quietly wipe them on update.
Handing in a corrected form is different from handing in a note saying “change line three.” A full form may erase lines you forgot to copy, while a note changes only what it names. Knowing which your application expects prevents accidental erasure.
22Group and Membership Conflicts
Groups decide who can open which doors. A disagreement about membership is a disagreement about access, so it deserves extra care.
Where Group Conflicts Come From
Okta can push group membership to applications, and some applications can also import groups and members back. Trouble starts when both sides add or remove people. An application administrator adds a user to a local group, while an Okta rule removes the same user from the matching Okta group at the next evaluation. The two sides keep undoing each other.
| Pattern | Who controls membership | Risk |
|---|---|---|
| Okta-owned groups pushed to apps | Okta rules only | Low: apps are followers |
| App-owned groups imported to Okta | The application | Medium: Okta mirrors, cannot govern |
| Both edit the same group | Nobody clearly | High: access drifts and audits fail |
| Different groups per side | Each owns its own groups | Low if names and purposes are clear |
Rules of Thumb
- One writer per group. Every group has exactly one system that may change its membership.
- Separate by name. Use naming that shows who owns the group, so nobody edits the wrong one.
- Treat unexpected app-side additions as findings. Detect them and either reverse or approve through a request process.
- Remove before add on moves. When a person changes department, remove old access first, so a failed step leaves them with less, not more.
- Reconcile regularly. Compare group membership in Okta with the application’s own list.
If both the doorman and the building manager can add names to the guest list, the list soon contains people nobody can explain. One person keeps the list, and the other asks them to make changes.
23Schema Design: Attributes That Sync Well
Many conflicts are born in the design of the attributes themselves. A clear schema removes whole categories of trouble.
Principles of Good Attributes
- One meaning per attribute. “Phone” that sometimes holds a desk line and sometimes a mobile number is a conflict waiting to happen. Create “work phone” and “mobile phone.”
- Consistent type and format. Store dates in one format, phone numbers with country codes, and country as a standard code.
- Clear empty value rules. Decide whether blank, missing, and “unknown” mean the same thing. A system that treats blank as “erase” will wipe values that another system treats as “no information.”
- Careful lists. Multi-valued attributes need rules for adding, removing, and ordering.
- Case and whitespace rules. Trim spaces and standardize capital letters for keys such as username.
- Documented owners. Every attribute has an owner, a purpose, and a retention note.
The Blank Value Trap
Suppose the human resources system has no value for a person’s cost center, while another system has one. If the feed sends an empty value and Okta treats it as an instruction, the good value is erased. A safer rule is that an empty value from a source is ignored unless the source is the declared owner and the field is explicitly allowed to be cleared.
| Situation | Risky behavior | Safer behavior |
|---|---|---|
| Source sends empty value | Erase the stored value | Keep the value unless the owner explicitly clears it |
| Two phone formats | Treat as different and push both ways | Normalize first, compare second |
| Name with extra spaces | Create new user | Trim and compare keys |
| List attribute edited in two places | Last list replaces the other | Merge by item or assign one owner |
| Custom attribute renamed | Mappings break silently | Treat renames as managed changes with testing |
A form with a field called “address” invites chaos: some write street, some write email. A form with separate boxes for street, city, and email is easier for everyone to fill and compare.
24Passwords and Credentials
Passwords are the touchiest data to sync. Two systems that both think they own a password create outages, lockouts, and security holes.
The Options
Single sign-on, no local password
The application trusts Okta and holds no password of its own. No sync, no conflict. The preferred design.
Okta as the password master
Okta pushes password changes to the application. The application is a follower, and local changes are blocked or overwritten.
Directory as the password master
A directory such as Active Directory owns the password, and Okta delegates authentication to it or syncs from it. Okta supports agents for this, with details that vary.
Two masters
Both systems accept changes and push to each other. Fragile and hard to secure. Avoid.
Why Two Masters Hurt
- Password rules differ, so a password valid in one system is refused by the other.
- A change that fails on one side leaves the user with different passwords in two places.
- Lockout counters differ, so a lockout in one system may not be mirrored.
- Sending passwords between systems widens the places a password could leak.
Where possible, remove local passwords from applications and use single sign-on. Syncing passwords is a workaround for older applications, not a goal. Confirm which password synchronization features your edition and each integration support.
Two banks each issuing their own PIN for the same card would leave customers guessing which one works where. A single card with a single PIN, issued by one bank, is easier to use and to protect.
25Detecting Drift and Reconciling
Even good designs let some differences slip through. Reconciliation is the regular health check that finds them.
What Reconciliation Does
Reconciliation compares what each system holds for the same people and lists the differences. For each difference it asks: who owns this attribute, which side is right, and what repair is safe? Simple, low-risk differences can be repaired automatically. Risky ones go to a person.
Export both sides
Pull a list of people and the important attributes from Okta and from the application.
Match and normalize
Link records with the stable key and clean formats so harmless differences vanish.
Compare
List missing people, extra people, and differing attributes.
Classify
Apply the ownership table to each difference. The owner’s value is the target.
Repair or escalate
Auto-fix low-risk items. Send access-related items for human review.
Record and trend
Save the counts. A growing difference count is an early warning of a design fault.
flowchart TD
A["Export from Okta"] --> M["Match by stable ID and normalize"]
B["Export from application"] --> M
M --> C["Compare attributes"]
C --> D{"Any difference?"}
D -->|"No"| OK["Record clean result"]
D -->|"Yes"| K{"Low risk and owner known?"}
K -->|"Yes"| FIX["Auto repair toward owner value"]
K -->|"No"| TICKET["Create review item for a person"]
FIX --> LOG["Log repair"]
TICKET --> LOG
A shopkeeper counts the till at closing and compares it with the sales slips. A few coins off is noted. A large gap triggers a search. Regular counts keep small errors from growing into big ones.
26Human Review: The Conflict Queue
Some conflicts should never be settled by a machine. A good queue makes human decisions quick and consistent.
What Belongs in the Queue
- Role or permission disagreements inside critical applications.
- Ambiguous matches that might join two different people.
- Mass changes that exceed the safety brake.
- Status disagreements involving leavers.
- Repeated conflicts on the same person, suggesting a deeper problem.
What Each Queue Item Should Show
| Field | Why the reviewer needs it |
|---|---|
| Person and stable ID | To be sure who is involved |
| Attribute and both values | To see the actual disagreement |
| Which side changed, and when | To judge freshness |
| Owner according to the ownership table | To suggest the default answer |
| Risk level | To set urgency |
| Suggested action and one-click choices | To speed decisions |
| History of earlier conflicts | To spot patterns |
Keeping the Queue Healthy
Assign an owner and a response time. Count how many items arrive each week, and treat the count as a measure of design quality. If the same kind of item keeps arriving, change the rules so it no longer needs a person. Every recurring item is a design bug, not a staffing problem.
A hospital’s emergency room sees the cases that routine clinics cannot handle. If the same complaint keeps arriving in the ER, hospitals open a clinic for it. A recurring queue item calls for a new rule in the same way.
27Multiple Okta Orgs and Mergers
When two companies merge, or one company runs several Okta orgs, the same person may exist in more than one place with different data.
The Merger Picture
After a merger, Company A and Company B each have their own identity systems and employees. Some people may have accounts in both, such as a consultant who worked for each. Others will be moved from one company to the other. For a time, both systems are live, and data flows between them to give staff access to shared tools.
Linking Orgs
Okta offers ways to connect one org to another, for example through an Okta-to-Okta integration that can provision users and groups and allow sign-in from one org into another. The details are product specific, so confirm current options. The design questions remain the same as for any two-way flow: which org owns which attributes, how are people matched, and what happens on deletion?
flowchart LR
HRA["HR system, Company A"] --> OA["Okta org A"]
HRB["HR system, Company B"] --> OB["Okta org B"]
OA -->|"provision selected users and groups"| OB
OB -->|"limited attributes back"| OA
OA --> AA["Apps for A"]
OB --> AB["Apps for B"]
Rules for Safe Linking
- Each person has one home org. The home org owns identity, status, and core attributes. The other org holds a guest copy.
- Limit what travels. Send only what the other side needs, such as name, email, and a few group memberships.
- Make the return flow tiny. If anything flows back, keep it to harmless attributes and never to status or access.
- Plan for the end. Decide when the two orgs will become one and how duplicates will be merged.
Two neighboring schools sharing a sports field keep their own registers. Pupils from one school are listed as visitors at the other. If both tried to edit the same register, nobody would know the truth.
28Failures, Retries and Idempotency
Networks fail, applications go down, and requests time out. A sync design must stay correct even when parts break.
Partial Failure
Suppose Okta updates a user’s title and pushes it to three applications. Two succeed and one fails. Now the user’s title differs across systems through no one’s decision. The system must remember that the third push is still owed and keep trying, without redoing the other two in a harmful way.
Idempotency Makes Retries Safe
If repeating an operation gives the same end state, retries are safe. “Set title to Director” is idempotent. “Add one day of leave” is not. Prefer designs that send the full desired value, not the difference, so that a repeated message does no harm.
| Failure | Risk | Defense |
|---|---|---|
| Application down during push | Missed update | Retry with backoff, alert after repeated failures |
| Timeout after the app already applied the change | Duplicate attempt | Idempotent writes |
| Import interrupted halfway | Partial data seen as deletions | Treat incomplete imports as failed, never as deactivation |
| Rate limit hit | Slow or dropped updates | Throttle, queue, and spread bulk jobs over time |
| Schema change in the application | Mappings break | Contract tests and change notices |
| Credential expiry of the connector | Silent stop of sync | Alert on stale last-success time |
Track the “last successful sync” time for each connection and alert when it is too old. A silent stop is more dangerous than a loud failure.
Pressing a lift button five times does not bring five lifts. The system treats repeated requests as one. Good sync operations behave like that button.
29Rate Limits, Bulk Changes and Scale
A design that works for ten test users may struggle with ten thousand real ones, especially when many changes happen at once.
Where Scale Hurts
- Bulk mapping changes. Changing a mapping can trigger updates for every assigned user at once.
- Large imports. Full imports of big directories take long and may overlap with the next scheduled run.
- Rate limits. Okta and many applications limit how many requests they accept per time period. Exact limits vary by plan and endpoint, so check current documentation.
- Merger and reorganization waves. Thousands of title and manager changes arrive on the same day.
- Retry storms. When many requests fail, naive retries can pile up and make things worse.
Handling Bulk Work Safely
Preview
Estimate how many users and requests a change will touch before starting.
Pilot
Apply to a small group, check the result, and compare with the plan.
Stage
Run in batches, outside peak hours, watching for errors and rate-limit signals.
Back off
When errors rise, slow down instead of retrying harder.
Reconcile
After the run, compare systems and repair leftovers.
Moving house with a single van takes several trips. Trying to cram everything into one trip breaks furniture. Batches keep every trip safe, and a checklist at the end shows nothing was left behind.
30Security of the Sync Itself
Whoever can change what flows between systems can change who has access. The sync is a privileged path and must be guarded as one.
| Threat | How it happens | Defense |
|---|---|---|
| Poisoned source data | An attacker edits a manager or group field in a source | Limit who can edit sources, alert on unusual edits |
| Privilege injection through an app | An app-side edit adds a role that Okta then pushes elsewhere | Ownership rules: apps cannot write access attributes |
| Connector credential theft | The token used for sync is stolen | Least-privilege tokens, rotation, storage in a vault, usage alerts |
| Mapping tampering | Attribute mappings are quietly changed | Change review and alerts on mapping edits |
| Mass deactivation attack | False feed empties the user list | Safety brakes and human approval |
| Data exposure in logs | Sensitive values appear in logs | Mask sensitive fields, restrict log access |
Habits That Help
- Give each connector only the permissions it needs, and no more.
- Use separate service identities per integration, with named owners.
- Review who may edit mappings, profile sources, and automations.
- Treat data from outside systems as untrusted until the ownership rules approve it.
- Keep an independent copy of the logs.
The mail room can rewrite delivery addresses on parcels. Because that is so powerful, only a few staff may do it, and every change is signed and logged. The sync pipeline holds similar power over access.
31Monitoring, Logging and Metrics
If you cannot see the sync working, you cannot trust it. A few well-chosen measures reveal almost every problem early.
What to Record
Okta’s System Log records provisioning, import, and profile events, usually including the user, the application, the outcome, and an error reason when something fails. Event names and fields change, so inspect real events in your own org. Stream logs to a monitoring platform, because retention inside the product is limited.
| Metric | Meaning | Warning sign |
|---|---|---|
| Time since last successful import or push | Freshness of each connection | Growing beyond the agreed window |
| Push failure rate | Health of outbound flow | Rising above a few percent |
| Conflicts detected per week | Design quality | Upward trend |
| Repeated updates to one user and attribute | Loop signature | Same pair more than a few times an hour |
| Reconciliation difference count | Drift | Not shrinking after repairs |
| Queue size and age | Human backlog | Old items accumulating |
| Mass-change brake activations | Possible bad feed | Any occurrence deserves a look |
| Time to propagate a termination | Security speed | Longer than target |
flowchart LR
SL["Okta System Log"] --> STR["Log streaming"]
STR --> PLAT["Monitoring platform"]
PLAT --> DASH["Dashboards: freshness, failures, conflicts"]
PLAT --> ALR["Alerts: stale sync, loop signature, brake activated"]
ALR --> ON["On-call identity engineer"]
DASH --> REV["Weekly design review"]
A pilot watches altitude, speed, and fuel, not every wire in the plane. A handful of dials tell when to act. These metrics are the dials of a sync system.
32A Troubleshooting Playbook
When someone says “the data is wrong,” a steady routine finds the cause faster than guessing.
Name the exact disagreement
Which person, which attribute, which two systems, which two values, and when was it noticed?
Look up the owner
Consult the ownership table. The owner’s value is the target. If none exists, that is the first finding.
Read the log history
Find every event touching that person and attribute. Who changed it last, from which source, and how many times?
Check for a loop or a revert
Repeated changes suggest a loop. A single revert at a regular time suggests a scheduled feed overwriting a local edit.
Check mappings and direction
Is the attribute mapped in both directions? Are formats the same? Does the application treat blanks as erasures?
Repair the data, then the rule
Set the correct value at the owner. Then fix the design fault so it does not recur.
Look for siblings
If it happened to one person, check others with the same pattern. Repair them together.
| Symptom | Likely cause | First check |
|---|---|---|
| Value reverts every night | Scheduled feed from another owner | Compare feed time with revert time |
| Value flips every few minutes | Loop between two systems | Look for repeated events and format differences |
| Person appears twice | Matching key mismatch | Compare keys across the two records |
| Leaver became active again | Status written by a non-owner | Find which source set the active flag |
| Group membership keeps changing | Two writers for one group | List who can edit it on each side |
| Nothing changes anymore | Connector credential expired | Check last success time and error messages |
A good mechanic does not replace parts at random. They follow a routine: listen, check the fuel, check the spark, check the air. A repeatable routine finds the fault with less luck and less cost.
33Privacy, Compliance and Audit of Synced Data
Every copy of a person’s data is another place to protect, explain, and eventually delete. Sync multiplies copies, so it multiplies duties.
What Auditors and Regulators Ask
- Where does each piece of personal data come from, and where does it go?
- Who can change it, and is that recorded?
- How quickly is a leaver’s access removed in every connected system?
- Are only the needed attributes shared with each application?
- How long is data kept, and how is it deleted everywhere?
Good Habits
Share the minimum
Map only attributes the application needs. Unused attributes are risk without benefit.
Keep a data flow map
The same diagram you use for conflicts doubles as the answer to “where does the data go?”
Plan deletion
Decide how a deletion request travels to every copy, and how you verify it.
Mind regions
Some regions limit where personal data may be stored or sent. Ask legal teams early, since rules vary.
This chapter is general orientation, not legal advice. Privacy and employment laws differ widely, so have your legal and privacy teams confirm what applies to your data and regions.
Each photocopy of a confidential letter is another page to lock away and later shred. The fewer copies you make, the fewer you must track. Sharing only what is needed keeps the pile small.
34Testing and Safe Rollout
Sync mistakes spread quickly and are tedious to undo. Testing before and during rollout keeps them small.
A Test Plan
Use a test org and a test application
Build the same mappings and ownership rules in a non-production org, with test users and a test instance of the application where possible.
Create deliberate conflicts
Edit the same attribute on both sides within the same minute. Confirm the owner’s value wins and the loser is logged.
Test the nasty cases
Update versus deactivate, create versus create, a missing record in an import, and a format difference.
Try to cause a loop
Change an attribute and watch logs for repeated updates over an hour.
Rehearse failure
Switch off the application for a while and confirm that retries, alerts, and recovery work.
Pilot in production
Enable for a small group, reconcile, and widen in waves.
Take a backup export of both systems before any large mapping change or first full import, and know how to restore. Not every change can be reversed by changing a setting back.
A fire drill is held before the fire. Testing deliberate conflicts is a drill for data: you learn the exits while it is calm.
35Ownership and Governance of the Sync Program
Technology does not settle disagreements between departments. People do, and they need a clear structure to do it.
| Role | Responsibility |
|---|---|
| Data owner for each attribute | Decides what the value means, who may change it, and how long it is kept |
| Identity engineering team | Builds and runs mappings, flows, brakes, and alerts |
| Application owner | Knows what the application does with synced data and signs off on changes |
| HR operations | Keeps the human resources data accurate and explains its timing |
| Security team | Reviews risk, watches alerts, and approves access-related rules |
| Help desk | Handles user reports, uses the playbook, and records patterns |
| Privacy and legal | Check data use, retention, and regional rules |
Meetings and Records
- A short weekly review of conflict counts, queue age, and sync freshness.
- A change calendar so that application upgrades and mapping edits do not surprise each other.
- A decision log capturing every ownership change with date, owner, and reason.
- A yearly review of the whole ownership table.
A shared kitchen runs smoothly when the chore chart names who cleans what and when. The chart is not about trust. It is about removing the daily question of whose job it is.
36Advantages, Disadvantages and Trade-offs
Two-way sync is not always worth its cost. Weigh the benefits against the complexity honestly.
Advantages
- People can fix their own data where it is convenient.
- Applications can supply facts that the central system lacks.
- Less manual re-entry and fewer help desk requests.
- Fits real organizations where no single system knows everything.
- Faster correction of wrong data.
Disadvantages
- Conflicts, loops, and duplicates become possible.
- Ownership rules must be designed and kept current.
- Debugging crosses several systems.
- More monitoring and reconciliation effort.
- Security surface grows with each write path.
Main Trade-offs
| Trade-off | Leaning one way | Leaning the other |
|---|---|---|
| Flexibility versus predictability | Many edit points, convenient, riskier | One edit point per attribute, calm, sometimes annoying |
| Speed versus safety | Automatic repair of everything | Human approval for risky changes |
| Real-time versus scheduled | Fresh data, more load | Batches, easier to control, older data |
| Central ownership versus local ownership | Consistent, slower to change | Responsive, harder to audit |
| Strict matching versus loose matching | Duplicates, no wrong merges | Fewer duplicates, risk of wrong merges |
The safest two-way sync is the one that is two-way for as few attributes as possible.
A town with two-way streets lets traffic move freely but needs traffic lights and rules. A town of one-way streets is simple but forces long detours. Choose two-way only where the benefit is worth the signals.
37Common Myths About Two-Way Sync
A few wrong beliefs cause most of the disappointment. Clearing them up early saves months of rework.
| Myth | Reality |
|---|---|
| “The tool will sort it out.” | Tools move data and apply the rules you give them. Without ownership decisions, they apply none. |
| “Two-way means both sides are always equal.” | Even in two-way flows, each attribute should have one winner when a conflict occurs. |
| “Real-time sync means no conflicts.” | Faster delivery shrinks the gap but never removes it, and a loop runs faster in real time too. |
| “Newest is always correct.” | The newest change may be a mistake, a stale retry, or a result of a clock difference. |
| “If values match, nothing is wrong.” | Both can be wrong in the same way, or matching may be temporary while a loop runs. |
| “Deleting is the cleanest fix.” | Deletion loses history and can be recreated by a stale feed. Deactivate first. |
| “We can fix it all later.” | Duplicates and drift grow with time and become much harder to untangle. |
| “Only big companies need this.” | Any organization with two connected systems that both accept edits can meet these problems. |
Many people believe that a faster car means a safer trip. Speed helps you arrive sooner and also makes a mistake costlier. Faster sync shortens delays and, if the rules are wrong, spreads wrong data faster.
38Design Patterns and Anti-Patterns
Habits that keep sync calm, and mistakes that keep recurring.
Patterns That Work
Ownership table
One written table naming the owner of each attribute and the strategy for conflicts.
Hub with one writer
Okta as the central hub, with each attribute having exactly one inbound writer.
Normalize, compare, write
Clean values first, compare second, write only when different.
Safety brakes
Limits on mass deactivations and update rates, with alerts.
Scheduled reconciliation
Regular comparison with auto-repair for safe items and a queue for the rest.
Signposted read-only fields
Where an attribute is locked, tell people where to change it.
Anti-Patterns
What it looks like
Every system is allowed to write every attribute in both directions, “to keep things flexible.”
Why it hurts
Nobody can explain why a value is what it is. Loops and lost edits become daily events.
Better approach
Assign one owner per attribute and make other systems read-only for it.
What it looks like
“Newest change wins” is used for everything, including access roles and status.
Why it hurts
Clock differences and detection delays pick winners randomly, and a stale update can reactivate a leaver.
Better approach
Use owner-wins for important attributes, and last writer only for low-risk ones with trusted times.
What it looks like
An import treats absence from a file as proof that a person has left.
Why it hurts
A broken or partial file deactivates hundreds of people at once.
Better approach
Validate file completeness, and put a safety brake on mass deactivation.
What it looks like
Email addresses are used as the only matching key.
Why it hurts
Name changes and rehires create duplicates or wrong merges.
Better approach
Use a stable internal ID, and keep email as a changeable attribute.
What it looks like
The sync is set up once and nobody watches it afterward.
Why it hurts
Expired credentials, schema changes, and drift go unnoticed until an audit or incident.
Better approach
Alert on stale syncs, reconcile on a schedule, and name an owner for each connection.
Old sailors kept charts of rocks and storms so that new captains would not need to rediscover them. Patterns and anti-patterns are such charts for data movement.
39Small Details That Decide Success
Most failed sync projects do not fail on big ideas. They fail on small details that nobody wrote down.
Time zones
Store and compare times in one standard zone. A change recorded at local midnight in two zones appears a day apart.
Character sets
Names with accents or non-Latin letters may be stored differently by each system. Test with real names, not just plain examples.
Length limits
A field that allows 100 characters in one system and 50 in another will be silently cut, then seen as a change.
Schedule overlap
If an import is still running when the next starts, they can overwrite each other. Space schedules and block overlaps.
Test and service accounts
Accounts with no human owner should be tagged and handled by separate rules, not swept into people processes.
Change notices
Application upgrades can change fields without warning. Ask vendors for change notices and test after upgrades.
A marathon is seldom lost at the starting line. It is lost to a blister at kilometer thirty. Small unwritten details do the same to data projects.
40Best Practices Checklist
A short list for design review and for yearly check-ups.
Design
- An ownership table exists for every attribute that crosses a system boundary.
- Each attribute flows in one direction wherever possible.
- Matching uses a stable unique ID, and ambiguous matches are held for review.
- Employment status and access groups have exactly one owner each.
- Formats are standardized and compared after normalization.
Safety
- Deactivate before delete, with retention and tombstones.
- Mass-change brakes are in place for deactivations and updates.
- Incomplete imports are treated as failures.
- Passwords are removed from applications where single sign-on is possible.
- Connector credentials are least-privilege, stored safely, and rotated.
Operations
- Each connection has an owner, a freshness target, and a stale-sync alert.
- Reconciliation runs on a schedule, with auto-repair for low-risk items.
- A conflict queue exists, with an owner and a response time.
- Bulk changes are previewed, piloted, staged, and followed by reconciliation.
- Logs stream to an independent platform with alerts for loops and brake activations.
Pilots read the checklist even after thousands of flights. The list is not for ignorance. It protects against the one small step forgotten on a busy day.
41Real-World Scenarios and Worked Numbers
Stories from the fictional Cedarwood Healthcare Group show the ideas at work. All numbers are illustrative.
Scenario 1: The vanishing phone number
Nurses kept updating their mobile numbers in the scheduling application, and the numbers kept reverting overnight. Investigation showed that the nightly human resources feed carried old numbers and, with no ownership rule, overwrote the edits. Cedarwood declared the person the owner of the mobile number, removed that field from the HR mapping, and the problem disappeared.
Scenario 2: The zombie contractor
A contractor was deactivated by the vendor management process, but a profile update from the training application marked him active again. Access to a clinical system returned for two days. Cedarwood made status read-only outside the owning process, blocked reactivation from applications, and added an alert whenever a deactivated user became active outside that process.
Scenario 3: The display name storm
A scheduling application stored names in capitals. Okta pushed mixed case, the application changed it, the import saw a difference, and Okta pushed again. For 3,000 users, this produced a stream of updates every ten minutes and ate into the rate limit. Fixing the mapping to compare after normalization ended the storm in one deployment.
Worked Numbers: Why Ownership Cuts Conflicts
Suppose Cedarwood has 7,000 staff and 12 attributes crossing system boundaries. If every attribute is two-way across three systems, then in a week with 2 percent of staff changing something, the number of potential collision points is large, and many need review.
| Design | Edit points per attribute | Weekly conflicts, illustrative |
|---|---|---|
| Everything two-way | 3 | About 140 needing attention |
| Ownership table, apps read-only for HR attributes | 1 for most, 2 for a few | About 12 |
| Ownership plus normalization | 1 for most, 2 for a few | About 4 |
| Ownership, normalization, and edit points removed for access attributes | 1 | Fewer than 2 |
The figures are invented to show a pattern: each design step removes a class of conflicts instead of settling them one by one. The cheapest conflict to resolve is the one the design never lets happen.
42A Maturity Path and a 90-Day Plan
Few teams start with a perfect design. A short path shows how to improve steadily.
Level 1: Accidental
Connections grew by request. Nobody knows which direction each attribute flows.
Level 2: Mapped
Flows are documented. Major loops are fixed. Employment status has one owner.
Level 3: Owned
Every attribute has an owner, matching uses stable IDs, and safety brakes exist.
Level 4: Observed
Metrics, alerts, scheduled reconciliation, and a conflict queue are in place.
Level 5: Self-healing
Safe repairs are automatic, recurring conflicts feed design fixes, and drills are routine.
| Period | Focus | Outputs |
|---|---|---|
| Days 1 to 30 | Discover | Inventory of every connection and direction, draft ownership table, list of known loops and duplicates |
| Days 31 to 60 | Fix the worst | Break loops, set status ownership, block reactivation from apps, add mass-change brakes, normalize formats |
| Days 61 to 90 | Observe and repair | Stale-sync alerts, first reconciliation, conflict queue, weekly review begins |
flowchart LR
A["Inventory connections"] --> B["Draft ownership table"]
B --> C["Fix loops and status ownership"]
C --> D["Add brakes and normalization"]
D --> E["Alerts and reconciliation"]
E --> F["Weekly review and improvement"]
Tidying a messy workshop starts with finding out what you own, then removing the dangerous clutter, then giving each tool a home. Only then can you keep it neat with a small weekly effort.
43A Design Exercise: Cedarwood’s Sync Design From Start to Finish
Let us put the ideas together by designing one complete two-way arrangement the way a working team would.
Step 1: List the Systems and the Directions
Cedarwood has a human resources system, a directory for its network, Okta, a scheduling application, a training application, and a clinical records application. The team draws every arrow and labels it import, push, or both. It discovers that the scheduling application is both a push target and an import source for phone numbers and display names, which no one intended.
Step 2: Write the Ownership Table
| Attribute | Owner | Others |
|---|---|---|
| Status, manager, department, title | HR system | Read-only everywhere |
| Work email, username | Okta | Read-only everywhere |
| Mobile number, preferred name | The person, through the scheduling application | Okta accepts, normalizes, and shares |
| Clinical role | Okta groups | The clinical application cannot add roles |
| Network password | Directory, with single sign-on elsewhere | No other password stores |
Step 3: Remove the Arrows That Should Not Exist
The team stops pushing display name to the scheduling application and stops importing the title from it. It turns off reactivation from the training application. It keeps the mobile number as a deliberate two-way attribute, with normalization.
Step 4: Add Protection and Eyes
Safety brakes are added for mass deactivation. A stale-sync alert is created for each connection. Reconciliation runs nightly on access-related data and weekly on the rest. A conflict queue is created and owned by the identity team.
flowchart TD
A["List systems and arrows"] --> B["Write ownership table"]
B --> C["Remove unintended arrows"]
C --> D["Normalize formats and matching keys"]
D --> E["Add brakes, alerts, reconciliation"]
E --> F["Pilot, then widen"]
F --> G["Review conflicts weekly"]
A city planner first draws the existing roads, then decides which should be one-way, then removes dead ends, then adds traffic lights and cameras. Planning starts with the map, not with the lights.
44Glossary of Terms
A quick reference for the words used in this guide.
| Term | Plain meaning |
|---|---|
| Agent | A small program inside your network that lets Okta talk to an on-premises directory |
| Attribute | One fact in a person’s record |
| Bi-directional | Changes may start on either side and travel to the other |
| Conflict | Both sides changed the same fact differently |
| Drift | Slow, unnoticed divergence between systems |
| Echo or loop | A change that bounces between systems indefinitely |
| Eventual consistency | The promise that systems agree after a while |
| Idempotent | Safe to repeat with the same result |
| Import | Pulling users and attributes into Okta |
| Mapping | The table linking fields between systems |
| Mastering | Declaring who owns a profile or an attribute |
| Normalization | Cleaning values so equal facts look equal |
| Push | Sending changes from Okta to an application |
| Reconciliation | Comparing both sides and fixing differences |
| SCIM | A standard language for provisioning requests |
| Source of truth | The system whose value wins |
| Tombstone | A marker recording a deletion |
| Universal Directory | Okta’s central store of profiles |
A small phrasebook does not make a traveler fluent, but it prevents small misunderstandings from growing. A shared glossary does the same for a project team.
45Frequently Asked Questions
46Summary and Key Takeaways
Conflicts in two-way sync are not random bad luck. They are the predictable result of two systems with different clocks, formats, and opinions sharing the same fact without a rule. Good design gives them the rule.
Key Takeaways
- A conflict needs two changes. If only one side changed, the other simply catches up. Separate real conflicts from format noise and ordering delays.
- Decide ownership per attribute. A written table naming the owner of each field, with a reason, prevents most conflicts before they exist.
- Prefer one direction. Make attributes editable in one place, and treat every two-way attribute as a cost that must justify itself.
- Avoid fragile winners. Use owner-wins for status, roles, and groups. Use last writer only for low-risk data with trustworthy time.
- Stop loops and protect against mass errors. Normalize before comparing, write only when different, cap update rates, and put safety brakes on bulk deactivations.
- Match on stable keys and treat removals carefully. Use unique internal IDs, deactivate before delete, and never reactivate from an application’s stray update.
- Watch, reconcile, and learn. Alert on stale syncs, compare systems on a schedule, route risky differences to a queue, and fix recurring causes in the design.