Penv Cloud
Start free
Docs
Reference

Vercel

Functions and builds authenticate as the project and environment they run in.

Functions and builds authenticate as the project and environment they run in.

Identity proof

The token has to come from https://oidc.vercel.com/acme, and its sub claim has to match the workload you named. We compare that claim byte for byte, with no wildcards.

Every token also has to name your workspace as its audience. Ask for this audience and no other. A token requested for two audiences fails every exchange.

Console fields

FieldExampleAdvancedWhat it pins
Team slugacmenoProject Settings → Security → Issuer Mode must be Team.
ProjectapinoUse the project name as Vercel lists it. A rename means a new trust.
EnvironmentproductionyesA development token carries the person who ran it. One of Production, Preview.

A field marked advanced carries a default and stays behind the disclosure until you open it.

The console also asks which project and environment this identity reaches and which role it gets, with the credential lifetime behind Advanced.

Trust

Built from the example answers above:

WhatValue
Issuerhttps://oidc.vercel.com/acme
Claim comparedsub
Subjectowner:acme:project:api:environment:production
Identity namevercel-api-production

We name the identity for you, so the form never asks for one.

Console snippet

// Runs in a build or a function's request handler, never at module scope.
// JavaScript only: a custom audience has no documented HTTP form.
import { getVercelOidcToken } from '@vercel/oidc';

export async function GET() {
  const T = await getVercelOidcToken({ audience: 'YOUR_WORKSPACE_ID' });
  const r = await fetch('https://penv.cloud/api/v1/auth/oidc', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ token: T }),
  });
  process.env.PENV_TOKEN = (await r.json()).credential;
}