Skip to content

feat(core): branded DCR OAuth providers (WorkOS, Auth0, Clerk, Stytch, Descope)#879

Open
harijoe wants to merge 2 commits into
mainfrom
julien/sky-447-branded-providers-workos-okta-descope-stytch
Open

feat(core): branded DCR OAuth providers (WorkOS, Auth0, Clerk, Stytch, Descope)#879
harijoe wants to merge 2 commits into
mainfrom
julien/sky-447-branded-providers-workos-okta-descope-stytch

Conversation

@harijoe

@harijoe harijoe commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add branded DCR OAuth providers in packages/core.
  • workosProvider, auth0Provider, clerkProvider, stytchProvider, descopeProvider.
  • Each is a thin wrapper over the generic customProvider (feat(core): customProvider (SKY-446) #878).
  • customProvider discovers the IdP's OAuth metadata and verifies JWTs via JWKS.
  • Wire an example app per provider under examples/auth-*; all five verified end to end on Alpic.

Architecture Notes

  • audience is now optional in customProvider/verify — when omitted, the aud check is skipped.
  • Needed for Clerk, whose tokens carry no aud claim; clerkProvider has no audience option.
  • Binding providers (workos/auth0/stytch/descope) re-require audience so it can't be silently dropped.

Relationship to #848 (community Descope example)

This supersedes #848 (@mrunankpawar) — please close #848 in favor of the branded descopeProvider here, crediting the contributor.

Carried over / improved vs #848:

  • Same demo app — coffee-data.ts, the view, and helpers.ts are byte-identical; the README is fuller (122 vs 85 lines).
  • Added Descope MCP Server auth #848's manual src/auth.ts (hardcoded JWKS URL, aud = ${SERVER_URL}/mcp) is replaced by the discovery-based branded descopeProvider.
  • Audience corrected: Descope binds the token aud to [DCR client id, project id], so the audience must be the Project ID (verified working). Added Descope MCP Server auth #848's ${SERVER_URL}/mcp does not match current Descope tokens.

Validation (Alpic + playground)

Beyond the unit tests, every example was deployed to Alpic and driven through the complete OAuth flow in the playground — DCR, IdP sign-in/consent, token verification, and a successful authenticated tool call:

  • WorkOS — example-workos-1210dbbd.alpic.live
  • Auth0 — example-auth0-00afc280.alpic.live
  • Clerk — example-clerk-2480a040.alpic.live
  • Stytch — example-stytch-3c5fa3cc.alpic.live
  • Descope — example-descope-8cb43574.alpic.live

Each verified end to end: build-time metadata capture → /.well-known/oauth-protected-resource 200 → 401 + WWW-Authenticate on an unauthenticated /mcp → IdP sign-in/consent → token aud/issuer verified by the provider → tool call succeeds. Per-IdP setup was validated too (DCR enabled; resource/audience configured; Stytch's self-hosted consent pages + SDK domain allowlist; Descope MCP Server).

Greptile Summary

This PR introduces five branded DCR OAuth providers (workosProvider, auth0Provider, clerkProvider, stytchProvider, descopeProvider) as thin wrappers over an expanded customProvider, and refactors the corresponding example apps to use them. It also makes audience optional in customProvider/verify to accommodate Clerk tokens, which carry no aud claim.

  • Provider layer: Each branded provider delegates to customProvider after normalising the issuer URL; clerkProvider explicitly omits audience to skip the aud check; descopeProvider derives the Descope Project ID from the MCP Server URL as the default audience.
  • Discovery update: discoverAuthorizationServer now continues past a valid OIDC document that lacks registration_endpoint, preferring the document that advertises DCR (handles Clerk's split metadata shape).
  • Example refactor: All five example apps drop their hand-rolled auth boilerplate (manual metadata routers, SDK-specific verify functions, CORS proxies) in favour of the new one-liner oauth: await <provider>(…) constructor option.

Confidence Score: 4/5

Safe to merge after fixing the Clerk README's phantom CLERK_AUDIENCE env variable; all five providers have been end-to-end validated and the core token verification logic is sound.

The Clerk README instructs users to set CLERK_AUDIENCE in their .env file, but env.ts never reads it and clerkProvider accepts no audience parameter. A user who follows the setup guide sets the variable, sees no errors (it is silently ignored), and is left debugging why audience-based access control has no effect.

examples/auth-clerk/README.md — the .env block includes CLERK_AUDIENCE which is not consumed anywhere in the example code.

Reviews (21): Last reviewed commit: "feat(examples): wire auth examples for t..." | Re-trigger Greptile

@harijoe harijoe changed the base branch from main to julien/sky-446-generic-custom-provider-abstraction-dcr-compatible June 18, 2026 13:45
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch 2 times, most recently from 11983ad to 585d101 Compare June 18, 2026 13:48
@mintlify

mintlify Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
skybridge-staging 🟢 Ready View Preview Jun 18, 2026, 1:51 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread packages/core/src/server/auth/providers/stytch.ts
Comment thread packages/core/src/server/auth/providers/descope.ts Outdated
Comment thread packages/core/src/server/auth/providers/custom.ts
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from 4862321 to d0c46c8 Compare June 18, 2026 16:12
Comment thread packages/core/src/server/auth/discovery.ts
Base automatically changed from julien/sky-446-generic-custom-provider-abstraction-dcr-compatible to main June 19, 2026 13:37
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from 9b8da36 to 47e5031 Compare June 19, 2026 15:34
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from 47e5031 to e1b562b Compare June 19, 2026 15:37
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from e1b562b to 6768374 Compare June 19, 2026 16:07
@harijoe harijoe changed the title feat(core): branded DCR providers — WorkOS, Stytch, Descope (SKY-447) feat(core): branded DCR OAuth providers (WorkOS, Auth0, Clerk, Stytch, Descope) Jun 19, 2026
Comment thread examples/auth-descope/README.md Outdated
Comment thread examples/auth-descope/.env.example Outdated
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from 6768374 to 6df104e Compare June 19, 2026 16:29
Comment thread packages/core/src/server/auth/providers/descope.ts Dismissed
@harijoe harijoe force-pushed the julien/sky-447-branded-providers-workos-okta-descope-stytch branch from 338dd01 to cd3cfe9 Compare June 19, 2026 17:05
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.

3 participants