Authentication System
Relevant source files
The following files were used as context for generating this wiki page:
The Authentication System in shunt is a multi-layered infrastructure designed to handle both inbound client verification and outbound provider credential management. Its primary purpose is to gate access to the gateway while facilitating secure communication with various LLM providers (Anthropic, OpenAI, xAI, Cursor, and ChatGPT/Codex). The system ensures that all requests passing through the gateway are authorized and that sensitive provider tokens are handled according to strict safety invariants.
The architecture separates authentication into inbound auth (verifying the caller) and outbound auth (managing credentials for upstream providers). It utilizes a hot-swappable state mechanism allowing for credential updates and route re-configuration without process restarts.
Sources: ARCHITECTURE.md:16-25, src/auth/mod.rs
System Architecture
The authentication system sits within the Infrastructure layer of the project, providing services to the Application and Domain layers. It is primarily invoked during the request pipeline in the proxy module.
The diagram shows how authentication is split into an initial gate for incoming requests and a subsequent injection phase for outgoing upstream requests.
Sources: ARCHITECTURE.md:32-45, src/proxy.rs
Inbound Authentication
Inbound authentication acts as the entry gate for the gateway. It validates that the client (typically Claude Code) has the right to use the shunt proxy. This is governed by the [server.auth] configuration section.
Authentication Mechanisms
The system supports two primary methods for inbound client validation:
- API Key / Bearer Token: Standard token-based authentication.
- OIDC / OAuth: Integration for external identity providers (where configured).
The inbound_auth gate in src/proxy.rs checks headers against the snapshotted configuration. If a request model matches no specific route, it resolves to the default_provider (usually Anthropic), but the inbound gate still applies to ensure only authorized clients can utilize the proxy.
Sources: src/auth/inbound.rs, src/proxy.rs, ARCHITECTURE.md:73-77
Outbound Provider Authentication
Once a request is authorized and routed, the gateway must authenticate with the specific upstream provider. Each provider type has a corresponding adapter and authentication strategy.
Supported Provider Auth Strategies
| Provider | Auth Type | Credential Source | Key Files |
|---|---|---|---|
| Anthropic | Passthrough / OAuth | ~/.claude/.credentials.json | auth/claude.rs |
| OpenAI | API Key | OPENAI_API_KEY env/config | auth/shared.rs |
| xAI | API Key | XAI_API_KEY env/config | auth/shared.rs |
| Cursor | OAuth | Cursor login flow | auth/cursor/ |
| ChatGPT/Codex | OAuth | ChatGPT login flow | auth/codex/ |
Sources: ARCHITECTURE.md:82-95, src/auth/mod.rs
Credential Management and Lifecycle
The system manages the lifecycle of credentials, including lookup and background refreshing. This is particularly critical for OAuth-based providers like Codex and Cursor.
- Refresh Logic: Credentials are read and refreshed from local files. Refresh operations are designed to be cancellation-safe and use off-thread I/O to prevent blocking the async runtime.
- Writeback Invariants: The system strictly guards credential writeback. Modified tokens (e.g., after a refresh) are persisted back to the filesystem (e.g.,
~/.claude/.credentials.json) to maintain session continuity.
Sources: ARCHITECTURE.md:104-108, AGENTS.md:78-82
Data Flow: Authentication Injection
The following sequence diagram illustrates how authentication is handled during a standard proxy request.
The flow highlights the distinct check at the start of the request and the injection of new credentials before the final dispatch.
Sources: src/proxy.rs, src/auth/mod.rs, ARCHITECTURE.md:20-30
Security Invariants
The Authentication System maintains several critical security boundaries to prevent credential leakage and unauthorized access:
- Credential Origins: Auth modules enforce allowed origins for injected bearer credentials.
- Safety Guards: The system prohibits committing secrets, tokens, or local generated config files to the repository.
- Error Masking: Gateway-owned authentication errors are reshaped into the Anthropic error envelope (
{"type":"error","error":{"type":"authentication_error",...}}) to prevent leaking implementation details to the client. - Snapshotting: Configuration and auth state are snapshotted once per request. A hot-reload of the configuration will not affect in-flight requests, ensuring consistency.
Sources: AGENTS.md:83-85, ARCHITECTURE.md:98-103, src/auth/mod.rs
Summary
The shunt Authentication System provides a robust gateway pattern for LLM access. By decoupling inbound verification from outbound provider authentication, it allows developers to swap models and providers (e.g., using OpenAI instead of Anthropic) while maintaining a consistent security posture for the client application. The system's reliance on file-based credential storage and background refresh logic enables seamless integration with official CLI tools and long-running developer sessions.