How does Vercel auth work and token storage?
How does auth work? Does vercel store a vercel token in my machine?
Yes — the Vercel CLI can store auth credentials on your machine, but the exact behavior depends on how you authenticate.
###How CLI auth works
The CLI uses this priority order:
--token <TOKEN>flagVERCEL_TOKENenvironment variable- Persisted local credentials
- If none exist and the command needs auth, it starts
vercel login
This is implemented in packages/cli/src/index.ts: it checks --token, then process.env.VERCEL_TOKEN, before reading stored credentials.
If you run vercel login, the CLI uses an OAuth device-code flow:
- It asks Vercel for a device code.
- Prints/opens a browser URL.
- Polls Vercel until you approve the login.
- Receives an
access_token,expires_in, and possibly arefresh_token. - Saves those into the CLI auth config.
See packages/cli/src/commands/login/future.ts.
###Does it store a Vercel token locally?
Yes, when you use vercel login.
After login, the CLI persists:
{
token: tokens.access_token,
expiresAt: ...,
refreshToken: tokens.refresh_token,
}
Source: packages/cli/src/commands/login/future.ts.
The auth config type includes:
token?: string;
refreshToken?: string;
expiresAt?: number;
userId?: string;
Source: packages/cli-config/src/types.ts.
###Where is it stored?
By default, the repo says credential storage defaults to file:
export const DEFAULT_CRED_STORAGE = 'file';
Source: packages/cli-config/src/types.ts.
The file is named:
auth.json
inside the Vercel global config directory:
getAuthConfigFilePath(configDir) {
return path.join(configDir, 'auth.json');
}
Source: packages/cli-config/src/cli-config.ts.
The global config directory comes from xdg-app-paths('com.vercel.cli'), with legacy fallback to ~/.now.
So practically, it’s usually somewhere like:
- macOS: app data directory for
com.vercel.cli - Linux: XDG data dir for
com.vercel.cli - Windows: AppData-style directory
- legacy:
~/.now/auth.json
You can also override the global config dir with:
vercel --global-config /some/path ...
###Can it use the OS keychain instead?
Yes. The credentials store supports:
'auto' | 'file' | 'keyring'
Source: packages/cli-config/src/types.ts.
The keyring service name is:
com.vercel.vercel-cli
Source: packages/cli-auth/credentials-store.ts.
Storage can be controlled via global config credStorage or the VERCEL_TOKEN_STORAGE env var. In auto mode, it tries keyring and falls back to auth.json.
###What about VERCEL_TOKEN or --token?
Those are not persisted.
When the CLI sees an explicit token, it sets:
client.authConfig = { token, skipWrite: true, tokenSource }
Source: packages/cli/src/index.ts.
So if you run:
VERCEL_TOKEN=... vercel deploy
or:
vercel deploy --token ...
the CLI uses that token for the current command and skips writing it to local auth storage.
###How API requests are authenticated
Before requests, the CLI calls ensureAuthorized():
- If the access token is still valid, it uses it.
- If expired and there is a refresh token, it refreshes the access token.
- If refresh fails, it clears stored auth and requires login again.
Then requests include:
Authorization: Bearer <token>
Source: packages/cli/src/util/client.ts.
###Short answer
vercel login: yes, stores credentials locally — access token, refresh token, expiry, etc.VERCEL_TOKEN=...: no, not stored by the CLI.--token ...: no, not stored by the CLI.- Storage is usually
auth.json, unless configured to use the OS keyring.
END OF POST