langwatch login --device and immediately get a working CLI experience —
no per-user setup, no IT tickets.
Time budget
The numbers below are hands-on time at the LangWatch admin console — not net of organisational approvals.
If your IT team is the bottleneck, you can start on the self-serve path today (skip §1 below) and add SSO later — the providers, routing policies, and budgets you set up keep working unchanged when SSO drops in.
Before you start: brand-new to LangWatch?
If this is your first LangWatch session — sign up at/auth/signup. The
post-signup flow routes you to /onboarding/welcome to create your
organization (name + ToS) and pick a flavor (Platform / Coding Agent /
MCP / Manual). Once that completes, you land at your first project, and
this guide picks up from there. The bootstrap creates: your
Organization, a Personal Team membership, an Owner RoleBinding on the
org, and your first Project — everything subsequent steps assume is
already in place.
If you already have a LangWatch account on the org you’re configuring,
skip to §1 below.
Prerequisites
- Organization owner or admin role at LangWatch.
- Workspace API keys for the providers you want to make available (one each from Anthropic, OpenAI, Gemini, Azure, Bedrock, Vertex — whatever your team needs).
- Your IdP’s SAML metadata or OIDC discovery URL (Okta, Azure AD, Google Workspace, Auth0).
On SaaS, governance rollout is managed per organization: if you don’t see the Govern menu, or AI-tools device login is refused with a governance error, contact your LangWatch account rep.You can reach
/governance with no project created yet: governance is org-scoped, not project-scoped.1. Connect SSO
In Settings → SSO, click Connect identity provider.- Okta (SAML)
- Azure AD (OIDC)
- Google Workspace (OIDC)
- In Okta admin, create a new SAML 2.0 application.
- Single sign-on URL:
https://app.langwatch.ai/api/auth/sso/{your-org-slug}/callback - Audience URI:
https://app.langwatch.ai - Map the NameID to email and add the standard claims
(
email,firstName,lastName). - Download the IdP metadata XML.
- Paste it into LangWatch’s Connect identity provider form.
- (Optional) Enable SCIM provisioning so users are auto-created the first time they sign in.
@yourdomain.com email is
auto-routed to your IdP at login. You can disable password
authentication entirely from this page if you want SSO-only.
2. Connect providers
In Settings → Model Providers, add an entry per upstream:- Click Add provider and pick from the list (Anthropic, OpenAI, Azure OpenAI, Bedrock, Vertex, Gemini, custom OpenAI-compatible).
- Paste the workspace API key (or AWS / GCP credentials).
- Set the scope:
Organization(everyone),Team(only members of one team), orProject(only one project).
Organization so the credential
is available everywhere. You can tighten later by creating
team-scoped overrides.
The provider entries here are the same ones the AI Gateway
already uses for service virtual keys. Personal keys reuse them — no
parallel pool.
3. Define routing policies
Open AI Gateway → Routing Policies and click New policy. A policy is the answer to “when one of my users wants to call a model, what providers can serve it, in what order?” — see the full reference at Routing policies. Two policies to create on day one:1
developer-default
- Scope: Organization
- Strategy:
priority - Providers (in order): Anthropic, OpenAI, Gemini
- Allowed models:
claude-3-5-*,claude-3-opus-*,gpt-4o*,gpt-5*,o1-*,o3-*,o4-*,gemini-2.5-* - Mark as default for ORG scope
2
evaluator-default
- Scope: Organization
- Strategy:
cost - Providers: OpenAI, Gemini, Anthropic
- Allowed models:
gpt-4o-mini,gpt-5-mini,gemini-2.5-flash,claude-3-5-haiku-* - Mark as default for the evaluator system VK (your LangWatch-internal evaluators will use this, keeping eval costs predictable).
TEAM-scoped policy with isDefault=true
overrides the ORG-scoped default for members of that team.
Smoke-test before you publish the portal: the org-default routing
policy MUST have at least one provider in its chain before personal
keys can serve traffic. If you publish
/me to teammates with an
empty developer-default policy, every issued VK provisions
successfully but the first call returns 504 provider_timeout (the
gateway has nothing to forward to). After §2 (Connect providers) +
this section, mint a test key against your own user, fire one
completion, and confirm a 200 before announcing the portal.4. Set per-user budgets
In AI Gateway → Budgets:- Click New budget and pick scope
User (default). - Set the monthly cap (e.g.
$500/mo). - Click save.
langwatch login inherits this
budget. To exempt a power user, override at scope User with a
specific user ID and a higher limit.
You can also set:
- Team budgets — cap an entire team’s total spend.
- Project budgets — cap a production agent’s spend.
- Org budgets — a hard ceiling for the whole organization.
5. Roll out to your team
Send your team this snippet:langwatch login, the
backend auto-provisions their personal team + project, mints a
personal VK against the developer-default routing policy, and
returns it in the same round-trip. They have a working CLI in
under a minute.
What you’ll see as users come online
In AI Gateway → Activity:- Per-user request counts and spend, in real time.
- A By tool breakdown (Claude Code vs Codex vs Cursor).
- A By model breakdown.
- The full audit trail of
vk-lw-…issuance,langwatch loginevents, budget violations, and policy denials.
- A list of every user with their personal team auto-created.
- Per-user budget ceiling and current spend.
- A Revoke all credentials button per user — useful for off-boarding.
Off-boarding flow
When someone leaves:- Disable them in your IdP (this is what your IT process already does).
- The next time the LangWatch SCIM sync runs (or when their access token expires, ~1h), their credentials are dead.
- (Optional, for immediate revocation) In Settings → Members, click Revoke all credentials for the user. This invalidates their refresh token and any active access tokens within 60s.
CLI device-flow REST API (for custom clients)
Thelangwatch CLI uses a standard
RFC 8628 device-code flow
against the control plane. Self-hosters who need to integrate
custom CLI clients, or audit the wire surface, can hit these
endpoints directly. The format is snake_case JSON (matches
RFC 8628 + every other OAuth library). Origin enforcement applies
to all endpoints — pass Origin: <your-base-url> from any client
outside a browser.
The browser approval surface is
https://<your-base-url>/cli/auth?user_code=XXXX-YYYY (the
verification_uri_complete field). Unauthenticated visitors are
bounced through SSO and return to the page automatically.
Verified behavior
The reference server passes all of:- Each
device-codemint returns a uniqueuser_codeanddevice_code user_codeis 8 chars, base32 alphabet (no I/O/0/1/L/U), dashedXXXX-YYYYverification_uriends with/cli/authexpires_indefaults to 600s (configurable),intervaldefaults to 5s- Polling
/exchangefaster than the per-device rate-limit (4s) returns429 slow_down - Polling with an unknown / TTL-expired
device_codereturns408 expired_token /refreshwith an unknown / expired token returns401 invalid_grant- All browser-side endpoints (
/lookup,/approve,/deny) require an active session cookie; unauthenticated requests get401 unauthorizedwith a body the CLI surfaces verbatim /logoutis idempotent — passing an unknown / already-revoked refresh token still returns200 { ok: true }
Try it locally (dogfood loop)
Want to see real spend land in/me/usage and the governance
dashboard before rolling out to your team? The repo ships dogfood
helpers that mint a personal virtual key and fire a real completion
through your local Go gateway.
seed-personas.ts helper covers persona 1 (admin), persona 3
(LLMOps majority — no chrome change), and persona 4 (admin who also
uses the CLI). Add --mint-vk to the latter two to get a usable
personal VK.
Budget caveat for
/me/usage: spend is computed from the
gateway_budget_ledger_events fold, which only writes ledger rows
when a Budget applies to the request. A fresh --mint-vk seed
produces a working personal VK but no Budget binding by default,
so /me/usage shows $0.00 even though real spans landed in the
trace store.This matches production behavior — admins attach budgets in step 4
above, and /me/usage spend appears once a Budget is bound to the
user (or to the personal VK directly). To prove real spend in a
dogfood run today, attach a $0-limit tracking budget to the
seeded user (or to the personal team) before firing completions.Product follow-up: separating the usage-display query from the
Budget-limit machinery (so /me/usage aggregates spans directly
scoped by principal_user_id regardless of Budget binding) is on
the post-merge follow-up list. Until then, /me/usage is
Budget-gated by design.What’s next
- Routing policies for the full policy DSL (priority/cost/latency/round_robin strategies, model allowlists, cascading defaults).
langwatchCLI — the unified CLI lives in the TypeScript SDK; the new device-flow login wraps every coding CLI through your governance plane.