How to Configure OAuth Providers with OmniRoute's 22 Provider Modules
OmniRoute centralizes OAuth provider configuration in src/lib/oauth/constants/oauth.ts and maps them to 22 modular LLM providers via open-sse/config/providerRegistry.ts, enabling PKCE or device-code flows without embedding secrets in source code.
OmniRoute is an open-source routing layer that unifies access to multiple LLM providers through a single OpenAI-compatible API. To configure OAuth providers with OmniRoute, you modify a single constants file to define PKCE parameters and register the provider in the centralized registry, allowing the routing engine to automatically handle token lifecycle management across all 22 supported modules.
Centralized OAuth Configuration File
All OAuth provider definitions live in src/lib/oauth/constants/oauth.ts. This file exports configuration objects that specify the data required for PKCE or device-code flows.
Each configuration object contains:
clientId– Resolved dynamically viaresolvePublicCred()to prevent literal secrets in source controlauthorizeUrlandtokenUrl– The OAuth provider's endpoint URLsscopes– Provider-specific OAuth scopes (e.g.,openid,offline_access)extraParams– Additional query parameters such asprompt=loginfor multi-account support- Optional fields –
userInfoUrl,clientSecret, ordeviceCodeUrlfor device-code flows
The provider registry imports these constants, creating a single source of truth for all 22 modules.
Registering a New OAuth Provider
Adding a new OAuth provider to OmniRoute requires four specific steps:
-
Create the configuration export.
Define a constant insrc/lib/oauth/constants/oauth.tsusingresolvePublicCred()to inject the client ID from environment variables. -
Update the provider registry.
Add an entry toopen-sse/config/providerRegistry.tsspecifyingid,name,format(typically"openai"for OAuth providers),baseUrl, and point theauthfield to your exported config. Include the array of available models with theirid,name, andmaxTokens. -
Configure the executor (if needed).
Most providers reuse the genericOAuthExecutorlocated inopen-sse/executors/oauthExecutor.ts. If the provider requires custom request handling, create a new executor underopen-sse/executors/and reference it in the registry entry. -
Write unit tests.
Add tests undertests/unit/that import the registry entry and assert OAuth fields are correctly wired, ensuring the token refresh logic integrates properly.
How the 22 Modules Consume OAuth Configs
When a request targets any of the 22 OAuth-enabled providers (e.g., model: "claude-2"), OmniRoute's pipeline executes four distinct stages:
-
Routing –
open-sse/services/combo.tslookups the model inopen-sse/config/providerRegistry.ts. If the entry'sauthfield contains an OAuth configuration, the router flags the request for token management. -
Token Acquisition –
src/lib/oauth/tokenRefreshService.tsretrieves the provider'sclientId,authorizeUrl, and scopes, then executes the PKCE or device-code flow. It stores the resulting access token on the connection record. -
Execution – The
OAuthExecutor(or a provider-specific executor) attaches the bearer token to outbound requests via theAuthorization: Bearer <access_token>header. -
Translation – Response translators (such as
open-sse/translator/claude.ts) process the upstream payload unchanged, as the authentication layer remains transparent to response formatting.
OmniRoute's 22 OAuth Provider Modules
The current release ships 22 OAuth-enabled provider modules, with key configurations defined in src/lib/oauth/constants/oauth.ts including:
- Claude –
CLAUDE_CONFIG - Codex (OpenAI) –
CODEX_CONFIG - Qoder –
QODER_CONFIG - CodeBuddy CN –
CODEBUDDY_CN_CONFIG - Grok CLI –
GROK_CLI_CONFIG - Grok Build –
GROK_BUILD_OAUTH_CONFIG - xAI API –
XAI_OAUTH_CONFIG - Openference –
OPENFERENCE_CONFIG - Kimi Coding –
KIMI_CODING_CONFIG - KiloCode –
KILOCODE_CONFIG - Cline –
CLINE_CONFIG - Antigravity –
ANTIGRAVITY_CONFIG
Additional providers utilize the generic OAuth executor infrastructure, bringing the total to 22 modular integrations.
Practical Implementation Example
The following example demonstrates adding a hypothetical "MyAI" provider to OmniRoute's ecosystem:
// src/lib/oauth/constants/oauth.ts
import { resolvePublicCred } from "@omniroute/open-sse/utils/publicCreds.ts";
export const MYAI_CONFIG = {
clientId: resolvePublicCred("myai_id", "MYAI_OAUTH_CLIENT_ID"),
authorizeUrl: "https://auth.myai.com/oauth/authorize",
tokenUrl: "https://auth.myai.com/oauth/token",
scopes: ["openid", "profile", "email", "offline_access"],
codeChallengeMethod: "S256",
};
// open-sse/config/providerRegistry.ts
import { REGISTRY } from "@omniroute/open-sse/config/providerRegistry.ts";
import { MYAI_CONFIG } from "../../src/lib/oauth/constants/oauth.ts";
REGISTRY["myai"] = {
id: "myai",
name: "MyAI",
format: "openai",
baseUrl: "https://api.myai.com/v1",
auth: MYAI_CONFIG,
models: [
{ id: "myai-chat", name: "MyAI Chat", maxTokens: 8192 },
],
};
// Client request
await fetch("http://localhost:20128/v1/chat/completions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: "myai-chat",
messages: [{ role: "user", content: "Hello!" }],
}),
});
Because the configuration uses resolvePublicCred(), you store the actual MYAI_OAUTH_CLIENT_ID in .env.example, keeping credentials out of the repository while allowing runtime injection.
Summary
- Centralized configuration – All OAuth parameters for the 22 modules reside in
src/lib/oauth/constants/oauth.ts, preventing credential leakage throughresolvePublicCred(). - Registry-based routing –
open-sse/config/providerRegistry.tsmaps model IDs to OAuth configs, enabling automatic token lifecycle management without code changes to the routing layer. - Four-stage pipeline – Requests flow through routing (
combo.ts), token acquisition (tokenRefreshService.ts), execution (OAuthExecutor), and translation layers seamlessly. - Modular expansion – Adding new providers requires only a registry entry and configuration export; the infrastructure handles PKCE flows, circuit-breaker back-off, and per-connection cooldowns automatically.
Frequently Asked Questions
How does OmniRoute prevent OAuth client secrets from appearing in source code?
OmniRoute uses the resolvePublicCred() utility function imported from @omniroute/open-sse/utils/publicCreds.ts to inject client IDs at runtime. You define environment variable names (such as MYAI_OAUTH_CLIENT_ID) in your configuration while storing actual values in .env.example or your deployment environment, ensuring no literal secrets exist in the repository.
Can I use device-code authentication instead of PKCE for OmniRoute providers?
Yes. The oauth.ts constants file supports optional fields including deviceCodeUrl and clientSecret. When these fields are present, src/lib/oauth/tokenRefreshService.ts automatically executes the device-code flow instead of PKCE, storing the resulting access token on the connection record for bearer token authentication.
Do I need to create a custom executor for every new OAuth provider?
No. Most of the 22 modules reuse the generic OAuthExecutor. You only need to create a custom executor under open-sse/executors/ if the provider requires non-standard request handling or authentication mechanisms that deviate from the standard OAuth 2.0 bearer token pattern.
Which file handles the actual token refresh logic for all 22 modules?
The src/lib/oauth/tokenRefreshService.ts file contains the core logic for token acquisition and refresh across all providers. It reads the provider-specific configuration from oauth.ts, manages the PKCE or device-code exchange, and maintains token state on connection records, insulating the routing and execution layers from OAuth complexity.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →