Skip to content
dot
Esc
↑↓navigate↵open⌘Jpreview
On this page

Vercel

Connect the Vercel CLI to a token in 1Password, deploy without linking, and give a project a short-lived OIDC token.

vercel, the Vercel CLI, needs a login to reach your projects: deployments, their logs, environment variables and domains.

This guide uses the token in 1Password way. The interactive alternative is at the end, for comparison.

Requirements

1Password with Integrate with 1Password CLI turned on (1Password and GitHub, step 1).

1. Install the CLI

dot apply packages    # installs what's missing: here, vercel

This installs vercel and op, from config/packages.conf; what’s already installed stays as it is. The next steps need both: op plugin init vercel only works once vercel exists.

2. Create a token (once, ever)

Open https://vercel.com/account/settings/tokens and create one:

  • Token name: vercel CLI (1Password)
  • Scope: the team your projects live in. A token reaches only its scope, so if your projects are spread across teams, choose your full account.
  • Expiration: your choice. A date means rotating the token when it expires (see Renewing).

Copy the token at the end: it’s shown only once, and the next step stores it.

3. Connect it to vercel (once per Mac)

op plugin init vercel

It asks three things:

  1. Credential: choose Import into 1Password, paste the token, and save it in your built-in personal vault (Personal, or Private on business accounts). On a later Mac, choose the item that already exists instead.
  2. Scope: choose Use as global default on my system, so vercel uses this token everywhere. It’s the third option: the list starts on Prompt me for each new terminal session, so move down before pressing Enter.
  3. It finishes by printing a command that adds a line to ~/.zshrc. Skip it: config/shell/op.zsh already loads the plugins (Shell and terminal). Open a new terminal instead, so the plugin is active.

If you choose another scope, 1Password saves the token but vercel doesn’t use it outside that scope, and vercel whoami answers “Logged out”. Run op plugin init vercel again, pick the existing item, and choose the global default.

Then add the dotfiles tag to the item it created, “Vercel API Token”, keeping the tag op added:

op item edit "Vercel API Token" --tags "1Password Shell Plugins,dotfiles"

4. Check it

vercel whoami

It asks for Touch ID, then prints your Vercel username. The plugin passes the token with --token for that single command; nothing is written to disk. dot auth status checks it too.

If the CLI offers to upgrade itself, answer no: Homebrew installed it, so brew upgrade vercel updates it once the formula has the new version.

Linking a project folder

vercel link --yes --project <name> --scope <team>

Deploying from a folder needs it linked once; the link lives in .vercel/. Linking also writes a short-lived VERCEL_OIDC_TOKEN into .env.local, in plain text, and has no option to skip it. If the project doesn’t use Vercel’s OIDC federation, delete that .env.local: deploying doesn’t need it.

To deploy without linking, name the project instead; nothing is written to the folder:

vercel deploy --project <name> --scope <team>           # a preview
vercel deploy --project <name> --scope <team> --prod    # production

A project’s OIDC token

Code that uses Vercel’s OIDC federation (Vercel Blob, for example) gets its token from Vercel when it runs there. On this Mac, a project’s code needs a development token, valid 12 hours:

vercel project token <name> --scope <team> --json

It prints {"token": "…"} and saves nothing. In a project that uses Varlock, .env.schema issues one on each run:

# @sensitive
VERCEL_OIDC_TOKEN=exec(`op plugin run -- vercel project token <name> --scope <team> --json | jq -r .token`)
  • op plugin run -- vercel, not vercel: the plugin’s vercel function only exists in interactive zsh, and Varlock runs the command in another shell. Without the plugin, vercel has no token and starts a login of its own.
  • The token is for the development environment: whatever it reaches (a Blob store, for example) must be connected to the project for Development too, or the request is denied.
  • Not vercel env pull: it writes the token into .env.local, and when the token expires the SDKs renew it with a saved CLI login, which this setup doesn’t keep.

Known limits of the plugin

The plugin adds --token to every vercel command, but not every command honors it:

  • vercel curl hands its flags to curl, which rejects --token. Request a deployment with plain curl instead; one behind Vercel’s protection needs a bypass token for that.
  • vercel env run authenticates on its own: finding no saved login, it starts a device login, and approving it saves a long-lived login token in the CLI’s config folder (auth.json), which this setup avoids. Don’t use it; if it already happened, vercel logout, called by the binary’s path (/opt/homebrew/bin/vercel logout) so the plugin’s token isn’t the one revoked, removes the file and revokes that login.

Friction

Criterion Token in 1Password Interactive login
Time a few minutes to create the token; per Mac: under a minute (op plugin init took 36 s) not measured
Browser once, to create the token on every Mac
2FA once, when creating the token, if asked on every Mac, if asked
Per machine op plugin init vercel (the shell line comes from dot apply shell) the whole login
Expires as set when creating the token when Vercel ends the session
Secret on disk no yes, in the CLI’s config folder

The token is created once; each later Mac repeats steps 1, 3 and 4.

Renewing

If the token has an expiration date, Vercel emails you before it expires. Create a new one, then replace the value in the 1Password item. Every Mac picks up the new value on its next vercel command.

Alternative: interactive login

vercel login

It opens the browser to authorize this Mac, then stores a token in the CLI’s config folder, in plain text. It has to be repeated on every Mac.

Was this page helpful?