How to Set Up OAuth Integration with Codex and Claude Code in AxonHub
AxonHub implements PKCE-based OAuth flows for both OpenAI Codex and Anthropic Claude Code, exposing REST endpoints to start sessions and exchange callbacks for access tokens.
AxonHub provides native OAuth integration with Codex and Claude Code through a unified PKCE (Proof-Key for Code Exchange) architecture. This implementation eliminates the need to store client secrets server-side while securely managing access tokens for LLM transformations. The following guide covers the complete setup process using AxonHub's administrative API endpoints.
Understanding the OAuth Flow Architecture
The OAuth implementation in AxonHub follows a standardized five-step PKCE pattern that applies to both providers. According to the source code in internal/server/api/codex.go and internal/server/api/claudecode.go, the flow generates cryptographically secure parameters before redirecting users to the provider's consent screen.
PKCE Implementation Details
When initiating a session, AxonHub generates a random 64-byte code_verifier and derives a SHA-256 code_challenge. The system also creates a unique state parameter to prevent CSRF attacks. These values are temporarily cached using the xcache abstraction defined in internal/pkg/xcache/cache.go with a 10-minute expiration window.
State Management and Caching
The OAuth state persists in AxonHub's cache layer during the handshake period. This allows the system to validate the callback integrity when the user returns from the provider's authorization server. The cache implementation supports both in-memory and Redis-backed configurations depending on your deployment topology.
API Endpoints for Codex OAuth
AxonHub exposes dedicated REST endpoints under /admin/codex/oauth/ for managing OpenAI Codex authentication. These routes are registered in internal/server/routes.go and handled by the functions in internal/server/api/codex.go.
Starting the Flow
To initiate OAuth with Codex, send a POST request to the start endpoint:
curl -X POST http://localhost:8090/admin/codex/oauth/start \
-H "Content-Type: application/json" \
-d '{}'
The response contains a session_id and the auth_url where you must redirect the user:
{
"session_id": "bFz1V8...5gA",
"auth_url": "https://codex.ai/oauth/authorize?response_type=code&client_id=...&code_challenge=...&state=bFz1V8...5gA"
}
Exchanging the Callback
After the user consents, Codex redirects to your configured RedirectURI with query parameters containing code and state. Exchange these for credentials by calling:
curl -X POST http://localhost:8090/admin/codex/oauth/exchange \
-H "Content-Type: application/json" \
-d '{
"session_id": "bFz1V8...5gA",
"callback_url": "https://your-app/callback?code=XYZ&state=bFz1V8...5gA"
}'
The codex.NewTokenProvider function in llm/transformer/openai/codex/token.go handles the actual token exchange with OpenAI's endpoint. The response returns a JSON credentials string:
{
"credentials": "{\"access_token\":\"eyJ...\",\"refresh_token\":\"r1...\",\"expires_in\":3600}"
}
API Endpoints for Claude Code OAuth
Anthropic Claude Code integration follows an identical pattern but requires special handling for state parameters encoded in URL fragments. The implementation resides in internal/server/api/claudecode.go with token exchange logic in llm/transformer/anthropic/claudecode/token_provider.go.
Fragment-Based State Handling
Claude Code returns the state parameter in the URL fragment (after the # symbol) rather than query parameters. AxonHub's parseClaudeCodeCallbackURL function checks both the fragment and query string as a fallback to maintain compatibility.
Initiate the flow using the Claude Code specific endpoint:
curl -X POST http://localhost:8090/admin/claudecode/oauth/start \
-H "Content-Type: application/json" \
-d '{}'
The response structure mirrors the Codex format:
{
"session_id": "hJk9pW2...xYz",
"auth_url": "https://claude.ai/oauth/authorize?response_type=code&client_id=...&code_challenge=...&state=hJk9pW2...xYz"
}
Token Exchange
When exchanging the callback for Claude Code, ensure your callback_url includes the fragment containing the state:
curl -X POST http://localhost:8090/admin/claudecode/oauth/exchange \
-H "Content-Type: application/json" \
-d '{
"session_id": "hJk9pW2...xYz",
"callback_url": "https://your-app/callback?code=ABC#hJk9pW2...xYz"
}'
The claudecode.NewTokenProvider handles the exchange with Anthropic's OAuth server, returning credentials in the same JSON format as Codex.
Token Provider Implementation
Both OAuth flows rely on dedicated token providers that encapsulate provider-specific HTTP logic. The Codex provider in llm/transformer/openai/codex/token.go and the Claude Code provider in llm/transformer/anthropic/claudecode/token_provider.go implement the same interface but target different token endpoints.
These providers support optional HTTP proxy configuration through the llm/httpclient/client.go abstraction. Set the proxy field in your request configuration to route OAuth traffic through corporate proxies or regional gateways.
Configuration and Proxy Support
AxonHub's OAuth implementation supports enterprise network configurations through the HTTP client layer defined in llm/httpclient/client.go. When initializing either token provider, you can specify an optional proxy parameter to route token exchange requests through a custom HTTP proxy.
This configuration is particularly useful when running AxonHub in restricted network environments where direct access to OpenAI or Anthropic endpoints requires traffic inspection or regional routing.
Summary
- AxonHub implements PKCE-based OAuth for both OpenAI Codex and Anthropic Claude Code, eliminating the need for client secrets.
- The flow uses POST /admin/codex/oauth/start and POST /admin/claudecode/oauth/start to initiate sessions, returning authorization URLs.
- Callback handling differs between providers: Codex uses query parameters while Claude Code uses URL fragments for state validation.
- Exchange endpoints (POST /admin/{provider}/oauth/exchange) convert callback URLs to JSON credentials using provider-specific TokenProvider implementations.
- Both flows support HTTP proxy configuration through the shared HTTP client abstraction for enterprise network deployments.
Frequently Asked Questions
How does AxonHub handle the state parameter differently for Claude Code compared to Codex?
AxonHub expects the state parameter in the URL fragment (after the # symbol) for Claude Code callbacks, whereas Codex returns state as a standard query parameter. The parseClaudeCodeCallbackURL function in internal/server/api/claudecode.go checks both locations to maintain compatibility with different redirect scenarios.
What is the expiration time for OAuth state sessions in AxonHub?
OAuth state parameters are cached for 10 minutes using the xcache abstraction defined in internal/pkg/xcache/cache.go. This window allows sufficient time for users to complete the provider's consent screen while minimizing the risk of replay attacks.
Can I route OAuth token exchanges through a corporate proxy?
Yes. Both the Codex and Claude Code token providers support optional HTTP proxy configuration through the llm/httpclient/client.go client. When initializing the OAuth flow, include the proxy field in your configuration to route token exchange traffic through your specified proxy server.
Where are the OAuth route handlers registered in the AxonHub server?
The REST endpoints for OAuth are registered in internal/server/routes.go. This file maps POST /admin/codex/oauth/start, POST /admin/codex/oauth/exchange, and their Claude Code equivalents to the handler functions defined in internal/server/api/codex.go and internal/server/api/claudecode.go respectively.
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 →