How to Configure OAuth 2.0 PKCE Authentication for AI Providers in OmniRoute
OmniRoute automatically enables OAuth 2.0 PKCE for any AI provider that declares the supportsBrowserPkce capability, handling the full flow from code generation to token exchange without additional wiring.
OmniRoute implements the OAuth 2.0 Authorization Code flow with Proof Key for Code Exchange (PKCE) to securely authenticate browser-based logins for AI providers like Codex, xAI-OAuth, and Grok-CLI. According to the OmniRoute source code, the PKCE machinery is built into the core OAuth package in src/lib/oauth/ and activates automatically when a provider configuration sets the supportsBrowserPkce flag to true. This eliminates the need for client secrets while protecting against authorization code interception attacks.
How OmniRoute Implements the OAuth 2.0 PKCE Flow
The implementation follows RFC 8252, with five distinct phases handled by the internal OAuth utilities.
Step 1: Generate the PKCE Pair
When initiating authentication, OmniRoute calls generatePKCE() in src/lib/oauth/utils/pkce.ts (lines 27-36). This utility creates a cryptographically random code verifier, derives the code challenge using SHA-256, and generates a CSRF-protecting state token. These values are stored temporarily to validate the callback.
Step 2: Build the Authorization URL
In src/lib/oauth/providers.ts (lines 135-150), the provider configuration merges with the generated PKCE data. The resulting authorization URL includes the code_challenge and code_challenge_method=S256 parameters required by the PKCE specification.
Step 3: Start the Loop-Back Redirect Server
For PKCE-enabled providers, OmniRoute starts a local HTTP server on a fixed port (e.g., localhost:51786) defined by PKCE_LOOPBACK_REDIRECT_HINT in src/lib/oauth/utils/pkceLoopbackWarning.ts (lines 31-42). This loop-back URI captures the authorization code without exposing a public callback endpoint.
Step 4: Exchange the Authorization Code
After the user authenticates in the browser, OmniRoute POSTs to the provider’s token endpoint from src/lib/oauth/providers.ts (lines 260-270). The request includes the original code verifier (code_verifier) to prove the client’s identity, allowing the provider to return the access token and optional ID token.
Step 5: Route Handling and Provider Classification
The Next.js API route at src/app/api/oauth/[provider]/[action]/route.ts (lines 49-60) maintains a list of PKCE_CALLBACK_PROVIDERS. When a request matches a provider in this list, the route directs the flow to the PKCE-specific handlers rather than standard device-code flows.
Configuring a New AI Provider with PKCE Support
Adding PKCE support requires only a configuration change in the provider constants. No modifications to the OAuth logic are necessary.
1. Declare the Provider Configuration
Create or edit the provider entry in src/lib/oauth/constants/oauth.ts. The critical flag is supportsBrowserPkce: true:
// src/lib/oauth/constants/oauth.ts
export const MYAI_OAUTH_CONFIG = {
providerId: "myai",
flowType: "authorization_code",
supportsBrowserPkce: true, // Enable PKCE
pkceVerifierBytes: 32, // Optional: verifier entropy size
authorizeUrl: "https://api.myai.com/oauth/authorize",
tokenUrl: "https://api.myai.com/oauth/token",
scopes: ["openid", "profile", "ai:write"],
};
2. Register the Provider Module
Export the provider from the index file in src/lib/oauth/providers/index.ts:
// src/lib/oauth/providers/index.ts
export * from "./myai";
3. Create the Provider Wrapper (Optional)
For clean abstraction, create a thin wrapper in src/lib/oauth/providers/myai.ts:
// src/lib/oauth/providers/myai.ts
import { generatePKCE } from "../utils/pkce";
import { oauthBase } from "./base";
import { MYAI_OAUTH_CONFIG } from "../constants/oauth";
export const myaiProvider = oauthBase({
config: MYAI_OAUTH_CONFIG,
// Base implementation automatically calls generatePKCE()
// because supportsBrowserPkce is true
});
When the client calls GET /api/oauth/myai/authorize, OmniRoute executes the full PKCE flow automatically.
Optional Customizations
You can fine-tune PKCE behavior for specific deployment environments.
Override the Loop-Back Port
Most providers use the default port mapping defined in PKCE_LOOPBACK_CALLBACK_PORT within src/lib/oauth/utils/pkceLoopbackWarning.ts. To assign a custom port for a specific provider, add an entry to this map:
// In pkceLoopbackWarning.ts
export const PKCE_LOOPBACK_CALLBACK_PORT: Record<string, number> = {
myai: 51800,
// ... other providers
};
Disable PKCE for Legacy Providers
For providers that require plain authorization code flows without PKCE (such as legacy native clients), set supportsBrowserPkce: false in the configuration, or add the provider identifier to the NO_PKCE_DEVICE_CODE_PROVIDERS list in the OAuth constants.
Key Source Files and Functions
| File Path | Role |
|---|---|
src/lib/oauth/utils/pkce.ts |
Contains generatePKCE() for creating verifiers and challenges |
src/lib/oauth/utils/pkceLoopbackWarning.ts |
Defines PKCE_LOOPBACK_REDIRECT_HINT and port mappings for loop-back servers |
src/lib/oauth/providers.ts |
Builds authorization URLs and handles token exchange with code_verifier |
src/lib/oauth/constants/oauth.ts |
Central registry for provider configurations using supportsBrowserPkce |
src/app/api/oauth/[provider]/[action]/route.ts |
API route dispatcher that classifies PKCE_CALLBACK_PROVIDERS |
src/lib/oauth/providers/index.ts |
Module export index for all provider implementations |
Summary
- OmniRoute implements OAuth 2.0 PKCE (RFC 8252) to secure browser-based authentication for AI providers without requiring client secrets.
- Enable PKCE by setting
supportsBrowserPkce: trueinsrc/lib/oauth/constants/oauth.ts; the system handlesgeneratePKCE(), loop-back servers, and token exchange automatically. - The flow generates a code verifier and challenge in
src/lib/oauth/utils/pkce.ts, builds the authorization URL insrc/lib/oauth/providers.ts, and completes exchange via the API route insrc/app/api/oauth/[provider]/[action]/route.ts. - Customize redirect ports by editing
PKCE_LOOPBACK_CALLBACK_PORTinpkceLoopbackWarning.ts, or disable PKCE entirely by adding providers toNO_PKCE_DEVICE_CODE_PROVIDERS.
Frequently Asked Questions
What is PKCE and why does OmniRoute use it for AI providers?
PKCE (Proof Key for Code Exchange) is an OAuth 2.0 extension that prevents authorization code interception attacks by requiring a cryptographically generated verifier that only the requesting client possesses. OmniRoute uses PKCE for AI providers like Codex and Grok-CLI because it enables secure token acquisition in browser-based flows without exposing client secrets in desktop or mobile applications.
How do I enable PKCE for a custom AI provider in OmniRoute?
Add a configuration object to src/lib/oauth/constants/oauth.ts with supportsBrowserPkce: true and the appropriate authorization and token endpoints. Export the provider from src/lib/oauth/providers/index.ts. The oauthBase() function in src/lib/oauth/providers.ts will automatically invoke generatePKCE() and handle the loop-back server when users initiate authentication.
Can I customize the redirect port for PKCE authentication?
Yes. While OmniRoute assigns default ports via PKCE_LOOPBACK_CALLBACK_PORT in src/lib/oauth/utils/pkceLoopbackWarning.ts, you can override this by adding your provider ID to the port mapping object. This is useful when the default port conflicts with local services or when a provider requires a specific redirect URI registration.
Which providers in OmniRoute already support OAuth 2.0 PKCE?
The OmniRoute source code explicitly identifies providers requiring browser-based PKCE flows—such as Codex, xAI-OAuth, Grok-CLI, and Openference—through the PKCE_CALLBACK_PROVIDERS constant in src/app/api/oauth/[provider]/[action]/route.ts. Any provider with supportsBrowserPkce: true in src/lib/oauth/constants/oauth.ts uses this secure authentication method.
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 →