Skip to content
Docs

Verify forwarded Passport tokens

When a Passport-protected app forwards a token to another backend, the receiving backend must verify it before trusting its claims. The verifyIdentity() helper verifies the Passport JWT signature, validates its Passport-specific claims, and checks that it came from the expected source project and environment.

Install @vercel/passport in the receiving service:

pnpm add @vercel/passport

verifyIdentity() is available in @vercel/passport version 0.1.3 and later.

Pass the owner ID, project ID, and environment from the Passport-protected deployment that minted the token. verifyIdentity() reads the bearer token directly from the request and always verifies it:

app/api/do-stuff/route.js
import { verifyIdentity } from '@vercel/passport';
 
const ownerId = 'team_your_team_id_here';
const projectId = 'prj_your_project_id_here';
const environment = 'production';
 
export async function POST(request) {
  try {
    const identity = await verifyIdentity(request, {
      ownerId,
      projectId,
      environment,
    });
 
    return Response.json({
      issuer: identity.payload.iss,
      subject: identity.subject,
      externalSubject: identity.externalSubject,
      email: identity.email,
    });
  } catch {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }
}

If the receiving backend runs in another Vercel project, keep validating the issuer and audience of the source Passport-protected deployment. Do not derive them from the receiving project.

For non-JavaScript services, verify the Passport token as a signed JWT. The service should check:

  • The signature with the Passport issuer's JSON Web Key Set (JWKS).
  • The iss claim, such as https://passport.vercel.com/your_team_slug_here.
  • The aud claim for the expected owner, project, and environment.
  • The exp and nbf claims.
  • The typ claim equals passport.
  • The iss and sub claims together identify the Passport visitor.
  • The project_id, environment, and optional owner_id claims.

Passport exposes OpenID Connect discovery at https://passport.vercel.com/your_team_slug_here/.well-known/openid-configuration. Its jwks_uri is https://passport.vercel.com/.well-known/jwks.json.

See the Passport token claims reference for the complete schema and guidance on choosing a visitor identifier.

Confirm that the source application sends the Passport token unchanged in Authorization: Bearer <token>, then pass the receiving request to verifyIdentity(). Do not forward the decoded payload or the Passport session cookie value in another format.

Pass the owner ID, project ID, and environment of the Passport-protected source deployment that minted the token. A receiving backend in another project must not substitute its own project ID or environment.

Confirm that verifyIdentity() receives the complete token and that the server can reach the Passport JWKS. Also confirm that the server clock is accurate so exp and nbf checks are reliable. Treat every verification failure as an unauthenticated request, and do not log the raw token.

Profile and additional claims are optional. Base the authorization decision on required, validated claims and deny access when a required claim is absent or has an unexpected type. See Configure additional identity scopes.

Last updated July 20, 2026

Was this helpful?

supported.