Skip to content

Cut over website to identify to PostHog by keycloak sub instead of email#2806

Merged
Will-Howard merged 3 commits into
masterfrom
wh-2713-website-identify-sub
Jul 19, 2026
Merged

Cut over website to identify to PostHog by keycloak sub instead of email#2806
Will-Howard merged 3 commits into
masterfrom
wh-2713-website-identify-sub

Conversation

@Will-Howard

Copy link
Copy Markdown
Collaborator

Description

This is the final step to cut PostHog over to solely identifying users by the Keycloak sub value rather than email. There is just a auth.sub ?? auth.email left in to catch users who haven't refreshed their auth since the migration started.

Issue

#2713

Developer checklist

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Will-Howard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c73a0adf-b06f-4732-b6e1-33074d396544

📥 Commits

Reviewing files that changed from the base of the PR and between ba44a19 and b8f58f1.

📒 Files selected for processing (4)
  • apps/website/src/lib/utils.test.ts
  • apps/website/src/lib/utils.ts
  • libraries/ui/src/utils/auth.test.tsx
  • libraries/ui/src/utils/auth.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wh-2713-website-identify-sub

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Will-Howard

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review @greptileai review

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@Will-Howard: I’ll review the changes in #2806.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR completes the PostHog identity migration by switching from email-based identification to Keycloak sub-based identification, removing the now-redundant posthog.alias call. A sub ?? email fallback gracefully handles sessions stored before PR #2755 that have not yet been refreshed.

  • auth.tsx: posthog.identify now uses auth.sub ?? auth.email as the distinct ID (email as a person property), and the posthog.alias(sub, email) call is removed since the alias was established in the prior migration step.
  • utils.ts: The form-URL guard for the PostHog distinct ID is changed from !distinctId.includes('@') (an email heuristic that breaks now that subs are UUID-like) to !useAuthStore.getState().auth (a proper auth-state check), correctly suppressing the ID for any logged-in user regardless of identifier format.

Confidence Score: 5/5

Safe to merge — the changes are a straightforward final cut-over of a well-staged migration, with no breaking logic and proper fallback handling for old sessions.

Both changed behaviour paths (auth identification and form-URL distinct-ID guard) are covered by updated unit tests. The fallback for pre-migration sessions is explicit and tested. The removal of posthog.alias is intentional since the alias was established in a prior migration step, and the auth-state guard in utils.ts correctly supersedes the brittle email-heuristic it replaces.

No files require special attention.

Important Files Changed

Filename Overview
libraries/ui/src/utils/auth.tsx Switches PostHog identification from email to keycloak sub, removes alias call, adds email fallback for old sessions pre-#2755
apps/website/src/lib/utils.ts Replaces the !distinctId.includes('@') email heuristic with !useAuthStore.getState().auth auth-state check for guarding distinct ID forwarding to form URLs
libraries/ui/src/utils/auth.test.tsx Updates tests to match new identify-by-sub behavior and verifies no alias is called; adds coverage for the email fallback path
apps/website/src/lib/utils.test.ts Replaces email-based distinct ID guard test with an auth-state-based test using try/finally cleanup; test description updated to match new semantics

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant AuthStore as useAuthStore
    participant PostHog

    Note over Browser,PostHog: Login flow (after this PR)
    Browser->>AuthStore: "setAuth({ sub, email, ... })"
    AuthStore->>PostHog: "identify(sub ?? email, { email })"
    Note over PostHog: sub used as distinct_id, email as person property

    Note over Browser,PostHog: buildApplicationUrl (logged-out visitor)
    Browser->>AuthStore: getState().auth null
    Browser->>PostHog: get_distinct_id() UUID
    Browser->>Browser: "append prefill_PostHog Distinct ID=UUID"

    Note over Browser,PostHog: buildApplicationUrl (logged-in user)
    Browser->>AuthStore: getState().auth truthy
    Browser->>Browser: skip distinct ID

    Note over Browser,PostHog: Logout
    Browser->>AuthStore: setAuth(null)
    AuthStore->>PostHog: reset()
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant AuthStore as useAuthStore
    participant PostHog

    Note over Browser,PostHog: Login flow (after this PR)
    Browser->>AuthStore: "setAuth({ sub, email, ... })"
    AuthStore->>PostHog: "identify(sub ?? email, { email })"
    Note over PostHog: sub used as distinct_id, email as person property

    Note over Browser,PostHog: buildApplicationUrl (logged-out visitor)
    Browser->>AuthStore: getState().auth null
    Browser->>PostHog: get_distinct_id() UUID
    Browser->>Browser: "append prefill_PostHog Distinct ID=UUID"

    Note over Browser,PostHog: buildApplicationUrl (logged-in user)
    Browser->>AuthStore: getState().auth truthy
    Browser->>Browser: skip distinct ID

    Note over Browser,PostHog: Logout
    Browser->>AuthStore: setAuth(null)
    AuthStore->>PostHog: reset()
Loading

Reviews (2): Last reviewed commit: "[refactor] Gate application-url distinct..." | Re-trigger Greptile

Comment thread apps/website/src/lib/utils.ts Outdated
@Will-Howard
Will-Howard temporarily deployed to wh-2713-website-identify-sub - bluedot-preview PR #2806 July 19, 2026 15:00 — with Render Destroyed
@Will-Howard
Will-Howard temporarily deployed to wh-2713-website-identify-sub - bluedot-storybook-preview PR #2806 July 19, 2026 15:00 — with Render Destroyed
@Will-Howard
Will-Howard marked this pull request as ready for review July 19, 2026 15:04
@Will-Howard
Will-Howard merged commit 6e7c6b1 into master Jul 19, 2026
10 checks passed
@Will-Howard
Will-Howard deleted the wh-2713-website-identify-sub branch July 19, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant