I’m using a Vercel Multi-Zone setup where one project acts as the public entry point, and another project is mounted behind it via rewrites.
The issue happens only when Vercel Authentication / Deployment Protection is enabled on the destination zone.
In short:
- Project A is the public/root domain.
- Project B is mounted under Project A via a rewrite.
- Without Vercel Authentication on Project B, the browser stays on Project A’s domain as expected.
- With Vercel Authentication enabled on Project B, the authentication flow redirects the browser to Project B’s domain.
I would like to keep the browser URL on Project A’s domain while still protecting direct access to Project B’s preview/deployment URLs.
Current behavior
Given this setup:
https://a.example.com/some-path
-> rewrite to Project B
When Vercel Authentication is disabled on Project B, the browser URL remains:
https://a.example.com/some-path
This is the expected Multi-Zone rewrite behavior.
However, when Vercel Authentication is enabled on Project B, accessing the same path from Project A causes the browser to enter the Vercel Authentication flow and eventually navigate to Project B’s domain.
For example, the browser may end up at something like:
https://b.vercel.app/some-path
or another Project B deployment/custom domain.
So the user-facing domain changes from Project A to Project B.
Expected behavior
When a user accesses Project B through Project A’s rewrite, I expected the browser URL to remain on Project A’s domain throughout the authentication flow.
Expected:
https://a.example.com/some-path
The destination zone should be protected, but the user should not be redirected to or exposed to Project B’s domain.
Ideally, I would like this behavior:
User -> https://a.example.com -> authenticated
https://a.example.com -> rewrite/proxy -> protected Project B
Direct access to Project B URL -> still protected
Browser URL -> always remains https://a.example.com
Configuration
Project A has a rewrite to Project B.
Example vercel.json / rewrite configuration:
{
"rewrites": [
{
"source": "/some-path/:path*",
"destination": "https://b.example.com/:path*"
}
]
}
or conceptually:
/some-path/:path* -> https://b.vercel.app/:path*
Steps to reproduce
-
Create Project A on Vercel.
-
Assign a custom domain to Project A, for example:
https://a.example.com -
Create Project B on Vercel.
-
Add a rewrite in Project A that forwards a path to Project B.
Example:
https://a.example.com/some-path -> https://b.example.com -
Open:
https://a.example.com/some-path -
Confirm that the browser URL stays on
a.example.comwhen Vercel Authentication is disabled on Project B. -
Enable Vercel Authentication / Deployment Protection on Project B.
-
Open the same URL again:
https://a.example.com/some-path -
The browser is redirected through the Vercel Authentication flow and ends up on Project B’s domain instead of staying on Project A’s domain.
Question
Is this behavior expected when using Vercel Authentication with Multi-Zone rewrites?
If it is expected, what is the recommended architecture for this use case?
Specifically:
- Can Vercel Authentication preserve the original host when the request comes through a rewrite?
- Is there a supported way to protect Project B while keeping the browser URL on Project A?
- Is using
x-vercel-protection-bypassfrom a server-side proxy in Project A the recommended approach? - Can this be done with Vercel rewrites directly, or does it require a Route Handler / Middleware / custom reverse proxy?
Project information
- Framework: Next.js
- Hosting: Vercel
- Architecture: Multi-Zone
- Project A: public/root project with the user-facing custom domain
- Project B: destination zone mounted behind Project A via rewrite
- Environment: Preview and Production
- Vercel Authentication / Deployment Protection:
- Disabled on Project B: rewrite works and the browser stays on Project A’s domain
- Enabled on Project B: browser is redirected to Project B’s domain during authentication
Security concern
A possible workaround is to disable Vercel Authentication on Project B and only protect Project A.
However, if Project B is not protected, then Project B’s preview/deployment URLs may be directly accessible by anyone who knows the URL.
So I am looking for a setup where:
Access through Project A -> allowed after authentication
Direct access to Project B preview/deployment URL -> protected
Browser URL -> always remains on Project A's domain