Skip to content

Authentication

Authentication is intentionally route-scoped. Once routing selects a provider, shunt resolves the credential strategy declared by that provider: pass through the Claude Code credential, read an API key, or reuse and refresh a subscription OAuth login (ChatGPT/Codex, or xAI SuperGrok via shunt login xai). That separation keeps Claude Code from needing provider-specific secrets for mapped models src/auth/mod.rs:29-99 src/auth/codex_auth.rs:34-63 src/auth/claude_auth.rs:27-92.

Credential mode Used by Secret source Boundary Source
Passthrough Anthropic default provider Inbound Claude Code headers Forwarded unchanged src/auth/mod.rs:17-22 src/adapters/anthropic.rs:66-89
ApiKey OpenAI and Anthropic-compatible gateways Env var named by api_key_env, with OpenAI fallback to Codex auth JSON Injected by shunt src/auth/mod.rs:57-80
ChatGptOAuth codex provider ~/.codex/auth.json Refreshed and sent with account ID src/auth/codex_auth.rs:34-63
XaiOauth xai provider (opt-in) ~/.shunt/xai-auth.json from shunt login xai (RFC 8628 device code) Refreshed under a single-flight lock (xAI rotates the refresh token), sent as Bearer only; base_url validated to stay on x.ai src/auth/xai_auth.rs:87-121 src/auth/xai_login.rs:52-100
Claude token helper Claude Code gateway discovery/pass-through credential SHUNT_GATEWAY_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, or ~/.claude/.credentials.json Printed to stdout for apiKeyHelper src/auth/claude_auth.rs:27-92
flowchart TB
    Route[Route provider] --> Provider[Config provider]
    Provider --> Auth{AuthMode}
    Auth -->|passthrough| Pass[Credential Passthrough]
    Auth -->|api_key| Env[Read api_key_env]
    Env -->|found| Api[Credential ApiKey]
    Env -->|OPENAI_API_KEY missing| CodexKey[Read OPENAI_API_KEY from codex auth]
    CodexKey --> Api
    Auth -->|chatgpt_oauth| Store[CodexAuthStore]
    Store --> Valid{Token valid beyond 5 min?}
    Valid -->|yes| Chat[Credential ChatGptOAuth]
    Valid -->|no| Refresh[Refresh token and atomic write-back]
    Refresh --> Chat
    Auth -->|xai_oauth| XStore[XaiAuthStore]
    XStore --> XValid{Token valid beyond 5 min?}
    XValid -->|yes| Xai[Credential XaiOauth]
    XValid -->|no| XRefresh[Single-flight refresh, persist rotated pair]
    XRefresh --> Xai
    classDef dark fill:#2d333b,stroke:#6d5dfc,color:#e6edf3;
    class Route,Provider,Auth,Pass,Env,Api,CodexKey,Store,Valid,Refresh,Chat,XStore,XValid,Xai,XRefresh dark;
    linkStyle default stroke:#8b949e;
sequenceDiagram
    autonumber
    participant Adapter as ResponsesAdapter
    participant Auth as resolve_credential
    participant Store as CodexAuthStore
    participant File as codex auth json
    participant OAuth as auth.openai.com
    Adapter->>Auth: route provider codex
    Auth->>Store: get_valid_chatgpt()
    Store->>File: read auth JSON
    Store->>Store: check JWT expiry with buffer
    alt expired
      Store->>OAuth: refresh_token grant
      OAuth-->>Store: new access/refresh/id token
      Store->>File: atomic write-back 0600
    end
    Store-->>Auth: access_token + account_id
    Auth-->>Adapter: Credential ChatGptOAuth
graph LR
    CC[Claude Code credential] -->|passthrough only| Anthropic[Anthropic-compatible upstream]
    Env[Provider API key env] -->|injected by shunt| OpenAI[OpenAI-compatible upstream]
    CodexFile[Codex auth JSON] -->|read and refresh by shunt| ChatGPT[ChatGPT Codex backend]
    ClaudeFile[Claude credentials JSON] -->|optional token helper| CC
    classDef dark fill:#2d333b,stroke:#6d5dfc,color:#e6edf3;
    class CC,Anthropic,Env,OpenAI,CodexFile,ChatGPT,ClaudeFile dark;
    linkStyle default stroke:#8b949e;
stateDiagram-v2
    [*] --> Missing
    Missing --> Present: env or file exists
    Present --> Valid: expiry beyond buffer
    Present --> RefreshNeeded: within five-minute buffer
    RefreshNeeded --> Valid: refresh succeeds
    RefreshNeeded --> Error: refresh fails
    Valid --> Injected: adapter builds request
    Error --> AuthenticationError
Page Relationship
Configuration Shows user-facing auth modes
xAI Grok Provider Setup for XAI_API_KEY and shunt login xai
Operations Shows codex login, OPENAI_API_KEY, and shunt token usage
Adapters and Translation Shows where credentials are injected
Testing and Quality Covers auth-related unit tests