feat(auth): add Ory auth provider integration#357
Conversation
PR SummaryHigh Risk Overview Auth.js is configured in The Ory auth provider reads Auth.js sessions for API clients switch from Middleware wraps Auth.js in Ory mode, redirects legacy 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. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 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".
6461f1c to
0b383da
Compare
There was a problem hiding this comment.
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.
0b383da to
acdcc60
Compare
acdcc60 to
1a5d00d
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ 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.
|
|
||
| signOut() { | ||
| return Promise.resolve({ redirectTo: ORY_SIGN_OUT_FLOW_PATH }) | ||
| }, |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 1a5d00d. Configure here.
1a5d00d to
d0e26f9
Compare
d0e26f9 to
0651a6e
Compare
| ORY_POST_LOGOUT_PATH, | ||
| } from '@/core/server/auth/ory/signout' | ||
| import { l, serializeErrorForLog } from '@/core/shared/clients/logger/logger' | ||
|
|
There was a problem hiding this comment.
🔒 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.
Reviewed by Cursor Security Reviewer for commit 0651a6e. Configure here.


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