Olympus Docs
CookbookAuth flows

Merge duplicate identities

A user signed up twice; combine the accounts

Users sign up with email A, forget, sign up again with email B (same person). Now they have two Olympus identities and two sets of app data. Merge.

Procedure

1. Confirm same person

Don't merge based on similar emails. Confirm via:

  • User submits a "merge accounts" request from logged-in session of account B.
  • User proves access to account A (e.g. enter password for A).

2. Pick the keeper

Typically: the older account (or the one with more data).

3. Transfer the verifiable address

# Add account B's email as a verifiable address on account A
curl -X PATCH http://localhost:3101/admin/identities/<accountA-id> -d '[
  { "op": "add", "path": "/verifiable_addresses/-", "value": {
    "value": "userB@example.com", "verified": true, "via": "email", "status": "completed"
  }}
]'

4. Re-key your app data

UPDATE app_table SET olympus_sub = '<accountA-id>' WHERE olympus_sub = '<accountB-id>';

Repeat for every table that references identity_id.

5. Delete account B

curl -X DELETE http://localhost:3101/admin/identities/<accountB-id>

6. Anonymize audit events for account B

UPDATE security_audit SET identity_id = '<accountA-id>'
WHERE identity_id = '<accountB-id>';
-- Or NULL them out if you don't want to attribute B's actions to A.

Caveats

  • OAuth2 grants, account B's grants are gone after delete. If A had grants to the same clients, fine. If only B did, the user must re-grant.
  • Audit log integrity, by re-attributing or anonymizing, you alter history. Document in a SOC 2 / GDPR audit trail.
  • Email collision, if A already has B's email as a verifiable address, the add fails. Handle by skipping the duplicate.

When NOT to merge

  • If the user is unsure / phishing concerns.
  • If you can't confirm same-person.
  • If compliance prohibits combining records (some HIPAA contexts).

When uncertain, deny the merge and explain.

Automation

For high-volume operators (e-commerce), build a "merge requests" admin queue:

  1. User submits merge request from settings.
  2. Operator reviews evidence.
  3. Operator clicks merge → backend runs the steps above.

On this page