---
title: Application authentication on Vercel
description: "Secure application authentication on Vercel across layers: proxy checks, the Data Access Layer, PPR-safe rendering, and platform controls like Firewall and BotID."
url: /kb/guide/application-authentication-on-vercel
canonical_url: "https://vercel.com/kb/guide/application-authentication-on-vercel"
published: 2025-11-03
last_updated: 2026-08-18
authors: Vercel
related:
  - /docs/vercel-firewall
  - /docs/deployment-protection
  - /docs/networking/secure-compute
  - /docs/botid
  - /docs/security/compliance
  - /blog/ai-sdk-6
  - /changelog/oauth-support-added-to-mcp-adapter
  - /kb/guide/protect-ai-endpoints-with-vercel-botid
  - /kb/guide/is-vercel-soc-2-compliant
  - /changelog/vercel-firewall-proactively-protects-against-vulnerability-with-middleware
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---
<!-- docsgraph:related -->
## Related pages

> **For AI agents:** Follow these links to understand how this page connects to the rest of the Vercel ecosystem. For the full cross-link map (inbound, outbound, prerequisites, and semantic neighbors), see the .graph.md link below.

- [Automated & Agent Access](https://vercel.com/docs/deployment-protection/automated-agent-access?from=related) — Grant AI agents, CI/CD pipelines, MCP servers, and testing tools access to Vercel deployments that have Deployment Prote
- [Restrict access to deployments with Vercel Authentication](https://vercel.com/docs/deployment-protection/methods-to-protect-deployments/vercel-authentication?from=related) — Vercel Authentication restricts access to your deployments so only authorized users can view and comment on your site.
- [Vercel Deployment Guide](https://ai-sdk.dev/docs/advanced/vercel-deployment-guide?from=related)
- [Authentication](https://eve.dev/docs/guides/auth-and-route-protection?from=related) — Secure your agent's HTTP routes with an ordered auth walk, verifier helpers, and connection OAuth via Vercel Connect.
- [Vercel MCP server](https://vercel.com/docs/agent-resources/vercel-mcp?from=related) — Vercel MCP has tools available for searching docs, managing teams, projects, and deployments, and querying Web Analytics
- [The complete guide to authentication on Vercel](https://vercel.com/kb/guide/complete-guide-authentication-vercel?from=related) — Learn how to implement authentication in your Vercel applications. Covers NextAuth/Auth.js setup, environment variable c
- [How to enable CORS on Vercel](https://vercel.com/kb/guide/how-to-enable-cors?from=related) — Learn how to enable CORS on Vercel with vercel.json, Routing Middleware, framework config, and route handlers, plus how
- [How to identify and authorize visitors with the Vercel Passport token in Next.js](https://vercel.com/kb/guide/vercel-passport-nextjs?from=related) — Read the Vercel Passport token server-side in a Next.js app to identify visitors with the external_sub claim and authori
- [Vercel vs Fastly](https://vercel.com/kb/guide/vercel-vs-fastly?from=related) — A detailed guide to Vercel vs Fastly: full-stack application platform vs edge infrastructure layer, covering framework s
- [How to Utilize Vercel’s Bot Management Features](https://vercel.com/kb/guide/how-to-utilize-vercels-bot-management-features?from=related) — A practical, step-by-step guide to identifying unwanted automated traffic and securing your Vercel apps with Bot Protect

Full cross-link map for this page: [/kb/guide/application-authentication-on-vercel.graph.md](/kb/guide/application-authentication-on-vercel.graph.md)
<!-- /docsgraph:related -->


Authentication is one of the hardest parts of an application to get right, and one of the most costly to fix after launch. No single layer is enough on its own, so a reliable setup checks the session in more than one place. That way, a gap in one layer doesn't expose protected data.

This guide covers how authentication on Vercel fits together across layers, from the proxy that runs before your pages to the Data Access Layer that sits next to your data. It also covers the platform controls that handle threats your application code can't handle, and the pitfalls that most often show up in production.

## How authentication on Vercel works across layers

Authentication on Vercel works best as a series of checks rather than a single gate. Each layer catches what an earlier one might miss, so a request that slips past one check still meets another before it reaches protected data.

Three layers do most of the work:

- **Proxy:** Runs before your pages and handles fast, optimistic checks based on the session cookie.
  
- **Data Access Layer:** Sits next to your database and verifies the session again before any read or write.
  
- **Server Actions:** Treat every mutation as a public endpoint and confirm the user is allowed to perform it.
  

Checking in all three places is deliberate redundancy. If one layer has a bug, the others still hold. For identity, sessions, and authorization logic, use a dedicated provider such as Clerk, Auth.js, or Auth0 rather than building your own, and structure the checks around the [Next.js authentication guide](https://nextjs.org/docs/app/guides/authentication). Vercel's platform security sits beneath all of this and is covered later in this guide.

## Handle authentication checks in the proxy layer

The layer closest to your users is the proxy, and it changed in Next.js 16\\. The file that used to be `middleware.ts` is now `proxy.ts`, and the exported function is named `proxy` instead of `middleware`. It runs on the Node.js runtime by default.

That runtime change removes a long-standing constraint. Earlier versions ran this layer only on the Edge Runtime, which ruled out packages like `jsonwebtoken`, `bcrypt`, Prisma adapters, and the Node.js `crypto` module. Auth libraries shipped separate edge-compatible bundles to work around it. On Next.js 16, that work is gone, since full Node.js APIs and npm packages are available.

The proxy runtime is Node.js and can't be configured, so the Edge Runtime isn't available in `proxy.ts`. If a migrated project still needs Edge behavior, keep the deprecated `middleware.ts` file, which Next.js supports for now with a warning.

Use the proxy for fast, optimistic checks based on the session cookie, and keep database calls out of it. The proxy runs on every route, including prefetched ones, so a database round trip here repeats on every navigation. A redirect based on a missing session cookie is the right kind of work for this layer.

Here's a proxy that redirects unauthenticated requests away from protected routes:

```javascript
// proxy.ts (Next.js 16+)
import { NextRequest, NextResponse } from 'next/server'
import { decrypt } from '@/app/lib/session'
import { cookies } from 'next/headers'

const protectedRoutes = ['/dashboard']

export default async function proxy(req: NextRequest) {
  const path = req.nextUrl.pathname
  const cookie = (await cookies()).get('session')?.value
  const session = await decrypt(cookie)

  if (protectedRoutes.includes(path) && !session?.userId) {
    return NextResponse.redirect(new URL('/login', req.url))
  }

  return NextResponse.next()
}
```

This check is optimistic on purpose. It confirms a session cookie exists and redirects when it doesn't, then hands off to the Data Access Layer for the authoritative check. For the full migration steps, see the [Next.js 16 upgrade guide](https://nextjs.org/docs/app/guides/upgrading/version-16).

## Render authenticated content with Partial Prerendering

Once a request passes the proxy, rendering is the next place authentication shows up. Partial Prerendering (PPR) changed how authenticated pages load. It's stable in Next.js 16 through Cache Components, which you enable with the `cacheComponents` config flag.

With PPR, Next.js serves a static shell immediately from Vercel's CDN and streams the dynamic, authenticated parts from the origin as they resolve. To make that work on an authenticated page, wrap each auth-gated section in its own `<Suspense>` boundary so it streams independently.

Here's a dashboard that streams two authenticated sections independently:

```javascript
import { Suspense } from 'react'

export default async function DashboardPage() {
  return (
    <>
      <StaticDashboardShell />
      <Suspense fallback={<ProfileSkeleton />}>
        <UserProfile />
      </Suspense>
      <Suspense fallback={<ActivitySkeleton />}>
        <RecentActivity />
      </Suspense>
    </>
  )
}
```

Strict security requirements add two constraints. First, PPR is incompatible with [nonce-based CSP](https://nextjs.org/docs/app/guides/content-security-policy), because the static shell scripts are generated before the request and can't read a per-request nonce. If you need a strict Content Security Policy (CSP), use hash-based CSP with Subresource Integrity instead, which Next.js supports alongside static generation.

Second, run auth checks close to the data rather than in a layout. Layouts don't re-render on client-side navigation, so a check that runs once on the first load won't run again as the user moves between child routes. Put the check in the component that renders protected content, or in the Data Access Layer function that reads it.

Application code handles identity and rendering, but the threats that arrive before your code runs are the platform's job.

## How Vercel platform security supports authentication

Application-level authentication is your responsibility, and so are session cookies, token validation, and authorization checks. The platform handles a different set of threats, including traffic that targets your deployment before your application code runs. The [Vercel Firewall](https://vercel.com/docs/vercel-firewall) mitigates Layer 3, Layer 4, and Layer 7 attacks automatically for every team on every plan, at no extra cost. Blocked traffic is stopped before it reaches your application code.

Four more platform capabilities shape how authentication works on Vercel:

- **Deployment Protection:** Enabled by default for new projects. [Vercel Authentication](https://vercel.com/docs/deployment-protection) restricts preview deployments to your team, and Shareable Links let external collaborators in without a Vercel account. It's available on all plans. Password Protection requires an Enterprise plan or the Advanced Deployment Protection add-on on Pro. Passport (for SAML or OpenID Connect through your identity provider) and Trusted IPs are Enterprise features.
  
- **Secure Compute:** Creates private connections between your Vercel Functions and backend infrastructure. On Enterprise, your deployments run in an isolated private network with dedicated static IP addresses, separate from other customers. Traffic is encrypted with WireGuard, and the keys are generated at instance boot with no persistence or reuse. If your auth backend sits inside a virtual private cloud (VPC), [Secure Compute](https://vercel.com/docs/networking/secure-compute) lets you allow traffic only from your Vercel infrastructure.
  
- **BotID:** An invisible CAPTCHA powered by Kasada that runs without visible challenges. Basic protection is free on all plans, and Deep Analysis adds enhanced detection. Because [BotID](https://vercel.com/docs/botid) runs on every request rather than once per session, you can gate sign-up and sign-in routes and stop automated abuse at the platform layer before it reaches your application logic.
  
- **Compliance evidence:** Vercel maintains SOC 2 Type 2, ISO 27001:2022, and PCI DSS v4.0, with a HIPAA Business Associate Agreement (BAA) available on Enterprise. Its [compliance documentation](https://vercel.com/docs/security/compliance) and Trust Center help regulated teams document transport security and audit readiness beyond their login code.
  

These controls run regardless of whether your application code is perfect. Even so, most authentication failures trace back to a handful of application-level mistakes.

## Common authentication pitfalls on Vercel

Most authentication failures on Vercel come from a small set of recurring mistakes. They tend to cross layers, so a single request can touch cookies, the proxy, Server Components, and environment variables before it breaks.

Here are five patterns to check first:

- **Oversized session cookies:** Some social logins fail when the cookie payload grows too large, often from long profile-photo URLs pushing a JSON Web Token (JWT) past the size limit. Keep session cookies small, move large values out of the cookie, or switch to opaque tokens backed by a server-side session store.
  
- **Token refresh races:** When several requests arrive at once, the proxy can refresh a token in memory but read a stale value before the new one is written to the cookie. Memoize the refresh result within a short window, and run token refresh on the Node.js runtime rather than the Edge Runtime.
  
- **Auth checks on prefetched routes:** The proxy runs on every route, including prefetched ones, so its checks run more often than the visible navigation suggests. Keep proxy checks optimistic and fast, and always add a fallback check in a Server Component or Route Handler. Treat every Server Action as a public endpoint and confirm the user is allowed to perform the mutation.
  
- `**NEXT_PUBLIC_**` **leaks:** Any environment variable prefixed with `NEXT_PUBLIC_` is bundled into client JavaScript and visible to anyone. Keep secrets in server-only environment variables, and review what's exposed before you deploy.
  
- **Auth checks in layouts:** A session check in a layout protects the first page load but not later client-side navigations to child routes. Move the check into the components or Data Access Layer functions that touch protected data.
  

Each of these lives in application code, which is why the redundant checks from the first section matter. When one layer misses, another catches it.

## Extend authentication to AI agents and MCP servers

Authentication now extends past human users to AI agents that call your backend through tools. When an agent connects to a remote Model Context Protocol (MCP) server, it needs the same identity and authorization rigor as a user-facing route.

[AI SDK 6](https://vercel.com/blog/ai-sdk-6) handles the client side of that flow. Its MCP support, stable in the `@ai-sdk/mcp` package, manages the full OAuth sequence for remote MCP servers, including Proof Key for Code Exchange (PKCE) challenges, token refresh, dynamic client registration, and retries when a token expires mid-session.

On the server side, the [MCP adapter](https://vercel.com/changelog/oauth-support-added-to-mcp-adapter) added OAuth support in version 1.0.0, following the MCP Authorization spec. It ships one-click deployable examples with providers such as Better Auth, Clerk, Descope, Stytch, and WorkOS, so you can start with a working setup. Auth.js also works on Vercel and automatically sets the correct host value, removing the need for manual callback URL configuration.

Any endpoint that exposes backend data to an agent through tool use needs the same treatment as a user route. Verify identity, enforce authorization, and audit access for sensitive tools.

## Next steps

With the layers in place, you can put this into practice on a new or existing project. [Start a new project](https://vercel.com/new) and enable Deployment Protection in its settings, or [browse the templates](https://vercel.com/templates) for a framework that includes authentication.

## Related resources

- [Deployment Protection](https://vercel.com/docs/deployment-protection)
  
- [Next.js authentication guide](https://nextjs.org/docs/app/guides/authentication)
  
- [BotID for AI endpoints](https://vercel.com/kb/guide/protect-ai-endpoints-with-vercel-botid)
  
- [AI SDK 6](https://vercel.com/blog/ai-sdk-6)
  
- [Vercel SOC 2 attestation](https://vercel.com/kb/guide/is-vercel-soc-2-compliant)
  

## Frequently asked questions

### Does Vercel replace my authentication provider?

No. Vercel's platform security, including the Firewall, distributed denial-of-service (DDoS) mitigation, Deployment Protection, and encrypted transport, complements your application-level authentication rather than replacing it. Use a dedicated provider such as Clerk, Auth.js, or Auth0, or a custom implementation, to handle user identity, session management, and authorization. The two layers work together.

### Is middleware.ts still supported on Next.js 16 and Vercel?

In Next.js 16, `middleware.ts` was renamed to `proxy.ts`, and the exported function changed from `middleware` to `proxy`. The proxy runs on Node.js and can't be configured for the Edge Runtime. The old `middleware.ts` file still works for Edge use cases but is deprecated and will be removed in a later release.

### Was my Vercel deployment affected by CVE-2025-29927?

Vercel-hosted deployments were protected. The [Vercel Firewall blocked](https://vercel.com/changelog/vercel-firewall-proactively-protects-against-vulnerability-with-middleware) the exploit vector for this Next.js middleware authorization bypass, so no action was required. Self-hosted Next.js applications needed patching to 14.2.25 or 15.2.3, or to the equivalent releases 12.3.5 or 13.5.9, to close the vulnerability.

### What session model should I use for authentication on Vercel?

For most applications, stateless sessions in encrypted, `httpOnly` cookies work well and keep reads fast. If your JWT payload grows large enough to break cookie-based flows, switch to opaque tokens backed by a server-side session store such as Redis. Payload size, more than architecture preference, usually drives that decision.