Skip to content

Deprecate email as a user identifier #2459

Description

@Will-Howard

🧩 Summary

Per the comment below, we rely on the assumption of a fixed email as the primary user identifier in these places:

  1. In code, as a foreign key and the primary key to get-or-create a user by when they log in
  2. In customer.io, which is what we use to send almost all emails to users
  3. In Keycloak (where we want to keep login-by-email, but enable the update-email setting)
  4. In PostHog, we use email as the distinct_id for users
  5. In the CRM base
  6. In automations throughout other bases (mostly sending things to customer.io, but some other cases)

We want to migrate all of these to handle potentially changing emails (brief summary, more detail will be in sub-issues etc):

  1. In code: We can use the user id (i.e. the id of the User record in the Applications base) as the foreign key. For the auth object itself and the initial get-or-create of the User, we can use the sub property that comes from Keycloak.
  2. In customer.io: Roughly speaking, we can run an Identify API call when someone updates their email, and then leave the existing automations as-is (which will pick up the new email, and a continuous history for the user will be preserved in customer.io). There are some edge cases here: emails relating to a specific application form (where we should keep the form email), and newsletter subscribers
  3. In Keycloak: Enable the update-email flow (verify-new-then-swap) so email becomes mutable, and treat the immutable sub as the identity.
  4. In PostHog: Use the stable user id as the distinct_id and set the email as a person property (so people stay searchable by email).
  5. In the CRM base: Keep Primary email as the human lookup key — the CRM also holds people with no account, so email has to stay the key here — but make matching dedupe on ANY known email (not just the current primary), and carry the stable user id on the Person where possible.
  6. In automations throughout other bases: Update on a case my case basis depending on what they do

I'll break this down into sub-issues which plan out the individual changes more concretely and what-blocks-what.

✅ Definition of done

The above consumers of email are migrated to support potentially changing emails

📌 Notes / Designs

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

Status
In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions