How to Configure OAuth for Provider Authentication in OmniRoute

To configure OAuth in OmniRoute, set NEXT_PUBLIC_BASE_URL for callback URLs, optionally override default credentials via environment variables, and run omniroute oauth login <provider> to authenticate through the browser flow.

OmniRoute treats every OAuth-enabled AI provider as a first-class connection, implementing a three-layer architecture that handles provider registration, encrypted token storage, and automatic refresh. This guide walks you through configuring OAuth authentication using the built-in CLI and dashboard interfaces, referencing the actual implementation in the diegosouzapw/OmniRoute repository.

Understanding OmniRoute's OAuth Architecture

OmniRoute's OAuth implementation consists of three tightly-coupled layers that manage the entire authentication lifecycle.

Provider Registration Layer

The static provider list in src/shared/constants/providers/oauth.ts registers every OAuth-enabled provider (Claude, Gemini, GitHub, GitLab Duo, etc.). Each entry contains a public client_id embedded via resolvePublicCred() in src/lib/oauth/constants/oauth.ts, enabling zero-configuration installations while allowing operators to override defaults through environment variables.

OAuth Credential Handling Layer

Tokens are encrypted at rest using AES-256-GCM and stored in the SQLite provider_connections table (see src/lib/db/provider_connections.ts). The tokenRefresh service (src/sse/services/tokenRefresh.ts) runs background health checks to detect expiring tokens (TOKEN_EXPIRY_BUFFER_MS) and refresh them automatically via provider-specific implementations.

API and UI Orchestration Layer

Dynamic API routes in src/app/api/oauth/[provider]/[action]/route.ts expose endpoints for login, callback, refresh, and logout actions. These routes handle the OAuth 2.0 flow, validate state parameters, exchange authorization codes for tokens, and persist credentials securely.

Prerequisites and Environment Setup

Before initiating OAuth flows, you must configure the base URL that providers use for redirect callbacks.

Set the NEXT_PUBLIC_BASE_URL environment variable in your .env file:

NEXT_PUBLIC_BASE_URL=https://omniroute.example.com

This value constructs the callback URI (<BASE_URL>/callback) that OAuth providers redirect to after user consent. According to docs/reference/ENVIRONMENT.md, this variable is required for both the dashboard and CLI authentication flows.

Step-by-Step OAuth Configuration

1. Configure the Base URL

Ensure NEXT_PUBLIC_BASE_URL points to your OmniRoute instance domain. This enables the OAuth callback handler to receive authorization codes from providers.

2. (Optional) Override Default Credentials

OmniRoute ships with public OAuth credentials for convenience, but you should override these for production deployments. Create custom OAuth apps in your provider's developer console, then set the corresponding environment variables:

GITLAB_DUO_OAUTH_CLIENT_ID=your-gitlab-app-id
GITLAB_DUO_OAUTH_CLIENT_SECRET=your-gitlab-app-secret

The resolvePublicCred() function in src/lib/oauth/constants/oauth.ts automatically prioritizes these environment variables over baked-in defaults.

3. Initiate the Login Flow

Via CLI:

omniroute oauth login gitlab-duo

This command opens your system browser to the provider's authorization endpoint. After consent, the provider redirects to your callback URL, and OmniRoute exchanges the code for access and refresh tokens.

Via Dashboard:

  1. Navigate to Providers → Add Provider
  2. Select the desired OAuth provider (e.g., GitLab Duo)
  3. Click Login to trigger the browser flow
  4. After authorization, the dashboard displays the connection with Active status

4. Verify the Connection

Confirm successful authentication by listing active OAuth connections:

omniroute oauth list

This outputs provider IDs, associated user emails, token expiry dates, and connection status by querying the encrypted provider_connections table.

Token Management and Automatic Refresh

OmniRoute handles token persistence and renewal automatically. The tokenRefresh service (src/sse/services/tokenRefresh.ts) implements:

  • Expiry Detection: Monitors tokens against TOKEN_EXPIRY_BUFFER_MS thresholds
  • Atomic Rotation: Prevents race conditions via rotation maps when updating credentials
  • Provider-Specific Logic: Executes refresh implementations located in open-sse/services/tokenRefresh/providers/

To force an immediate refresh:

omniroute oauth refresh gitlab-duo

This invokes refreshGitLabDuoToken() (or the provider-specific equivalent) directly.

Resilience Configuration

OAuth connections participate in OmniRoute's three-layer resilience system. Configure circuit-breaker thresholds via:

OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD=5
OMNIROUTE_CIRCUIT_BREAKER_OAUTH_RESET_MS=60000

These values, defined in open-sse/config/constants.ts, control how many failures trigger cooldown periods before retrying authentication attempts.

Programmatic Usage

When building custom integrations, retrieve valid access tokens programmatically:

import { getAccessToken } from '@omniroute/open-sse/services/tokenRefresh';

// Get fresh token for GitHub (auto-refreshes if expired)
const token = await getAccessToken('github', { refreshToken: undefined }, false);
console.log('Bearer:', token);

The routing layer (open-sse/services/combo.ts) uses hasUsableOAuthToken(providerId) from src/lib/oauth/helpers.ts to filter connections with valid, non-expired tokens before forwarding requests.

Troubleshooting and Resilience

If authentication fails, verify these common configuration issues:

  • Redirect URI Mismatch: Ensure NEXT_PUBLIC_BASE_URL matches the callback URL registered in your OAuth app exactly
  • Token Encryption: Verify the database encryption key is persisted; tokens stored in provider_connections use AES-256-GCM and cannot be read without the proper key
  • Circuit Breaker: Check if the provider is temporarily disabled due to OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD violations

Summary

  • Set NEXT_PUBLIC_BASE_URL before initiating any OAuth flows to ensure callbacks reach your OmniRoute instance
  • Override default credentials via environment variables (e.g., GITLAB_DUO_OAUTH_CLIENT_ID) for production security
  • Use omniroute oauth login <provider> to authenticate through the browser flow, or trigger via the dashboard
  • Tokens encrypt automatically using AES-256-GCM in the provider_connections table and refresh via src/sse/services/tokenRefresh.ts
  • Reference implementation files: src/shared/constants/providers/oauth.ts for provider definitions, src/lib/oauth/constants/oauth.ts for credential resolution, and src/app/api/oauth/[provider]/[action]/route.ts for flow handling

Frequently Asked Questions

How does OmniRoute store OAuth tokens securely?

OmniRoute encrypts all OAuth tokens using AES-256-GCM before persisting them in the SQLite provider_connections table (see src/lib/db/provider_connections.ts). The encryption key is managed by the database layer, ensuring tokens remain secure at rest while remaining accessible to the automatic refresh service.

Can I use my own OAuth app instead of OmniRoute's default credentials?

Yes. While OmniRoute includes public client_id values baked into the binary via resolvePublicCred() in src/lib/oauth/constants/oauth.ts, you can override these by setting provider-specific environment variables like GITLAB_DUO_OAUTH_CLIENT_ID and GITLAB_DUO_OAUTH_CLIENT_SECRET. These variables take precedence over the embedded defaults.

Why is my OAuth provider showing as inactive in the dashboard?

A provider appears inactive when hasUsableOAuthToken() in src/lib/oauth/helpers.ts detects missing or expired tokens. This can occur if the initial authentication failed, the refresh token expired, or the circuit breaker triggered due to consecutive API failures. Run omniroute oauth refresh <provider> to force a token renewal, or re-authenticate using omniroute oauth login <provider>.

Does OmniRoute support PKCE for OAuth authentication?

Yes. OmniRoute implements the OAuth 2.0 authorization code flow with PKCE support where required by providers. The CLI command omniroute oauth login <provider> automatically generates code verifiers and challenges, handling the PKCE exchange in the /api/oauth/[provider]/callback route without requiring manual configuration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →