A Vercel team holds two kinds of high-value machine credentials: the access tokens that control the platform, and the third-party secrets stored as environment variables that every deployment can read. A full-account token can deploy, change settings and read configuration across every team its owner belongs to, while environment variables routinely hold database URLs, payment keys and LLM API keys. Vercel now offers project-scoped tokens, write-only Secret variables and OIDC federation that removes many stored cloud credentials altogether. This guide explains how identity and access work on Vercel, how to scope and govern each credential type, what to log and a hardening baseline. It is written for platform engineers, application security teams and developers who run production workloads on Vercel.
Key takeaways
- Scope every access token to a project where you can. Vercel tokens can be Full Account, Team or Project scoped; a project-scoped token is denied any request outside its project and cannot mint new tokens.
- Store credentials as Secret, not Config. Secret environment variables are write-only after saving and redacted from build logs, while Config values stay readable to members with access.
- Replace stored cloud keys with OIDC federation. Vercel issues short-lived signed tokens per build and function that AWS, Google Cloud and Azure can exchange for temporary credentials, so no long-lived cloud key needs to sit in an environment variable.
- Bind trust to the subject claim. Cloud trust policies should match the
subclaimowner:[TEAM]:project:[PROJECT]:environment:production, not just the issuer, or any project in the team can assume production roles. - Several URLs and headers act as bearer secrets. Deploy hook URLs and Protection Bypass for Automation secrets grant deploy or access rights to whoever holds them and need the same handling as tokens.
How identity and access work in Vercel
Vercel separates human access (team members and their roles), programmatic access (access tokens and integration credentials) and workload identity (OIDC tokens issued to builds and functions). Each has its own controls.
| Credential | Issued to | Lifetime | Reach |
|---|---|---|---|
| Access token, Full Account scope | A user, from the Account Tokens page, CLI or API | Expiration chosen at creation | The personal account and every team the user belongs to; needed to create tokens through CLI or API |
| Access token, Team scope | A user, scoped to one team | Expiration chosen at creation | Read and write on all projects in that team |
| Access token, Project scope | A user, scoped to one project | Expiration chosen at creation | Only that project; user-level and team-level requests are denied |
| OIDC token (build) | Each build, as VERCEL_OIDC_TOKEN | One hour | Exchangeable with a cloud provider that trusts the Vercel issuer |
| OIDC token (function) | Each function request, in the x-vercel-oidc-token header | Two hours for preview and production, reused for up to 90 minutes | As above |
| OIDC token (development) | A developer, through vercel env pull | 12 hours | As above; carries a user_id claim |
| Deploy hook URL | A project and branch | Until revoked | Anyone with the URL can trigger a deployment |
| Protection bypass secret | A project | Until revoked or regenerated | Skips Password Protection, Vercel Authentication, Trusted IPs and bot challenges on all deployments in the project |
- Tokens act as their creator: access tokens authenticate requests to the REST API and CLI on the user's behalf, carry that user's role and are shown only once (personal access tokens begin with
vcp_). When the user leaves, their tokens become orphaned risk unless they are deleted. - Team enforcement applies to token creation: some teams require two-factor authentication or SAML before a member can create tokens scoped to them.
- Environment variables are encrypted at rest: they are set at team level (shared across linked projects) or project level, targeted to Production, Preview (optionally per Git branch), Development or custom environments, and apply only to new deployments.
Admin roles and privileged access
Team and project roles decide who can create tokens that act with their permissions, who can read and change production variables, and who can deploy to production.
| Role | Plan | Relevant powers |
|---|---|---|
| Owner | Pro, Enterprise | All team and project settings, role changes, security policies such as SAML enforcement and Separate Production Secret Values |
| Member | Pro, Enterprise | Deployments, integrations, deploy hooks, function settings and project security settings; cannot invite users or edit billing |
| Developer | Pro, Enterprise | Deploy and manage preview and development variables; cannot alter production environment variables; can reach production by merging to the production branch |
| Security | Enterprise | Firewall, rate limiting and Deployment Protection; read-only on projects; no deployments by default |
| Contributor with Project Administrator | Enterprise | All settings and all environment variables, including production, for assigned projects only |
| Contributor with Project Developer | Enterprise | Deployments and non-production variables for assigned projects |
| Viewers and Billing | Varies | Read-only project access; Project Viewer can examine environment variables across environments, so Secret type still matters |
- Permission groups widen roles: Environment Variable Manager, Full Production Deployment and Connector Manager can be added to lower roles. Review them as privileged grants.
- Keep Owners few but not one: Vercel recommends at least two Owners for continuity; more than a handful makes token and policy governance hard.
- Enforce SAML: Owners can switch on Require Team Members to login with SAML under Security & Privacy, so no team information is reachable without an identity provider session. SAML sessions last 24 hours by default, adjustable from one to 30 days with
session_lifetime. Directory Sync (Enterprise) automates joiner and leaver changes; without it, removals are manual.
See the SaaS API Token Security Guide for the general model of user-bound tokens.
Integrations, API tokens and service accounts
Access tokens for CI and automation
- Pick the narrowest scope: a CI job that deploys one project needs a project-scoped token. Team- and project-scoped tokens also remove the need for
teamIdon API calls, which reduces the chance of a script acting on the wrong team. - Always set an expiry: expiration is chosen at creation. Match it to a rotation cycle you will actually run, and record the owner and purpose in the token name. Package registry tokens used by the same builds need the same discipline; see the Artifactory Tokens Security Guide.
- Do not use personal tokens for shared pipelines: a token created by an engineer carries that engineer's role and dies, or lingers, with their account. Use a dedicated automation account with a minimal role, governed like any service account.
- Prefer Git integration over CLI tokens: deployments triggered by the Git integration need no token in CI at all. Where a pipeline must run
vercel deploy, store the token in the CI system's secret store. See the CI/CD Pipeline Identity Security Guide.
Environment variables
- Secret versus Config: choose Secret for passwords, API keys and tokens. Secret values are write-only after saving, cannot be converted back to Config in place, and can now be used in Development as well as Preview and Production. Legacy Sensitive variables are treated as Secret automatically.
- Build log redaction: Secret values of 32 characters or longer are replaced with
[REDACTED]in build logs, andVERCEL_AUTOMATION_BYPASS_SECRETandVERCEL_OIDC_TOKENare always redacted. Shorter secrets are not, so do not rely on redaction alone. - Separate production values: the Separate Production Secret Values team policy (Require Separate Values, Owner only) forces each Secret to use a different value in Production than in Preview, Development and custom environments. It replaces the deprecated Enforce Sensitive Environment Variables policy.
- Never prefix secrets with
NEXT_PUBLIC_: in Next.js that prefix inlines the value into the JavaScript bundle at build time, where every visitor can read it. See the React and Next.js Security Guide. - Integration-created variables: variables added by Marketplace integrations cannot be switched to Secret from the list. Vercel's documented route is to disconnect, rotate the provider secrets, reconnect without Development and with Sensitive enabled, then redeploy.
- Local copies:
vercel env pullwrites Development variables, including the development OIDC token, to a plain-text.envor.env.localfile. Keep these files in.gitignoreand keep production values out of the Development target.
OIDC federation to cloud providers
- How it works: Vercel signs a JWT for each build and function; the cloud provider validates it against Vercel's JWKS (discovered at
https://oidc.vercel.com/[TEAM_SLUG]/.well-known/openid-configurationin team mode) and returns short-lived credentials. For AWS this isAssumeRoleWithWebIdentity, helped by@vercel/oidc-aws-credentials-provider; for Azure and others,getVercelOidcToken()from@vercel/oidc. - Use the team issuer: Vercel recommends the Team issuer mode (
https://oidc.vercel.com/[TEAM_SLUG]) over the global issuer, so a trust relationship cannot be satisfied by another team's tokens. - Constrain on
subandaud: matchsubexactly to one project and environment, and the defaultaudofhttps://vercel.com/[TEAM_SLUG]or a custom audience. Grant production cloud roles only toenvironment:production, and give preview and development their own lower-privilege roles. Claims such asproject_idandowner_idare stable identifiers when the provider supports conditions on them. - Plan for renames: renaming a team or project changes the token claims and can break, or unexpectedly widen, trust policies. Update policies before the rename.
- Do not cache the token: Vercel's helpers read the current token on every call; caching it outside the request breaks rotation.
See the Workload Identity Federation Guide and the AWS IAM Policies and Roles Guide.
Choosing a credential pattern
| Need | Prefer | Avoid |
|---|---|---|
| Function reads from AWS S3, Google Cloud or Azure | OIDC federation with a role bound to the production subject | Static cloud access keys in environment variables |
| Function calls a SaaS API that only accepts API keys | Secret environment variable, separate production value, scheduled rotation | Config variables or NEXT_PUBLIC_ prefixes |
| CI deploys one project | Git integration, or a project-scoped token with expiry | A full-account personal token |
| Headless CMS triggers rebuilds | Deploy hook stored in the CMS secret settings | Hook URLs pasted into tickets or chat |
| E2E tests against protected previews | A named bypass secret per tool, sent as a header | Disabling Deployment Protection, or the query parameter form in logged URLs |
Logging and detection
The Activity Log (all plans) records team and project events and can be filtered with vercel activity. Enterprise Owners also get Audit Logs with CSV export and external storage through Vercel Drains.
| Event | Why it matters |
|---|---|
user-token-created, user-token-deleted, user-tokens-deleted | New tokens outside the automation account, or mass deletion during an incident |
env-variable-read and env-variable-read:cli:env:pull | Decryption of variable values, especially by users who do not normally pull production values |
env-variable-read:unknown-source | Decryption from an unexpected path; investigate every occurrence |
env-variable-add, env-variable-edit, env-variable-delete | Unapproved changes to production configuration |
env-variable-masked | A Secret appeared in build output; fix the code that printed it |
team-member-role-update, team-member-add, project-member-added | Privilege changes that also change what new tokens can do |
integration-scope-changed, saml-connection-deleted | Widened integration access or weakened sign-in |
On the cloud side, log the role assumptions made with Vercel OIDC tokens (for example AWS CloudTrail AssumeRoleWithWebIdentity events) and alert when a non-production subject assumes a production role.
Metrics that show it is working
- Token scope mix: share of active tokens that are project-scoped, and the number of full-account tokens used by automation, target zero.
- Token hygiene: tokens without expiry or without a named owner, target zero.
- Secret coverage: percentage of credential-bearing variables stored as Secret.
- Static cloud keys: number of AWS, Google Cloud or Azure keys stored in Vercel variables, falling as OIDC replaces them.
- Rotation time: hours from a rotation trigger to the old credential being invalidated across all redeployed projects.
Hardening baseline
- Inventory: export the list of tokens per member, team and project variables with their type and targets, deploy hooks, bypass secrets and integrations.
- Lock down sign-in: enforce SAML (or at least two-factor enforcement), so token creation also requires a strong session. Remove leavers and delete their tokens.
- Reissue tokens narrowly: replace full-account automation tokens with project-scoped tokens with expiry, owned by a dedicated automation identity. Revoke the old ones after the pipeline is proven.
- Convert credentials to Secret: recreate credential-bearing Config variables as Secret, enable Require Separate Values, and move production secrets out of the Development target.
- Adopt OIDC: set the Team issuer, create cloud trust policies bound to project and environment, deploy, verify, then delete the static cloud keys.
- Review bearer URLs: rename, re-create or revoke deploy hooks and bypass secrets, one bypass secret per tool, sent as the
x-vercel-protection-bypassheader. - Rotate in the safe order: generate the new credential at the provider, update the Vercel variable, redeploy every project linked to it (check Link to Projects for team-level variables), verify, then invalidate the old value. Old deployments keep old values, so redeploy any you still serve.
- Monitor: alert on the Activity Log events above and export them where your plan allows.
Small team or large estate
- Small teams: project-scoped tokens with expiry, Secret type for every credential, Git integration for deploys and two-factor enforcement deliver most of the benefit without Enterprise features.
- Enterprise: Contributor plus project roles to separate production variable access, SAML enforcement with Directory Sync, Audit Logs exported to the SIEM, and OIDC federation as the default for every cloud dependency.
Common misconfigurations
- Credentials stored as Config or legacy non-sensitive variables: in the Vercel Context.ai OAuth Breach 2026, an attacker who reached Vercel's internal environment through a compromised employee Google Workspace account decrypted customers' non-sensitive variables; Vercel said it had no evidence sensitive variables were accessed.
- Full-account tokens in CI: one leaked token reaches every team the creator belongs to and can mint more tokens.
- OIDC trust on issuer only: a trust policy that checks
audbut notsublets any project or preview deployment in the team assume a production role. - Secrets in
NEXT_PUBLIC_variables: shipped to every browser and cached in CDNs long after rotation. - Bypass secrets in query strings: the query parameter form is meant for tools that cannot set headers; elsewhere it leaks the secret into access logs and third-party webhook settings.
- Rotation without redeploy: the variable is updated but running deployments still use the old value, so the old credential is never safely invalidated.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | MITRE ATT&CK (threat addressed) |
|---|---|---|---|
| Token scope, expiry and rotation | IA-5 Authenticator Management | PR.AA-01 | T1528 Steal Application Access Token, T1550.001 Application Access Token |
| Roles and production variable access | AC-6 Least Privilege, AC-2 Account Management | PR.AA-05 | T1078.004 Cloud Accounts |
| Secret variables and local env files | SC-28 Protection of Information at Rest | PR.DS-01 | T1552.001 Credentials In Files |
| Third-party integrations | SA-9 External System Services | PR.AA-05 | T1528 |
| Activity and audit logs | AU-2 Event Logging, AU-6 Audit Record Review | PR.PS-04, DE.CM-03 | Detection for all of the above |
Practitioner checklist
- Replace every full-account token used by automation with a project-scoped token with expiry and a named owner.
- Enforce SAML or two-factor authentication for the team and delete tokens of departed members.
- Store every credential as a Secret variable and enable Require Separate Values for production.
- Check that no secret uses a
NEXT_PUBLIC_prefix and that.env*files are ignored by Git. - Move cloud access to OIDC federation with Team issuer mode and trust bound to
subper environment. - Treat deploy hook URLs and bypass secrets as credentials: inventory, store in secret stores, revoke when exposed.
- Rotate in the documented order and redeploy every linked project before invalidating the old value.
- Alert on token creation, production variable reads and changes, and role updates in the Activity Log.
Standards and references
- Vercel: Access tokens
- Vercel: Config and Secret environment variables
- Vercel: OpenID Connect (OIDC) Federation
- Vercel: OIDC Federation Reference
- Vercel: Access Roles
- Vercel: Rotating environment variables
- Vercel: Using the Activity Log
- Next.js: How to use environment variables in Next.js
Related NHI Mgmt Group resources: Secrets Management Guide · Workload Identity Federation Guide · CI/CD Pipeline Identity Security Guide · Token Lifetime Policy Design Guide · Firebase Credentials Security Guide