Skip to content

feat(auth): add Ory auth provider integration#357

Open
ben-fornefeld wants to merge 1 commit into
mainfrom
pr-2-dashboard-ory-provider-integration-eng-4125
Open

feat(auth): add Ory auth provider integration#357
ben-fornefeld wants to merge 1 commit into
mainfrom
pr-2-dashboard-ory-provider-integration-eng-4125

Conversation

@ben-fornefeld
Copy link
Copy Markdown
Member

@ben-fornefeld ben-fornefeld commented Jun 5, 2026

Summary

  • adds the Ory/Auth.js hosted auth provider implementation and OAuth routes
  • wires Ory bearer auth headers through dashboard API/infra API calls
  • adds Ory identity/profile resolution, dashboard bootstrap, signout, token refresh, and account update flows
  • adds focused Ory auth tests on top of the profile/prep PR

Stacked on #356. Retarget this PR to main after #356 merges.

@ben-fornefeld ben-fornefeld requested a review from drankou as a code owner June 5, 2026 20:31
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 5, 2026

ENG-4125

@cla-bot cla-bot Bot added the cla-signed label Jun 5, 2026
@cursor
Copy link
Copy Markdown

cursor Bot commented Jun 5, 2026

PR Summary

High Risk
Large authentication and authorization surface: new OAuth/session/bootstrap paths, token refresh, and switching how all dashboard/infra API calls authenticate when Ory is enabled.

Overview
Adds a full Ory + Auth.js path when AUTH_PROVIDER=ory, replacing the previous fail-closed Ory stub with OAuth via Hydra, JWT sessions, and downstream API auth.

Auth.js is configured in src/auth.ts at /api/auth/oauth with the Ory Hydra provider. New routes handle oauth-start (sign-in/sign-up/reauth with Hydra prompts), oauth-recover (OAuth error recovery), signout-flow (Auth.js + Kratos session revoke + RP-initiated logout), and bootstrap-failed (deny sign-in if dashboard user bootstrap fails, then clear Ory session). Sign-in callbacks bootstrap new users via POST /admin/users/bootstrap, persist Ory tokens in the JWT, resolve Kratos identityId, and optionally attach signup IP/UA metadata.

The Ory auth provider reads Auth.js sessions for getAuthContext, loads live profiles from Kratos Identity API, enforces reauth freshness (auth_time) before password/email changes, and updates identities via admin API (password through updateIdentity import path). oryAuthAdmin implements user/email lookups by subject and external id.

API clients switch from SUPABASE_AUTH_HEADERS to authHeaders(), which sends Authorization: Bearer and X-Team-ID in Ory mode. Env validation and .env.example document Ory/Auth.js secrets.

Middleware wraps Auth.js in Ory mode, redirects legacy /sign-in and /sign-up to oauth-start, and treats sessions with RefreshTokenError as logged out. Dashboard entry routes use provider-aware sign-out when team resolution fails.

Tests cover bootstrap, callbacks, identity resolution, flows, routes, headers, and refresh token behavior.

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

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

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

Project Deployment Actions Updated (UTC)
web Ready Ready Preview, Comment Jun 6, 2026 2:08am
web-juliett Ready Ready Preview, Comment Jun 6, 2026 2:08am

Request Review

Comment thread src/features/dashboard/terminal/sandbox-session.ts Outdated
Comment thread src/core/server/auth/ory/auth-route-redirect.ts
Comment thread src/app/api/auth/oauth-start/route.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce88f81bc0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/configs/api.ts
Comment thread src/proxy.ts
Comment thread src/features/dashboard/sandbox/inspect/context.tsx Outdated
Comment thread src/configs/api.ts
Base automatically changed from pr-1-dashboard-user-profile-ory-prep-eng-4125 to main June 5, 2026 21:32
@ben-fornefeld ben-fornefeld changed the title Add Ory auth provider integration feat(auth): add Ory auth provider integration Jun 5, 2026
Copilot AI review requested due to automatic review settings June 5, 2026 21:34
@ben-fornefeld ben-fornefeld force-pushed the pr-2-dashboard-ory-provider-integration-eng-4125 branch from 6461f1c to 0b383da Compare June 5, 2026 21:34
Comment thread src/core/server/auth/ory/authjs-callbacks.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an Ory-backed Auth.js authentication provider and associated OAuth routes, and updates downstream API/infra calls to send provider-appropriate auth headers (Supabase headers vs Ory Bearer) while adding test coverage for the new Ory auth flows.

Changes:

  • Add Auth.js (NextAuth v5) integration with Ory Hydra, including OAuth entry/recovery routes and logout flows.
  • Implement Ory auth provider/admin capabilities: session → AuthContext mapping, identity resolution, profile/account update flows, Kratos session revocation, and token refresh.
  • Replace direct Supabase header construction with a shared authHeaders() helper across server modules and add focused unit/integration tests for Ory behaviors.

Reviewed changes

Copilot reviewed 62 out of 64 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vitest.config.ts Adjust Vitest config to inline Auth.js deps for ESM/Next resolver compatibility.
tests/unit/signout-flow.test.ts Tests Ory sign-out flow (Auth.js signOut + Kratos revoke + Hydra logout redirect).
tests/unit/bootstrap-failed-route.test.ts Tests bootstrap-failure logout flow and cookie cleanup behavior.
tests/unit/auth-ory-provider.test.ts Tests Ory provider session handling and RefreshTokenError unauth behavior.
tests/unit/auth-ory-provider-profile.test.ts Tests Ory live profile resolution via IdentityApi (id vs external_id fallback).
tests/unit/auth-ory-provider-account.test.ts Tests Ory account update flow, reauth freshness gating, and session revocation.
tests/unit/auth-ory-identity.test.ts Tests mapping from Kratos Identity → dashboard AuthUser fields/capabilities.
tests/unit/auth-ory-flows.test.ts Tests trait patch vs password updateIdentity behavior + error mapping.
tests/unit/auth-ory-find-identity.test.ts Tests subject/email identity resolution strategy behavior.
tests/unit/auth-ory-authjs-callbacks.test.ts Tests Auth.js callback wiring: signIn bootstrap gate, jwt persistence/refresh, session projection.
tests/unit/auth-ory-admin.test.ts Tests admin identity lookup and email resolution behavior for app user IDs.
tests/unit/auth-headers.test.ts Tests authHeaders() output for supabase vs ory modes.
tests/integration/auth-ory-dashboard-bootstrap.test.ts Integration tests for dashboard bootstrap confirmation/import behavior.
src/types/next-auth.d.ts Adds Session/JWT augmentation for Ory token fields (access/id/refresh/identityId/error).
src/proxy.ts Wrap middleware proxy with Auth.js middleware in Ory mode and avoid auth-route redirect ping-pong on poisoned sessions.
src/lib/utils/server.ts Switch token generation infra call to use authHeaders() (provider-agnostic).
src/lib/env.ts Add env schema entries for Auth.js + Ory configuration.
src/features/dashboard/terminal/sandbox-session.ts Use authHeaders() when connecting/creating terminal sandboxes.
src/features/dashboard/sandbox/inspect/context.tsx Use authHeaders() for sandbox inspect connections.
src/core/server/functions/sandboxes/get-team-metrics-max.ts Use authHeaders() for infra metrics requests.
src/core/server/functions/sandboxes/get-team-metrics-core.ts Use authHeaders() for infra metrics requests.
src/core/server/auth/ory/signout.ts Introduce Ory signout constants + Hydra logout URL builder.
src/core/server/auth/ory/refresh-token.ts Add refresh-token exchange logic for Ory OAuth2 tokens.
src/core/server/auth/ory/provider.ts Implement the Ory AuthProvider (AuthContext, profile, updateUser, reauth dispatch, signout, other session revocation).
src/core/server/auth/ory/ory-error.ts Add helper to unpack Ory SDK ResponseError bodies for better classification/logging.
src/core/server/auth/ory/kratos-session.ts Add Kratos session revocation with contention retries and structured logging.
src/core/server/auth/ory/jwt-claims.ts Add lightweight JWT claim decoding + claim helpers for bootstrap/freshness.
src/core/server/auth/ory/identity.ts Add mapping helpers from Auth.js Session / Ory Identity to dashboard AuthUser.
src/core/server/auth/ory/freshness.ts Add auth_time parsing and reauth freshness window logic.
src/core/server/auth/ory/flows.ts Add Ory identity update flows (traits patch vs password import via updateIdentity) + error classification.
src/core/server/auth/ory/find-identity.ts Add multi-strategy identity resolution (id → external_id → email) with optional credential includes.
src/core/server/auth/ory/dashboard-bootstrap.ts Add dashboard bootstrap confirmation/import flow driven by OIDC claims + team lookup.
src/core/server/auth/ory/client.ts Add cached Ory IdentityApi client using ORY_SDK_URL + ORY_PROJECT_API_TOKEN.
src/core/server/auth/ory/build-start-url.ts Add helper to construct oauth-start URLs for intent/returnTo.
src/core/server/auth/ory/authjs-callbacks.ts Add Auth.js callbacks bridging Ory tokens to JWT/session + bootstrap gate + refresh behavior.
src/core/server/auth/ory/authjs-boundary.ts Add typed boundary helpers for extracting Ory fields from Auth.js account/profile/jwt/session.
src/core/server/auth/ory/auth-route-redirect.ts Add middleware-level redirects mapping legacy auth routes to Ory hosted UI intents.
src/core/server/auth/ory/admin.ts Implement Ory AuthAdmin (getUserById, getEmailsByIds).
src/core/server/auth/index.ts Wire Ory provider/admin into the auth switch (replacing the prior Ory stub provider).
src/core/server/actions/sandbox-actions.ts Use authHeaders() for sandbox kill action infra call.
src/core/modules/webhooks/repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/templates/repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/teams/user-teams-repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/teams/teams-repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/sandboxes/repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/keys/repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/builds/repository.server.ts Switch repository auth header dependency to authHeaders().
src/core/modules/billing/repository.server.ts Switch billing API auth header construction to authHeaders().
src/configs/api.ts Introduce provider-aware authHeaders() and a new team header constant for non-Supabase providers.
src/auth.ts Add NextAuth (Auth.js) configuration for Ory Hydra provider + callbacks and basePath routing.
src/app/sbx/new/route.ts Use authHeaders() for sandbox creation requests.
src/app/dashboard/terminal/page.tsx Use authHeaders() for sandbox existence checks.
src/app/dashboard/route.ts Adjust “no personal team” sign-out/redirect behavior for Ory vs Supabase.
src/app/dashboard/account/route.ts Adjust “no personal team” sign-out/redirect behavior for Ory vs Supabase.
src/app/dashboard/(resolvers)/inspect/sandbox/[sandboxId]/route.ts Use authHeaders() for sandbox existence checks.
src/app/api/auth/oauth/signout-flow/route.ts Add route to perform full Ory signout (Auth.js + Kratos revoke + Hydra logout).
src/app/api/auth/oauth/bootstrap-failed/route.ts Add route to clear local session and redirect through Hydra logout when bootstrap fails.
src/app/api/auth/oauth/[...nextauth]/route.ts Add NextAuth handlers route for the Ory/Auth.js basePath.
src/app/api/auth/oauth-start/route.ts Add server-side entrypoint for starting Ory OAuth flow with intent handling.
src/app/api/auth/oauth-recover/route.ts Add recovery route to avoid showing Auth.js error page and prevent tight redirect loops.
scripts/check-app-env.ts Enforce required env variables when AUTH_PROVIDER=ory.
package.json Add dependencies for Ory client and NextAuth v5 beta.
bun.lock Lockfile updates for new auth dependencies.
.env.example Document required Ory/Auth.js configuration variables and migration-related flags.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/server/auth/ory/refresh-token.ts Outdated
Comment thread src/configs/api.ts
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1a5d00d. Configure here.

Comment thread src/core/server/auth/ory/dashboard-bootstrap.ts

signOut() {
return Promise.resolve({ redirectTo: ORY_SIGN_OUT_FLOW_PATH })
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ory signOut ignores returnTo

Medium Severity

oryAuthProvider.signOut always returns ORY_SIGN_OUT_FLOW_PATH and never reads SignOutOptions.returnTo, unlike the Supabase provider. Callers such as signOutAction pass returnTo, but Ory sign-out cannot honor post-logout navigation.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1a5d00d. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, expected

Comment thread src/core/server/auth/ory/ory-error.ts Outdated
@ben-fornefeld ben-fornefeld force-pushed the pr-2-dashboard-ory-provider-integration-eng-4125 branch from 1a5d00d to d0e26f9 Compare June 6, 2026 00:08
ORY_POST_LOGOUT_PATH,
} from '@/core/server/auth/ory/signout'
import { l, serializeErrorForLog } from '@/core/shared/clients/logger/logger'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: MEDIUM
The new sign-out flow is implemented as an unauthenticated GET route but performs state-changing actions (signOut plus Ory session revocation). Because browsers can be induced to make cross-site GET navigations, this enables logout CSRF.

Impact: An attacker can force a logged-in victim to be signed out and have their Ory sessions revoked, causing involuntary session disruption without user intent.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 0651a6e. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants