Skip to content

CLI authentication

Setup OAuth2 authentication for OpenQuok CLI.

6 min read

Connect your agent today

Draft from chat, review in your calendar, and publish only what you approve.

Start for $0

Overview

The OpenQuok CLI authenticates to the programmatic API in one of two ways. Both yield a Bearer token with the opo_ prefix:

  • OAuth2 device flow (recommended) — No client ID or secret in the CLI; a small CLI auth server holds the OAuth client secret and completes the flow.
  • Programmatic access token — set OPENQUOK_API_KEY to an opo_ token from the dashboard for scripts and CI.

If both are present, stored OAuth2 credentials take priority over OPENQUOK_API_KEY — run openquok auth:logout to clear them if you want the env var to be used.

OAuth2 (device flow)

Open the sign-in link on your phone or computer, sign in to OpenQuok if needed, choose a workspace, and tap Authorize. Credentials are stored for later commands (default ~/.openquok/credentials.json).

OAuth mobile login

Alternatively, it equals to run following in terminal:

Run:

openquok auth:login

Remote / SSH / CI use (no local browser launch)

OAuth2 device flow always needs a browser somewhere to complete authorization — it doesn’t have to be on the CLI’s machine. The CLI’s job is just to print the verification URL and poll until you authorize it.

Interactive auth:login always prints the verification URL and user code, then tries to open a browser on the CLI’s machine. If open() fails, the CLI re-prints the URL so you can open it manually.

For SSH, CI, or any flow where you don’t want the CLI to call open(), use auth:login --json: the first JSON object on stdout includes verification_uri and verification_uri_complete, and the CLI never launches a browser. Open the link in any browser (your laptop, phone, etc.) to complete authorization — the CLI keeps polling until you do.

For fully unattended auth with no browser at all, use a programmatic token instead — see Programmatic token below.

Machine-readable output (--json)

For scripts, CI, or automation, emit the full device payload and polling result as JSON:

openquok auth:login --json

This prints an initial JSON object (including device_code, user_code, verification_uri, verification_uri_complete, expires_in, and interval), then polls until completion and prints a second JSON object when credentials are stored—similar to the historical CLI behavior.

Other auth commands:

openquok auth:status
openquok auth:logout

Which auth server does the CLI use?

The CLI talks to the device-flow API at:

  • https://cli-auth.openquok.com (default OPENQUOK_AUTH_SERVER)

That origin serves POST /device/code and POST /device/token. The browser step uses a different URL returned in verification_uri:

  • Hosted OpenQuok: https://www.openquok.com/cli/device/verify

You can point the CLI API at your own deployed auth server (self-hosted OpenQuok or local development of agent/server):

  • Environment variable: set OPENQUOK_AUTH_SERVER to the server API origin (no trailing slash).
  • Per run: pass --authServer to openquok auth:login.
export OPENQUOK_AUTH_SERVER="https://auth.example.com"
openquok auth:login
openquok auth:login --authServer "https://auth.example.com"

For local auth server development, the default API URL is http://localhost:3111. With only the auth server running (no web proxy), the browser opens http://localhost:3111/device/verify. To test the production-style split locally, run the web dev server, set BROWSER_ORIGIN on the auth server, and set CLI_AUTH_SERVER_URL on web — see Development environment and Configuration - Agent.

Programmatic token

Rotate a workspace programmatic token from AccountSettingsDevelopersAccess. The plaintext opo_ value is shown once after Generate / Rotate token.

Set it for non-interactive use:

export OPENQUOK_API_KEY="opo_..."
export OPENQUOK_API_URL="https://api.openquok.com"

Add exports to your shell profile if you want them to persist.

You can also store a token once (storage behavior is described in agent/README.md):

openquok auth:login --apiKey "opo_your_programmatic_token"

Environment variables

These variables apply to the CLI process (your shell, CI job, or agent), not to the auth server deployment.

VariableRequiredDefaultDescription
OPENQUOK_API_KEYNo*Bearer opo_ programmatic token for the public API
OPENQUOK_API_URLNohttps://api.openquok.comAPI origin; requests use paths under /api/v1/
OPENQUOK_AUTH_SERVERNohttps://cli-auth.openquok.comAPI origin for device flow (/device/code, /device/token). Browser URLs come from the server’s verification_uri. Use http://localhost:3111 when running agent/server locally.

*Either OPENQUOK_API_KEY or successful openquok auth:login (stored credentials) is required for authenticated commands.

Switching between production and local / self-hosted

The CLI resolves two origins for every run:

  1. APIOPENQUOK_API_URL, then (if unset) apiUrl from ~/.openquok/credentials.json after device login, then the hosted default https://api.openquok.com.
  2. Device-flow APIOPENQUOK_AUTH_SERVER only; if unset, the default is https://cli-auth.openquok.com.

Use openquok config:show to print the resolved URLs, whether you match hosted OpenQuok (openquok_cloud) or a custom setup, and whether each value came from environment, credentials_file, or default.

Back to hosted OpenQuok (production defaults)

  1. In the current shell, clear overrides you set for local development:
    unset OPENQUOK_AUTH_SERVER
    unset OPENQUOK_API_URL
  2. If you added the same export lines to ~/.zshrc, ~/.bashrc, or similar, remove or comment them so new terminals also get defaults.
  3. Run openquok config:show — you should see the hosted API and auth origins and deployment: openquok_cloud.
  4. If you still use OAuth stored credentials from a local stack, run openquok auth:logout and openquok auth:login again without --authServer and without OPENQUOK_AUTH_SERVER set, so the token and stored apiUrl match production.

Point the CLI at local or self-hosted again

Set the same variables (and optionally pass --authServer on auth:login for a one-off):

export OPENQUOK_AUTH_SERVER="http://localhost:3111"
export OPENQUOK_API_URL="http://localhost:3000"
openquok auth:login

After device login, the CLI may persist apiUrl in credentials.json; OPENQUOK_API_URL still wins when set. Confirm with openquok config:show.

Self-hosting the auth server

You do not need to self-host the auth server to use the CLI with OpenQuok’s hosted stack — the defaults above are enough.

If you run your own OpenQuok deployment and want a dedicated device-flow service:

  1. Deploy agent/server and set SERVER_URL to your API host.
  2. Set BROWSER_ORIGIN to your web origin (or omit it to serve browser steps on the same host as the API).
  3. Deploy web with CLI_AUTH_SERVER_URL when using split hosts.
  4. Register the OAuth callback on your OAuth app — BROWSER_ORIGIN/cli/device/callback when split, or SERVER_URL/device/callback on a single host.
  5. Set OPENQUOK_AUTH_SERVER in the CLI to your API origin.

Clone the repository

The auth server lives at agent/server in the openquok-monorepo repository:

git clone https://github.com/Ratimon/openquok-monorepo.git
cd openquok-monorepo

Next, configure environment variables (DATABASE_URL, OPENQUOK_OAUTH_CLIENT_ID, OPENQUOK_OAUTH_CLIENT_SECRET, SERVER_URL, BROWSER_ORIGIN) and register the OAuth callback — see Configuration - Agent for the full reference.

Deployment

Deploy anywhere that runs Node.js and can reach a Postgres database — Vercel, Railway, Render, a VPS, or your own infrastructure.

All device-flow state lives in Postgres, so the process itself holds no state and scales horizontally. Put multiple replicas behind a load balancer when you need more throughput — see Scaling & Postgres.

For Vercel (the path with the most tooling in this monorepo), use two projects when mirroring OpenQuok production:

# Auth server API (agent/server)
pnpm vercel:env:sync:agent-server:prod
pnpm vercel:deploy:agent-server:prod

# Web browser routes (/cli/device/*)
pnpm vercel:env:sync:web:prod
pnpm vercel:deploy:web:prod

Or:

pnpm vercel:deploy:cli-device-flow:prod

More for Step-by-step Deployment Guides

Search documentation
Find a docs page
Discord Support