openai-auth
A Rust library for OpenAI/ChatGPT OAuth 2.0 authentication with PKCE support.
Provides both synchronous (blocking) and asynchronous (runtime-agnostic) APIs for authenticating with OpenAI's OAuth 2.0 endpoints.
Features
- ✅ Sync & Async APIs - Choose blocking or async based on your needs
- ✅ Runtime Agnostic - Async API works with tokio, async-std, smol, etc.
- ✅ PKCE Support - Secure SHA-256 PKCE authentication flow
- ✅ Fully Configurable - Custom client IDs, endpoints, redirect URIs, ports
- ✅ Browser Integration - Auto-open browser for authorization (default enabled)
- ✅ Callback Server - Optional local server for automatic callback handling
- ✅ JWT Utilities - Extract ChatGPT account ID from access tokens
- ✅ API Key Exchange - Exchange id_token for OpenAI API key (Codex CLI flow)
- ✅ No Token Storage - You control how/where to persist tokens
Installation
[]
= "1.0"
⚠️ Breaking Changes in v1.0
The callback server API has changed to fix OAuth session handling issues:
run_callback_server()now returnsTokenSetinstead ofString- Token exchange happens automatically inside the callback server
- No need to call
client.exchange_code()after getting the callback - This fixes the
login_challenge_not_found_in_sessionerror with OpenAI OAuth
Migration Guide:
// ❌ Old (v0.x):
let code = run_callback_server.await?;
let tokens = client.exchange_code.await?;
// ✅ New (v1.0):
let tokens = run_callback_server.await?;
Other APIs (manual code exchange, blocking, etc.) remain unchanged.
Quick Start (Async API - Default)
use ;
// or async-std, smol, etc.
async
Quick Start (Blocking API)
use ;
Feature Flags
| Feature | Description | Default |
|---|---|---|
async |
Asynchronous API (runtime-agnostic) | ✅ Yes |
blocking |
Synchronous/blocking API | ❌ No |
browser |
Auto-open browser for authorization | ✅ Yes |
callback-server |
Local server for OAuth callback (requires tokio) | ❌ No |
full |
Enable all features | ❌ No |
Enable blocking API:
[]
= { = "1.0", = ["blocking"] }
Enable callback server (full automation):
[]
= { = "1.0", = ["callback-server"] }
= { = "1", = ["full"] }
Custom Configuration
use ;
let config = builder
.client_id
.redirect_port // Custom port
.build;
let client = new?;
Examples
See the examples/ directory for complete working examples:
01_basic_manual_sync.rs- Basic sync flow with manual code entry02_with_browser_sync.rs- Sync with browser auto-open03_basic_manual_async.rs- Basic async flow04_callback_server.rs- Full automation with callback server05_id_token_sync.rs- Exchange the code for an API key (blocking)06_callback_custom_html.rs- Callback server with custom HTML responses
Run examples with:
Custom Callback HTML
You can provide a custom HTML responder for the callback server:
use ;
let html = ;
let tokens = run_callback_server_with_html.await?;
Token Storage
This library intentionally does not handle token persistence. You should store tokens securely based on your application's needs.
Recommended approaches:
- System Keychain: Use
keyringcrate - Encrypted Files: Encrypt tokens before writing to disk
- Environment Variables: For development/testing only
See examples/08_keyring_storage_sync.rs for a secure storage example.
API Overview
Async API (default, runtime-agnostic)
use OAuthClient;
let client = new?;
// Start flow (sync - no I/O needed)
let flow = client.start_flow?;
// Async methods
let tokens = client.exchange_code.await?;
let new_tokens = client.refresh_token.await?;
// Extract account ID from JWT (sync)
let account_id = client.extract_account_id?;
API Key Exchange (Codex CLI flow)
use OAuthClient;
let client = new?;
let flow = client.start_flow?;
let tokens = client.exchange_code_for_api_key.await?;
// Use tokens.api_key for OpenAI API requests
let api_key = tokens.api_key.as_deref;
Blocking API
use OAuthClient;
let client = new?;
// Start flow (generates PKCE, returns auth URL)
let flow = client.start_flow?;
// Exchange code for tokens
let tokens = client.exchange_code?;
// Refresh expired tokens
let new_tokens = client.refresh_token?;
Browser Integration
use open_browser;
let flow = client.start_flow?;
open_browser?; // Opens user's default browser
Callback Server (requires callback-server feature)
use ;
async
Requirements
- Rust 1.70+
- ChatGPT Plus or Pro subscription (for OAuth access)
License
MIT