Skip to content

fix(dashboard): rewrite proxied OAuth redirects to public origin - #376

Draft
M-DGayle wants to merge 1 commit into
oblien:mainfrom
Madd-Technologies:fix/mcp-oauth-proxy-location
Draft

fix(dashboard): rewrite proxied OAuth redirects to public origin#376
M-DGayle wants to merge 1 commit into
oblien:mainfrom
Madd-Technologies:fix/mcp-oauth-proxy-location

Conversation

@M-DGayle

@M-DGayle M-DGayle commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • rewrite same-origin Location responses from the private dashboard API upstream to the configured public OpenShip origin
  • leave redirects to external origins unchanged, including native MCP clients' loopback OAuth callbacks
  • add focused regression coverage for the OpenShip self-redirect and the client callback boundary

Root cause

The same-host dashboard proxy streamed upstream response headers verbatim. During MCP OAuth, Better Auth adds prompt=consent by redirecting back to the authorize endpoint using the API request's internal origin (http://127.0.0.1:4000). A remote browser therefore followed the private VM address and failed before the consent page could load.

Impact

External MCP clients such as Codex can complete OAuth against a self-hosted OpenShip instance served through the dashboard proxy. The API and dashboard may remain bound to loopback; this change does not require opening another port or weakening authentication.

Validation

  • reproduced the released v0.5.0 behavior: the public authorize request returned Location: http://127.0.0.1:4000/...
  • deployed the same rewrite to a loopback-only self-hosted instance and verified the redirect now stays on its HTTPS public origin with no internal port
  • completed codex mcp login openship; codex mcp list reports the server as OAuth
  • bun run --cwd apps/dashboard test — 123 tests passed
  • bunx tsc --noEmit -p apps/dashboard/tsconfig.json — passed
  • bunx prettier --check ... for all changed files — passed
  • NEXT_PUBLIC_API_PROXY=true INTERNAL_API_URL=http://127.0.0.1:4000 OPENSHIP_PUBLIC_URL=https://ops.example.com bun run --cwd apps/dashboard build — passed

The repository's current bun run --cwd apps/dashboard lint command was also attempted, but Next 16 interprets next lint as a project-directory argument and exits with Invalid project directory .../apps/dashboard/lint. The TypeScript check and production build both pass.

Exclusions

  • no OAuth scopes, consent behavior, cookies, or session handling changed
  • no new endpoint, dependency, database change, or public network exposure
  • no unrelated formatting changes

Risk

The rewrite applies only when the upstream Location resolves to the same origin as the configured private API upstream. Redirects to a Codex/Claude loopback callback or any other external origin are preserved byte-for-byte.

Related to #346 and #119.

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