Overview
Rhombus supports OAuth 2.0 with PKCE so you can build applications that sign users in with their existing Rhombus credentials. When a user clicks Sign in with Rhombus in your app, they’re redirected to the Rhombus Console to authenticate, then bounced back to your redirect URI with a short-lived authorization code. You exchange that code for an access token and call the Rhombus API on the user’s behalf. This is the same flow used by the official Rhombus CLI —rhombus login is a working reference implementation in Go that you can read end to end.
Use this guide to build:
- CLI tools that authenticate via browser login (like the Rhombus CLI itself)
- Web applications that let Rhombus users sign in to your service
- Admin dashboards and internal integrations for customers that manage many Rhombus orgs
- Desktop applications using a local-loopback redirect
What this guide isn’t. This is for third-party developers building apps that sign in Rhombus users. If you’re a Rhombus customer trying to configure SAML SSO for your employees (Okta, Azure AD, Google Workspace) or SCIM for user provisioning, see SAML SSO & SCIM Provisioning instead — that’s a separate surface from the OAuth flow described here.
How the flow works
The Rhombus OAuth surface spans three hosts. This is a common source of confusion — your app talks to all three at different stages of the flow.| Host | Role |
|---|---|
console.rhombussystems.com | Where the user signs in and approves your app |
auth.rhombussystems.com | Token exchange endpoint |
api2.rhombussystems.com | API calls made with the resulting access token |
Before you begin
Before you start, make sure you have:
- A Rhombus account with an API key (generated in the Rhombus Console under Settings → API Management)
- A redirect URI your app controls — a public HTTPS URL in production, or
http://localhost:<port>/callbackfor CLI and desktop apps - Basic familiarity with OAuth 2.0 Authorization Code flow and PKCE (RFC 7636)
Step 1: Register your application
Before you can start an OAuth flow, Rhombus needs to know about your application. Registration gives you aclientId and clientSecret pair.
There are two paths to a clientId, depending on where you are in your build:
Prototyping & development
Call the
submitApplication API directly with your existing API key. Fastest path to a working flow on localhost. Self-serve, immediate.Production & distribution
Apps that will be shipped to customers or accept logins from users outside your own organization must be reviewed by Rhombus. Contact your Rhombus representative or post in the Developer Community to start review.
Register with the API
POST /api/oauth/submitApplication returns a fresh clientId and clientSecret. Store the clientSecret securely — it is not retrievable later.
Step 2: Build the authorization URL
Rhombus uses PKCE (Proof Key for Code Exchange) to protect against authorization code interception. For every login attempt, generate:- A code verifier — a 43–128 character URL-safe random string
- A code challenge — the SHA-256 hash of the verifier, base64url-encoded (without padding)
- A state parameter — an unguessable random value used to prevent CSRF
codeVerifier and state alongside the user’s session (or, for CLI tools, in process memory) until the callback lands. You’ll need both.
Step 3: Handle the redirect callback
After the user authenticates, Rhombus redirects to yourredirectUri with query parameters:
| Parameter | Description |
|---|---|
code | Authorization code to exchange for an access token. Short-lived. |
state | The state value you sent — you must verify it matches. |
isPartner | "true" if the authenticated user is a partner account holder. See partner accounts. |
accessToken | (sometimes present) A pre-exchanged access token. If set, skip the token exchange step and use it directly. |
error | Present on failure (e.g., access_denied). |
error_description | Human-readable error detail. |
Step 4: Exchange the code for an access token
CallPOST https://auth.rhombussystems.com/oauth/token with the authorization code and your PKCE verifier. This is a different host from the main API — the /oauth/token endpoint lives on auth.rhombussystems.com.
Step 5: Call the Rhombus API
Use the access token with two headers on every Rhombus API call:x-auth-scheme: api-oauth-tokenx-auth-access-token: <accessToken>
api-token + x-auth-apikey) — OAuth access tokens use their own scheme identifier so Rhombus can apply OAuth-specific authorization.
If this call returns a list of users, your OAuth flow is working end to end. The user has authenticated, you have an access token, and you’re calling the API on their behalf.
Access token lifetime
TheaccessTokenExpirationSec field on the token response tells you how long the access token is valid (typically one hour). When it expires, the Rhombus API will return an authentication error.
For long-lived access — background services, daemons, scheduled jobs, or any client that cannot re-prompt the user — mint a durable API key using the OAuth access token (see next section) rather than trying to maintain a refreshed OAuth session. This is the pattern the Rhombus CLI uses.
A
refreshToken is returned alongside the access token. The refresh flow is not currently part of the publicly supported surface — for persistent access, prefer the API key path below.Mint a long-lived API key
Once a user has signed in with OAuth, you can trade the short-lived access token for a permanent API key. This is whatrhombus login does so the CLI can continue making API calls after the browser session ends.
Call POST /api/integrations/org/submitApiTokenApplication with x-auth-scheme: api-oauth-token and x-auth-access-token: <accessToken>:
x-auth-scheme: api-token + x-auth-apikey headers — no further OAuth calls required. The CLI also supports a certificate-based (mTLS) variant of this flow for higher-security deployments; see cmd/login.go for the full implementation.
Working with partner accounts
If the authenticating user is a partner account holder (an MSP or reseller managing multiple customer organizations), the callback includesisPartner=true.
When isPartner is true:
- Use
x-auth-scheme: partner-api-oauth-tokeninstead ofapi-oauth-tokenon API calls - Mint long-lived keys via
POST /api/partner/submitApiTokenApplicationinstead of the standard integrations endpoint - To act on a specific client org, include the client org UUID in the appropriate request field (refer to Partner endpoints in the API Reference)
Partner accounts are relatively rare for third-party apps. If your app targets end customers with standard Rhombus orgs, you can safely treat
isPartner=false as the default path and show a clear error if a partner account tries to log in when you don’t support it.Reference implementation
The Rhombus CLI is a production reference for everything in this guide.cmd/login.go walks the full flow end to end: PKCE generation, local callback server, authorization URL construction, token exchange, partner branching, mTLS API-key minting, and credential persistence.
If something in your implementation isn’t working, diff your behavior against the CLI — it’s the canonical example.
Troubleshooting
state mismatch on callback
state mismatch on callback
Your callback received a
state value different from what you sent. Verify you’re persisting the state you generated in Step 2 alongside the user’s session (or in memory for CLI tools) and comparing it on the callback. A persistent mismatch can indicate a CSRF attempt — abort the flow rather than retrying silently.Token exchange returns HTTP 400 or `error: true`
Token exchange returns HTTP 400 or `error: true`
Common causes:
redirectUrimismatch — theredirectUriin the token exchange body must match exactly (including scheme, host, port, and path) theredirectyou sent in Step 2 and the URI registered with your OAuth application.- Expired
code— authorization codes are short-lived (seconds, not minutes). Exchange them immediately on callback. codeVerifierdoesn’t hash tocodeChallenge— verify you’re using SHA-256 and base64url encoding without=padding on both the challenge generation and the verifier transmission.- Wrong header — the token exchange requires
x-auth-scheme: web2, notapi-tokenorapi-oauth-token.
API calls return 401 with a valid access token
API calls return 401 with a valid access token
Check the headers. OAuth access tokens use
x-auth-scheme: api-oauth-token and x-auth-access-token: <token>. Using x-auth-apikey (the API key header) with an OAuth access token will fail — those are different schemes with different header names.Redirect lands on the console login page again with no code
Redirect lands on the console login page again with no code
The
client_id you’re sending may be unrecognized. Double-check you’re using the clientId returned from submitApplication, not the application UUID from a different response. If you rotated applications, the old clientId is no longer valid.`isPartner=true` arrives unexpectedly
`isPartner=true` arrives unexpectedly
A partner account holder authenticated through a flow your app doesn’t support. Either implement the partner flow or show the user a clear error message explaining your app supports standard Rhombus orgs only.
Next steps
Rhombus CLI
Read how the official CLI uses this flow end to end
API Reference
Browse all endpoints available once you have an access token
Rate Limits
Understand request limits before you ship
Developer Community
Request production OAuth review and ask questions