Vercel OIDC Plugin for Traefik
A Traefik middleware plugin that validates Vercel OpenID Connect (OIDC) tokens for authenticating requests to your services.
This plugin integrates with Vercel's OIDC authentication system to protect your services hosted outside of Vercel and served behind Traefik. It validates JWT tokens issued by Vercel, ensuring that only authorized requests from your Vercel deployments can access your backend services.
Configuration
Traefik startup configuration
Also known as "install configuration"; formerly known as the "static configuration".
Include in your your Traefik's startup configuration (usually traefik.yaml) the following to load the plugin:
# traefik.yml
experimental:
plugins:
vercel-oidc-auth:
moduleName: github.com/vercel-labs/traefik-oidc-auth-plugin
version: v0.5.0Define the middleware
Once the plugin is defined, you can define middlewares of kind "vercel-oidc-auth" in the routing configuration (formerly known as dynamic configuration).
Using the YAML format for the routing configuration, this looks similar to:
http:
middlewares:
vercel-oidc-auth:
plugin:
vercel-oidc-auth:
# If using the global issuer, set this to "https://oidc.vercel.com"
issuer: "https://oidc.vercel.com/your-team"
teamSlug: "your-team"
projectName: "your-project"
environment: "production"
# Optional but recommended: custom audience expected in the token
# If unset, defaults to "https://vercel.com/your-team"
# audience: "https://your-service.example.com"
# Optional, defaults to "Authorization"
# tokenHeader: "Authorization"Docker Compose Example
version: '3.7'
services:
traefik:
image: traefik:v3.6
command:
- --api.insecure=true
- --providers.docker=true
- --entrypoints.web.address=:80
- --experimental.plugins.vercel-oidc-auth.modulename=github.com/vercel-labs/traefik-oidc-auth-plugin
- --experimental.plugins.vercel-oidc-auth.version=v0.5.0
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app:
image: your-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`your-domain.com`)"
- "traefik.http.routers.app.middlewares=vercel-oidc-auth"
- "traefik.http.middlewares.vercel-oidc-auth.plugin.vercel-oidc-auth.issuer=https://oidc.vercel.com/your-team"
- "traefik.http.middlewares.vercel-oidc-auth.plugin.vercel-oidc-auth.teamSlug=your-team"
- "traefik.http.middlewares.vercel-oidc-auth.plugin.vercel-oidc-auth.projectName=your-project"
- "traefik.http.middlewares.vercel-oidc-auth.plugin.vercel-oidc-auth.environment=production"Configuration Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
issuer | - | https://oidc.vercel.com/{teamSlug} | JWT issuer URL. Use https://oidc.vercel.com (or the alias global) for global, or https://oidc.vercel.com/{teamSlug} (or the alias team) for team-specific. Defaults to the team issuer |
teamSlug | ✓ | - | Your Vercel team slug |
projectName | ✓ | - | The name of your Vercel project. Supports the matching patterns below |
environment | ✓ | - | Environment name (e.g., "production", "preview"). Supports the matching patterns below |
audience | - | https://vercel.com/{teamSlug} | Custom audience expected in the token's aud claim. See Custom audiences |
tokenHeader | - | "Authorization" | HTTP header containing the JWT token |
jwksEndpoint | - | {issuer}/.well-known/jwks | JWKS endpoint URL for key retrieval |
Custom audiences
By default, Vercel OIDC tokens use a fixed audience of https://vercel.com/{teamSlug}, and this plugin validates against that value when audience is not set.
You can instead issue tokens with a custom audience scoped to a specific downstream service. Setting the audience parameter makes the plugin require that exact value in the token's aud claim.
Using a custom audience is recommended for security reasons: it prevents token replay attacks, since a token minted for one service cannot be replayed against another.
Project and Environment Matching
projectName and environment are exact matches by default, but they also support simple matching patterns:
| Pattern | Behavior | Example |
|---|---|---|
* | Matches any project or environment | environment: "*" |
foo* | Matches values that start with foo | projectName: "docs-*" |
foo|bar | Matches either foo or bar | environment: "production|preview" |
fo*|ba* | Combines alternatives with prefix matching | projectName: "web-|api-" |
These patterns only apply to projectName and environment. teamSlug must always match exactly.
Usage with Vercel
1. Configure OIDC in your Vercel project
In your Vercel project settings, OIDC is enabled with team-specific issuers by default.
You can refer to the official documentation for more information.
2. Make requests from Vercel Functions
You can obtain the OIDC token by invoking getVercelOidcToken from any Vercel Function.
The result is a string that can be used as header in fetch requests.
import { getVercelOidcToken } from '@vercel/functions/oidc'
// Get the OIDC token
const token = await getVercelOidcToken()
// Make the fetch request
const response = await fetch('https://example.com/api/data', {
headers: {
// Note the "Bearer" prefix is optional
'Authorization': 'Bearer '+token,
}
})