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:
- Navigate to Providers → Add Provider
- Select the desired OAuth provider (e.g., GitLab Duo)
- Click Login to trigger the browser flow
- 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_MSthresholds - 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_URLmatches the callback URL registered in your OAuth app exactly - Token Encryption: Verify the database encryption key is persisted; tokens stored in
provider_connectionsuse 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_THRESHOLDviolations
Summary
- Set
NEXT_PUBLIC_BASE_URLbefore 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_connectionstable and refresh viasrc/sse/services/tokenRefresh.ts - Reference implementation files:
src/shared/constants/providers/oauth.tsfor provider definitions,src/lib/oauth/constants/oauth.tsfor credential resolution, andsrc/app/api/oauth/[provider]/[action]/route.tsfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →