Skip to main content
The SSO device flow lets an employee at a Google Workspace or Okta org run a CLI command, approve it in their browser via a real IdP sign-in, and receive a short-lived sk-proxy-… key scoped to their identity. It’s a full RFC 8628 OAuth 2.0 Device Authorization Grant implementation — no admin has to manually mint or share credentials.

When to use it

Use SSO device-flow keys for:
  • Interactive CLI tools — anywhere a developer runs a local command that needs a RouteShift key.
  • Notebooks and one-off scripts — short-lived credentials that auto-expire.
  • Onboarding — new hires get a working key the moment they can sign in to your IdP, with no admin ticket.
Stick with regular virtual keys for:
  • Production services and CI — long-lived, machine-owned credentials with per-key budgets and model allowlists.
  • Shared agents — keys that outlive any one employee.

How the flow works

1

Employee runs the CLI

Their local tool calls POST /oauth/device/code with the employee’s email. RouteShift looks up the team by email domain (home-realm discovery) and returns a device_code, an 8-character user_code, and a verification_uri.
2

Employee approves in the browser

The CLI prints the code and opens https://proxy.routeshift.io/oauth/device/verify. The employee signs in to Google Workspace or Okta, sees the code they were shown, and clicks Approve.
3

RouteShift verifies the identity

The IdP redirects back to /oauth/device/callback with an authorization code. RouteShift exchanges it for an ID token, validates the issuer, audience, nonce, and email domain, then marks the authorization approved.
4

CLI receives a key

The CLI has been polling POST /oauth/device/token with the device_code. Once approved, it receives a fresh sk-proxy-… token valid for 8 hours.
Keys minted this way are stamped with metadata.issued_via = "sso_device_flow" and metadata.email = "<verified-email>". Only one live SSO key is allowed per (team, email) pair — a second flow for the same identity replaces the previous key.

Key properties

The 8-hour TTL is a deliberate defense against leaked keys — even if the token ends up in a repo or a chat log, its blast radius closes overnight.

Configuring an IdP connection

Every team that wants SSO device flow needs one idp_config row per login domain. Provision it via the admin API:
Requirements:
  • providergoogle_workspace or okta.
  • login_domain — the email domain employees sign in with (e.g. acme.com). A domain belongs to exactly one team; conflicts return 409.
  • issuer — the OIDC issuer URL. RouteShift fetches its discovery document at create time to validate reachability and the JWKS endpoint. Do not include a trailing slash — the issuer is compared byte-for-byte against the iss claim during token verification.
  • client_id / client_secret — the OAuth app you registered in the IdP console. The secret is encrypted at rest with PROVIDER_KEY_SECRET.
  • Redirect URI — register ${SSO_CALLBACK_BASE_URL}/oauth/device/callback in the IdP app console. This must match the environment variable exactly.
The IdP-side redirect URI must exactly match SSO_CALLBACK_BASE_URL configured on the proxy. A mismatch causes the browser leg to fail with an opaque IdP error before RouteShift ever sees the callback.

CLI example

A minimal client that walks the flow:
The device-code endpoint returns:
The token endpoint returns standard RFC 8628 errors:

Rollout gate

The device flow is disabled by default. To enable it on a deployment:
  1. Set SSO_DEVICE_FLOW_ENABLED=true on apps/proxy.
  2. Set SSO_CALLBACK_BASE_URL to the public HTTPS origin of the proxy (must match the redirect URI you register in each IdP).
  3. Provision at least one idp_config via the admin API.
SSO_DEVICE_FLOW_ENABLED is a per-team onboarding gate, not a global kill switch. Once a team has an idp_configs row, flipping the flag off does not stop that team’s employees from logging in. To disable a specific team, delete their idp_configs row via DELETE /admin/idp-configs/{id}?team_id=….

Audit

Every SSO-issued key writes an sso_issued event to api_key_audit_events with the verified email, IdP config ID, and issuance timestamp. Filter for these in the audit log to see which employees are actively using the flow. Revocation, rotation, and expiry follow the same key lifecycle as any other virtual key.