Render Tutorials
Render CLI for power users

Authenticate and switch workspaces

⏱ 8 min

The CLI has two ways to authenticate, and the rules for which one wins are simple - once you’ve seen them. This step gets you logged in, gets a long-lived API key minted for CI, and shows you how to juggle multiple workspaces without accidentally deploying to prod.

The two auth modes

ModeUse it forWhere it’s storedLifetime
render login (CLI token)Local development on your laptop~/.render/cli.yamlPeriodic expiry, re-login when prompted
RENDER_API_KEY (env var)CI/CD, scripts, AI toolingThe environment of the processNever expires (rotate manually)

These coexist. The CLI picks one based on a precedence rule, which you’ll cover after you get both working.

Log in locally

Terminal
render login

The CLI opens your browser to a Render-hosted page, you confirm, and a token gets written to ~/.render/cli.yaml. The next command prompts you to pick a default workspace:

Terminal
$render workspace set
? Select a workspace > acme-prod acme-staging personal
$render workspace
Active workspace: acme-prod (tea-xxxxxxxxxxxxxxxx)

The selected workspace is saved to the same cli.yaml. Every subsequent command runs against it until you switch.

Mint an API key for scripting

For anything non-interactive - CI/CD, cron jobs, your runbook script - use an API key instead of a CLI token. Generate one from the Render Dashboard:

  1. Open Account Settings In the Render Dashboard, click your avatar → Account SettingsAPI Keys.
  2. Create a key Click Create API key, name it after where it’ll live (gh-actions-deploy, runbook-laptop, cron-backups).
  3. Copy the value once The key is shown once. Paste it somewhere safe (1Password, a CI secret) before you close the dialog.
  4. Scope it by workspace Each key belongs to a specific workspace. To deploy to a different workspace from CI, you’ll need a separate key.

Set it in your shell:

Terminal
export RENDER_API_KEY="rnd_xxxxxxxxxxxxxxxxxxxxxxxx"
render services

For CI, drop it into a repo secret (RENDER_API_KEY) and expose it as an env var on the job.

Precedence: API key wins

When both are set, the API key always takes precedence over the saved CLI token.

flowchart TD
  start["render <command>"]
  apikey{"RENDER_API_KEY set?"}
  useapi["Use API key (env)"]
  cfg{"~/.render/cli.yaml exists?"}
  usecfg["Use CLI token (login)"]
  prompt["Prompt: render login"]

  start --> apikey
  apikey -->|"yes"| useapi
  apikey -->|"no"| cfg
  cfg -->|"yes"| usecfg
  cfg -->|"no"| prompt

This matters more than it looks. The trap is when you have an API key exported in your shell for a script you wrote last month, and weeks later you wonder why render services shows different services than the Render Dashboard.

The fix is one of:

Terminal
unset RENDER_API_KEY
render services

or:

Terminal
env -u RENDER_API_KEY render services

The second form is non-destructive - it strips the variable just for that command, leaving your shell untouched.

Switch workspaces without thinking

Most teams have at least two: a production workspace and a staging or sandbox one. Two patterns keep them straight.

Pattern A: change the default

Terminal
render workspace set
render workspace

workspace set is interactive; it lists every workspace your token can see and stores your pick. Good for short sessions where you’re focused on one workspace.

Pattern B: per-command override with an env var

Terminal
RENDER_API_KEY=$STAGING_KEY render services
RENDER_API_KEY=$PROD_KEY render services

Because API keys are workspace-scoped, swapping the key swaps the workspace. This is the right pattern for scripts and aliases:

~/.zshrc
alias render-prod='RENDER_API_KEY=$RENDER_PROD_API_KEY render'
alias render-stg='RENDER_API_KEY=$RENDER_STAGING_API_KEY render'

Then render-prod services and render-stg services give you instant, unambiguous switches.

Inspect what you’ve got configured

When something doesn’t feel right, two commands give you the truth:

Terminal
$render workspace
Active workspace: acme-staging (tea-xxxxxxxxxxxxxxxx)
$render workspaces -o json | jq '.[] | {name, id}'
{ "name": "acme-prod", "id": "tea-yyyyyyyyyyyyyyyy" } { "name": "acme-staging", "id": "tea-xxxxxxxxxxxxxxxx" }

The first tells you what’s active right now. The second tells you what you could switch to. Together they’re enough to diagnose every “wait, why am I seeing this service?” moment.

Config file at a glance

~/.render/cli.yaml is just YAML. You can read it; you usually shouldn’t edit it.

~/.render/cli.yaml
token: rnd_cli_xxxxxxxxxxxxxxxxxxxx
workspace:
id: tea-xxxxxxxxxxxxxxxx
name: acme-staging
output: interactive
FieldSet byNotes
tokenrender loginShort-lived CLI token; replaced on every login
workspace.id / namerender workspace setThe active workspace
output--output flag or interactive pickerDefault output format; can be interactive, json, yaml, text

If you keep multiple Render accounts (personal vs work), point RENDER_CLI_CONFIG_PATH at a different file per account:

~/.zshrc
alias render-work='RENDER_CLI_CONFIG_PATH=$HOME/.render/work.yaml render'
alias render-personal='RENDER_CLI_CONFIG_PATH=$HOME/.render/personal.yaml render'

Each alias gets its own login state. No more “wait, I’m signed into the wrong account”.

Your CI workflow logs in with `RENDER_API_KEY`, but locally you also run `render login` and switched your default workspace to `staging`. You then run a CI job locally for debugging (with the prod API key exported in your shell). Which workspace does the job hit?

What you learned

  • `render login` for laptops; `RENDER_API_KEY` for everything non-interactive
  • API keys never expire and take precedence over the saved CLI token - useful for scripts, but a gotcha when you forget you exported one
  • Switch workspaces with `render workspace set` for sessions, or swap `RENDER_API_KEY` per-command for unambiguous scripted switches
  • `render workspace` and `render workspaces -o json` are your two diagnostic commands when something feels off
  • Multiple Render accounts? Point `RENDER_CLI_CONFIG_PATH` at a different config file per account and alias each one