Coding Agent OAuth Flow
Relevant source files
The following files were used as context for generating this wiki page:
The Coding Agent includes an OAuth flow to securely authenticate with third-party services, providing an alternative to manually configuring API keys via environment variables. This system allows the agent to obtain API access tokens on behalf of the user, which are then stored locally for use in subsequent API calls. The primary supported provider for this flow is Anthropic.
This flow is initiated by the user through the /login and /logout slash commands within the Terminal User Interface (TUI). The process involves opening a browser for user authorization, capturing an authorization code, and exchanging it for access and refresh tokens.
Sources: packages/coding-agent/src/tui/tui-renderer.ts:1003-1011, packages/coding-agent/src/oauth/index.ts, packages/mom/src/agent.ts:40-46
Architecture Overview
The OAuth system is composed of several key components that work together to manage authentication, token exchange, and storage. The TuiRenderer handles user interaction, while the core logic in the oauth directory manages the provider-specific details and secure token storage.
The following diagram illustrates the main components of the OAuth flow and their interactions.
Key Components
| Component | File Path | Description |
|---|---|---|
| TuiRenderer | packages/coding-agent/src/tui/tui-renderer.ts | Manages the TUI, handles slash commands like /login and /logout, and displays the OAuthSelectorComponent. |
| OAuthSelectorComponent | packages/coding-agent/src/tui/oauth-selector.ts | A TUI component that presents a list of OAuth providers for the user to select for login or logout. |
OAuth Core (index.ts) | packages/coding-agent/src/oauth/index.ts | The main entry point for the OAuth flow. It orchestrates the login and logout process by calling provider-specific logic. |
| Anthropic Provider | packages/coding-agent/src/oauth/anthropic.ts | Implements the OAuth 2.0 logic specific to Anthropic, including URL generation and code-for-token exchange. |
| Token Storage | packages/coding-agent/src/oauth/storage.ts | Handles the serialization and deserialization of OAuth tokens to and from the oauth.json file. |
| Model Configuration | packages/coding-agent/src/main.ts | Uses the stored OAuth token as an API key when making requests to the corresponding provider. |
| Mom Agent | packages/mom/src/agent.ts | The Slack bot mom also utilizes the OAuth token by reading the ANTHROPIC_OAUTH_TOKEN environment variable. |
Sources: packages/coding-agent/src/tui/tui-renderer.ts, packages/coding-agent/src/oauth/index.ts, packages/coding-agent/src/oauth/anthropic.ts, packages/coding-agent/src/oauth/storage.ts, packages/coding-agent/src/main.ts, packages/mom/src/agent.ts
Login Flow
The login process is initiated by the user and involves interaction between the TUI, the core OAuth logic, and an external browser.
This sequence diagram details the step-by-step process from the user command to the successful storage of tokens.
Key Functions
TuiRenderer.showOAuthSelector(): Displays the UI for selecting an OAuth provider.
Sources: packages/coding-agent/src/tui/tui-renderer.ts:1003-1011login(providerId, onAuthUrl, onCode): The central function inoauth/index.tsthat manages the login flow. It takes callbacks to interact with the TUI.
Sources: packages/coding-agent/src/oauth/index.ts:24-60anthropic.getAuthUrl(): Generates the specific URL for Anthropic's authorization endpoint.
Sources: packages/coding-agent/src/oauth/anthropic.ts:11-23anthropic.exchangeCode(): Exchanges the authorization code for an access token and refresh token by making a POST request to Anthropic's token endpoint.
Sources: packages/coding-agent/src/oauth/anthropic.ts:25-39
Logout Flow
The logout process is simpler, involving the removal of stored tokens for a selected provider.
logout(providerId): The function inoauth/index.tsthat removes the tokens for the specified provider from storage.
Sources: packages/coding-agent/src/oauth/index.ts:62-70
Token Storage and Usage
Storage Mechanism
OAuth tokens are stored in a JSON file named oauth.json inside the agent's configuration directory (~/.pi/agent/). The storage.ts module provides functions to read, write, and delete these tokens.
The data is stored in a key-value format where the key is the provider ID.
// packages/coding-agent/src/oauth/storage.ts:6-11
export interface StoredTokenData {
accessToken: string;
refreshToken: string;
expiresAt: number; // Unix timestamp in milliseconds
}
| Function | Description |
|---|---|
loadTokens() | Reads oauth.json and returns all stored token data. |
saveTokens() | Writes the token data for a specific provider to oauth.json. |
deleteTokens() | Removes the token data for a specific provider from oauth.json. |
getOAuthPath() | Returns the full path to the oauth.json file. |
Sources: packages/coding-agent/src/oauth/storage.ts
Token Usage
Once a token is stored, it is used as an API key for making requests.
-
Coding Agent: The
getApiKeyForModelfunction inmain.tschecks for an OAuth token for the given model's provider. If an access token exists, it is returned and used for API calls. This takes precedence over environment variables likeANTHROPIC_API_KEY.
Sources: packages/coding-agent/src/main.ts:771-787 -
Mom (Slack Bot): The
momagent has a similar mechanism. ThegetAnthropicApiKeyfunction checks for theANTHROPIC_OAUTH_TOKENenvironment variable first, which is expected to be the stored access token.
Sources: packages/mom/src/agent.ts:40-46
This flow diagram shows how an API key is resolved.
Summary
The OAuth flow in the pi-mono repository provides a robust and user-friendly way to manage API credentials for services like Anthropic. By integrating directly into the TUI with /login and /logout commands, it abstracts away the complexity of manual token management. The system securely stores tokens on the local filesystem and prioritizes them over environment variables, creating a seamless authentication experience for the user.