---
title: Protect internal apps with Vercel Passport and your identity provider
description: Vercel Passport protects internal apps behind your own identity provider, such as Okta or Microsoft Entra ID. Learn how Passport works, how to set it up for a project or team, and how to read visitor identity in your code.
url: "https://vercel.com/kb/guide/vercel-passport"
published: 2026-10-15
last_updated: 2026-10-15
authors: Ben Sabic
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Vercel Passport protects your deployments behind your own identity provider, so visitors sign in with Okta, Microsoft Entra ID, Auth0, or another OpenID Connect provider before they can view a protected deployment. After a visitor signs in, Vercel forwards a signed identity token to your deployment, so your code can personalize pages, restrict routes, and record who did what. Passport is available on Enterprise plans, and you can enable it per project or as a team-wide default.

In this guide, you'll learn how to:

- Understand how Passport authenticates visitors and forwards their identity
  
- Connect Okta or Microsoft Entra ID to Passport
  
- Enable Passport for a project, set a team default, and assign it to existing projects
  
- Read a verified visitor identity in server-side code with `@vercel/passport`
  
- Troubleshoot the most common discovery, sign-in, and identity problems
  

## How does Vercel Passport work?

Vercel Passport runs in Vercel's network before your deployment's routes and middleware execute. Passport has two parts that work together:

- **Connect application:** The Vercel Connect OAuth application that stores your identity provider's issuer, authorization endpoint, token endpoint, client ID, and client secret.
  
- **Project or team setting:** The Passport configuration that points to the Connect application and controls whether Passport is enabled.
  

When a visitor without a session opens a protected deployment, Vercel redirects them to your identity provider. After the provider authenticates them, Vercel validates the response, stores a signed session token in a HttpOnly cookie, and forwards the same token to your deployment in the `x-vercel-oidc-passport-token` request header. Visitors with a valid session can view the deployment until the session expires.

Vercel strips any client-supplied value for `x-vercel-oidc-passport-token` and injects its own verified token, so a visitor can't forge an identity by setting the header themselves. Passport also protects every path on a protected URL, which makes it a good fit for internal apps and a poor fit for apps with public pages.

Passport is one of four Deployment Protection methods, alongside Vercel Authentication, Password Protection, and Trusted IPs. Choose Passport when your visitors already have accounts in your company identity provider, and see [Methods to protect deployments](https://vercel.com/docs/deployment-protection/methods-to-protect-deployments) to compare the options.

## Plans, roles, and pricing for Vercel Passport

Passport is available on [Enterprise plans](https://vercel.com/docs/plans/enterprise). Contact your account team for pricing.

Only team [Owners](https://vercel.com/docs/rbac/access-roles#owner-role) can manage Passport, including enabling it for projects, setting a team default, and creating Connect applications.

## Before you begin

Make sure you have:

- **Owner access:** The Owner role on your Vercel Enterprise team.
  
- **Identity provider:** One that supports OAuth 2.0 or OpenID Connect.
  
- **Identity provider application:** Configured as a confidential client with a client secret. You can create the matching Connect application during Passport setup.
  
- **Redirect URI:** Registered in your identity provider's OAuth application:
  

```plaintext
https://connect.vercel.com/callback
```

## How to connect your identity provider to Passport

Passport connects to your identity provider through a Connect application. Create the application in your identity provider first, then add its credentials to Vercel.

### Connect Okta

Create an Okta OpenID Connect web application, then add its credentials to a Connect application:

1. **Create the app integration:** In the Okta Admin Console, go to **Applications** > **Applications** and select **Create App Integration**. Choose **OIDC - OpenID Connect** and **Web Application**.
   
2. **Add the redirect URI:** Keep the **Authorization Code** grant enabled, then add `https://connect.vercel.com/callback` as a **Sign-in redirect URI**.
   
3. **Assign access:** Save the application and assign the people or groups who should be able to open Passport-protected deployments.
   
4. **Copy the credentials:** Copy the application's client ID and client secret. Then, in **Security** > **API** > **Authorization Servers**, copy the issuer URI of the authorization server that should authenticate visitors.
   
5. **Create the Connect application:** In the Vercel dashboard, create an **OAuth** Connect application and select **Your own credentials**. Enter the exact issuer URI in the **Server URL** field, select **Discover** to fill the endpoints, enter the client ID and client secret, and select **Create Connector**.
   

For Okta's default custom authorization server, the issuer URI looks like this:

```plaintext
https://your_okta_domain.okta.com/oauth2/default
```

Okta organization authorization servers use an issuer URI without the `/oauth2/{authorization_server_id}` segment. Use the exact issuer URI that Okta displays, and don't combine an issuer, endpoints, or JWKS URI from different authorization servers.

The Connect application requests the `openid` scope. Make the `email` and `profile` scopes available in Okta when you want Passport to receive the visitor's email and name.

### Connect Microsoft Entra ID

Create a web application registration in the Microsoft Entra admin center, then add its credentials to a Connect application:

1. **Register the application:** Create a web application registration and add `https://connect.vercel.com/callback` as a web redirect URI.
   
2. **Create a client secret:** Add a client secret, and assign users or groups if your tenant requires user assignment.
   
3. **Create the Connect application:** In the Vercel dashboard, create an **OAuth** Connect application and select **Your own credentials**. Enter your tenant-specific issuer URI in the **Server URL** field, select **Discover**, enter the client ID and client secret, and select **Create Connector**.
   

Use a tenant-specific issuer rather than a multi-tenant endpoint, so Passport can validate a stable issuer:

```plaintext
https://login.microsoftonline.com/your_tenant_id/v2.0
```

## How to enable Vercel Passport for a project

Enable Passport for a single project from that project's Passport settings:

1. **Open Passport settings:** From your Vercel dashboard, open the [Project’s Passport Settings](https://vercel.com/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fsettings%2Fpassport&title=Project+Passport+Settings).
   
2. **Enable Passport:** Turn on the **Passport** toggle.
   
3. **Select a Connect application:** Choose an existing Connect application, or create one from the setup flow. For an OpenID Connect provider, choose **OAuth**, select **Your own credentials**, enter your provider's issuer URI in the **Server URL** field, and select **Discover**. If discovery doesn't work, enter the OAuth endpoints manually.
   
4. **Save your changes:** Click **Save**.
   

New visits to protected deployment URLs use Passport after you save. Existing authenticated sessions can stay valid until they expire.

## How to set a team-wide default for Vercel Passport

Set a team default so new projects inherit your Passport configuration:

1. **Open team settings:** From your Vercel dashboard, open the [Team’s Passport Settings](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fsettings%2Fpassport&title=Team+Passport+Settings).
   
2. **Enable Passport:** Turn on the **Passport** toggle.
   
3. **Select a Connect application:** Choose an existing Connect application, or create one.
   
4. **Save your changes:** Click **Save**.
   

Projects created after you save use this Passport configuration, while existing projects keep their current settings.

## How to assign Vercel Passport to existing projects

Assign the same Connect application to many existing projects at once from your team's Passport settings:

1. **Select projects:** From the [Team Passport Settings](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fsettings%2Fpassport&title=Team+Passport+Settings), select the projects you want to update. You can filter the list to show all projects, or only projects where Passport is disabled.
   
2. **Start the assignment flow:** Begin assigning Passport to the selected projects.
   
3. **Select the Connect application:** Choose the application to apply.
   
4. **Confirm the assignment:** Apply Passport to the selected projects.
   

## How to read a visitor's identity in your code

Read the visitor's identity with the `@vercel/passport` SDK rather than parsing the header or cookie yourself. The SDK verifies the token's signature and claims, and it handles session tokens that Vercel splits across multiple cookies.

Install the SDK:

**pnpm**

```bash
pnpm i @vercel/passport
```

**npm**

```bash
npm i @vercel/passport
```

**yarn**

```bash
yarn add @vercel/passport
```

**bun**

```bash
bun add @vercel/passport
```

Then call `getIdentity()` from server-side code. It returns the verified identity, or `null` when the request has no Passport session:

```typescript
import { getIdentity } from '@vercel/passport';

export async function GET(request: Request) {
  const identity = await getIdentity(request);

  if (!identity) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  // Return only the fields the client needs. Never return identity.token.
  return Response.json({
    subject: identity.subject,
    email: identity.email ?? null,
    name: identity.name ?? null,
  });
}
```

Keep these rules in mind when you use the identity:

- **Use** `sub` **as the visitor identifier:** The SDK exposes it as `identity.subject`. If your app accepts tokens from more than one Vercel team, store it together with the `iss` claim.
  
- **Don't use** `external_sub`**,** `email`**,** `name`**, or** `sid` **alone as an identifier:** The `external_sub` claim comes from your identity provider and is specific to the Connect application, so it isn't globally unique. Email and name can change or be absent.
  
- **Verify before you trust:** Decoding a JWT doesn't verify it. If you can't use the SDK, verify the signature, issuer, validity period, `typ`, project, and environment yourself.
  
- **Read identity on the server:** Pass only the fields you need to the browser, and never send the raw token to client-side code.
  

Profile fields such as `email` and `name` only appear when your identity provider returns them. Your app can also receive allowlisted claims such as `groups` by requesting the scope in your Connect application.

For complete, framework-specific walkthroughs, see [Identify users and control access in Next.js with Vercel Passport](https://vercel.com/kb/guide/vercel-passport-nextjs) and [Personalize and lock down a Nuxt app with Vercel Passport](https://vercel.com/kb/guide/vercel-passport-nuxt).

### How to develop locally with Passport

Your local development server never receives a real Passport session, because Passport only runs in Vercel's network. When there's no token, `getIdentity()` returns a development identity outside preview and production deployments, so the same code path works locally.

The development identity has no token and no `groups`. Customize it with `VERCEL_PASSPORT_DEV_*` environment variables, or set `VERCEL_PASSPORT_DEV=0` to make `getIdentity()` return `null`. To test the real sign-in flow and verified claims, use a Passport-protected preview deployment.

## How to let automation reach a Passport-protected deployment

Passport redirects any request without a session to your identity provider, including webhooks, Cron Jobs, and end-to-end tests. Automated requests need a [Protection Bypass for Automation](https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation) secret, sent with the original request as a header or query parameter.

Middleware in your app can't make a path public, because Passport has already made its sign-in decision before the request reaches your code.

## How to monitor Passport sign-ins

Each successful Passport authentication creates a `passport-access-granted` event in the Activity Log and Audit Logs. The event records the visitor, the protected hostname, and the project, so you can see who opened what and when.

## Troubleshooting

### Discovery can't find your OAuth metadata

Use the issuer URL of your authorization server, not only your identity provider's domain. For Okta's default custom authorization server, use:

```plaintext
https://your_okta_domain.okta.com/oauth2/default
```

If discovery still fails, enter the authorization endpoint, token endpoint, issuer, JWKS URI, and userinfo endpoint manually.

### Creating a Connect application returns Not Found

Confirm that your team is on an Enterprise plan with access to Passport, and that you're signed in as a team Owner.

### Visitors can't complete sign-in

Confirm these settings in your identity provider:

- The redirect URI is `https://connect.vercel.com/callback`.
  
- The visitor is assigned to the application.
  
- The application supports the `authorization_code` grant.
  
- The scopes include `openid`.
  
- The issuer, authorization endpoint, token endpoint, and JWKS URI all belong to the same authorization server.
  

### `getIdentity()` returns `null` on a deployment

Confirm that Passport is enabled for the project and that its protection scope covers the deployment you're testing. Requests sent with Protection Bypass for Automation have no identity unless they also carry a Passport session.

The SDK also checks the token's `project_id` and `environment` claims against the `VERCEL_PROJECT_ID` and `VERCEL_TARGET_ENV` (or `VERCEL_ENV`) System Environment Variables. If those variables aren't exposed to your functions, verification fails. Confirm that **Enable access to System Environment Variables** is checked in your project’s [environment variable settings.](https://vercel.com/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fsettings%2Fenvironment-variables%3Fenv%3Dsystem)

### The `groups`, `email`, or `name` claim is missing

These claims are optional. Confirm that your identity provider returns the claim, that the Connect application requests the scope and lists the claim under Forwarded ID Token Claims, and then start a new Passport session. Existing sessions keep the claims from when they were issued.

## Next steps

- Read visitor identity in more detail with [Read Passport identity in your application](https://vercel.com/docs/passport/read-identity).
  
- Review every claim in the [Passport token claims reference](https://vercel.com/docs/passport/token-claims).
  
- Add group membership with [Configure additional identity scopes](https://vercel.com/docs/passport/additional-identity-scopes).
  
- Pass identity between services with [forwarding identity](https://vercel.com/docs/passport/forward-identity) and [verifying forwarded tokens](https://vercel.com/docs/passport/verify-identity).
  
- Compare Passport with other [methods to protect deployments](https://vercel.com/docs/deployment-protection/methods-to-protect-deployments).
  

## Frequently asked questions

### What is Vercel Passport?

Vercel Passport is a Deployment Protection method that requires visitors to sign in with your own identity provider before they can view a protected deployment. It works with providers that support OAuth 2.0 or OpenID Connect, such as Okta, Microsoft Entra ID, and Auth0, and it's available on Enterprise plans.

### How much does Vercel Passport cost?

Vercel Passport is available on Enterprise plans. Contact your account team for pricing.

### Who can manage Vercel Passport?

Only team Owners can manage Passport, including enabling it for projects, setting a team default, and creating Connect applications.

### Which identity providers does Vercel Passport support?

Vercel Passport works with any identity provider that supports OAuth 2.0 or OpenID Connect, including Okta, Microsoft Entra ID, and Auth0. You connect a provider through a Connect application that stores its issuer, endpoints, client ID, and client secret.

### How do I read a visitor's identity after Passport authentication?

Install `@vercel/passport` and call `getIdentity()` from server-side code. It verifies the Passport token and returns the visitor's identity, including `subject`, which is the stable visitor identifier to store. Use `subject` (the `sub` claim) rather than `externalSubject` (the `external_sub` claim), which isn't globally unique.

### Why can't visitors sign in to a Passport-protected deployment?

Sign-in usually fails because of a mismatch in your identity provider's OAuth configuration. Confirm that the redirect URI is `https://connect.vercel.com/callback`, the visitor is assigned to the application, the application supports the `authorization_code` grant, the scopes include `openid`, and the issuer, authorization endpoint, token endpoint, and JWKS URI all belong to the same authorization server.