Skip to content

Capture OAuth signup attribution - #209

Open
Jayko001 wants to merge 2 commits into
mainfrom
hypeship/oauth-attribution-survey
Open

Jayko001 wants to merge 2 commits into
mainfrom
hypeship/oauth-attribution-survey

Conversation

@Jayko001

@Jayko001 Jayko001 commented Sep 22, 2026

Copy link
Copy Markdown

summary

  • require two attribution answers before an org-less OAuth user can create an organization
  • preserve dynamic OAuth client registration metadata and record the observed client ID and redirect origin
  • store the answers and client context on the Clerk user before organization creation
  • keep organization creation blocked when attribution persistence fails

The existing $mcp_initialize event already records $mcp_client_name and $mcp_client_version with the organization group. Together, these fields distinguish discovery, connection trigger, OAuth application, and the first MCP runtime without treating any one signal as authoritative.

The analytics half is kernel/kernel#4269. Merge and deploy both changes before evaluating coverage.

data captured

  • firstDiscoverySource
  • connectorTrigger
  • signupPath
  • oauthClientId
  • oauthClientName (self-reported during dynamic registration)
  • oauthClientUri (self-reported origin)
  • oauthRedirectOrigin (observed authorization request)
  • oauthClientType

tests

  • bunx tsc --noEmit
  • bun test (611 passing)
  • production bun run build with local placeholder configuration

Note

Medium Risk
Touches OAuth registration and Clerk user metadata with redirect-uri validation; Redis metadata loss is non-blocking for registration but affects attribution enrichment.

Overview
Adds OAuth signup attribution for users on /select-org who have no organization: they must answer a short discovery/trigger survey before Create organization appears. Answers and OAuth context are written to Clerk publicMetadata via saveOAuthAttribution; returning users with valid metadata skip the survey.

Dynamic registration now stores client name, optional client_uri, and redirect URIs in Redis (180-day TTL) after Clerk creates the app. Attribution enriches metadata with oauthClientId, registered client name/URI, client type, and an observed redirect origin only when the authorize query redirect_uri matches stored redirects (localhost expansion included); mismatches drop oauthRedirectOrigin so arbitrary callback URLs are not trusted.

Registration failures to save metadata are logged and do not fail the registration response; survey save failures keep org creation blocked until success.

Reviewed by Cursor Bugbot for commit cecbc94. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Sep 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
mcp Ready Ready Preview Sep 22, 2026 9:18pm UTC

The select-org query string is browser-controlled, so a mismatched
redirect_uri could pair a real client ID with an unrelated origin.
For dynamically registered clients, drop the redirect origin unless it
matches one of the client's registered redirect URIs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview cecbc945 Deployed Sep 22, 2026 by vercel[bot]
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