Skip to navigation

Vercel Workload Identity

Vercel can issue a short-lived OIDC token to builds and Functions. Mixlayer verifies the deployment’s team, project, and environment claims and exchanges the token for a short-lived Mixlayer access token, so you do not need to store a Mixlayer API key in Vercel.

1. Enable Vercel OIDC

In the Vercel dashboard, open the project and go to Settings > Security > Secure backend access with OIDC federation. Select the Team issuer mode, which scopes the issuer to your team.

Record the team slug from the Vercel team URL and the stable team and project IDs from the project settings. Use the IDs in Mixlayer policy because team and project names can change.

2. Configure the Mixlayer provider

Create an OIDC provider in Workload Identity:

SettingValue
Issuer URIhttps://oidc.vercel.com/[TEAM_SLUG]
Allowed audiencehttps://api.mixlayer.com
JWKS sourceOIDC discovery

Replace [TEAM_SLUG] with the slug from your Vercel team URL. The Vercel helper exchanges the deployment token for a Vercel-signed token with the Mixlayer-specific audience above.

Map stable identifiers and the deployment environment:

mixlayer.subject = assertion.sub
attribute.owner_id = assertion.owner_id
attribute.project_id = assertion.project_id
attribute.environment = assertion.environment

Admit only the expected team and project:

attribute.owner_id == "team_..." &&
attribute.project_id == "prj_..."

If only production deployments should authenticate, include the environment in the admission condition:

attribute.owner_id == "team_..." &&
attribute.project_id == "prj_..." &&
attribute.environment == "production"

Use true as the final authorization rule and grant only the permissions the deployment needs.

Do not authorize only by Vercel’s issuer and audience. Restrict admission with the stable team and project IDs.

3. Exchange a token from a Vercel Function

Store the non-secret Mixlayer provider ID in a Vercel environment variable named MIXLAYER_IDENTITY_PROVIDER_ID, then install Vercel’s OIDC helper:

pnpm add @vercel/oidc

Call getVercelOidcToken() inside the request handler. In a Function, the token is available only in the request context and cannot be read at module initialization.

file=app/api/mixlayer/route.ts
import { getVercelOidcToken } from "@vercel/oidc";
export async function POST() {
const identityProviderId = process.env.MIXLAYER_IDENTITY_PROVIDER_ID;
if (!identityProviderId) {
return new Response("Missing MIXLAYER_IDENTITY_PROVIDER_ID", { status: 500 });
}
const subjectToken = await getVercelOidcToken({
audience: "https://api.mixlayer.com",
});
const exchange = await fetch(
"https://api.mixlayer.com/v1/workload_identity/token",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
subject_token_type: "urn:ietf:params:oauth:token-type:jwt",
subject_token: subjectToken,
identity_provider_id: identityProviderId,
}),
},
);
if (!exchange.ok) {
return new Response(await exchange.text(), { status: exchange.status });
}
const { access_token: accessToken } = await exchange.json();
const inference = await fetch(
"https://mixlayer.ai/v1/chat/completions",
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "qwen/qwen3.5-4b-free",
messages: [{ role: "user", content: "Hello from Vercel" }],
}),
},
);
return new Response(inference.body, {
status: inference.status,
headers: { "Content-Type": "application/json" },
});
}

Vercel supplies the original OIDC token to the Function in the x-vercel-oidc-token request header. The helper reads it and requests the custom-audience token without requiring you to handle either step directly.

Builds and local development

During a Vercel build, the original token is available as VERCEL_OIDC_TOKEN. Use the same helper to request the custom-audience token, then follow the shared OIDC exchange example:

export MIXLAYER_SUBJECT_TOKEN="$(
node --input-type=module -e '
import { getVercelOidcToken } from "@vercel/oidc";
process.stdout.write(await getVercelOidcToken({
audience: "https://api.mixlayer.com",
}));
'
)"

For local development, vercel env pull writes a development OIDC token to .env.local. Development tokens identify the local user and last longer than preview or production tokens. Use a separate development provider or admission policy, and do not grant a downloaded development token production access.

Troubleshooting

  • Confirm the Vercel project uses the Team issuer mode and that the provider issuer includes the exact team slug.
  • Confirm the allowed audience is https://api.mixlayer.com and request the same audience from getVercelOidcToken().
  • Compare owner_id, project_id, and environment with the admission condition.
  • Call getVercelOidcToken() inside the Function handler, not at module scope.
  • If a team or project is renamed, the name-based iss and sub values change. Update the provider issuer after a team-slug change; continue using stable IDs for admission.
  • Do not log either the Vercel OIDC token or the Mixlayer access token.