# OAuth Authentication Flow in Kimi CLI: Technical Implementation and Platform Integration

> Explore the Kimi CLI OAuth authentication flow. Learn how it uses Authorization Code flow for secure platform integration and token exchange with auth.kimi.ai.

- Repository: [Moonshot AI/kimi-cli](https://github.com/MoonshotAI/kimi-cli)
- Tags: deep-dive
- Published: 2026-07-20

---

**Kimi CLI implements a standard OAuth 2.0 Authorization Code flow that opens a browser for user consent, receives the authorization code via a temporary local server, exchanges it for an access token at `https://auth.kimi.ai/token`, and persists credentials in the local configuration store.**

The Kimi CLI (hosted in the `MoonshotAI/kimi-cli` repository) authenticates users against the Kimi platform through a secure, multi-layered OAuth authentication flow. This implementation leverages Python's async generators and temporary HTTP servers to bridge the browser-based authorization process with the command-line interface, ensuring tokens are securely stored and validated for subsequent API requests.

## Three-Layer OAuth Architecture

The OAuth authentication flow in Kimi CLI is divided into three distinct architectural layers that handle user interaction, protocol negotiation, and request validation.

**CLI UI Layer** ([`src/kimi_cli/ui/shell/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/ui/shell/oauth.py)): Exposes the `login` and `logout` commands to users. The `login()` function triggers the authentication sequence and manages shell reloads after successful token acquisition.

**OAuth Helper Layer** ([`src/kimi_cli/auth/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/oauth.py)): Contains the core `login_kimi_code()` and `logout_kimi_code()` async generators. These functions manage the temporary local HTTP server, browser redirection, token exchange, and configuration persistence.

**Web-API Middleware Layer** ([`src/kimi_cli/web/auth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/web/auth.py)): Implements `AuthMiddleware` to validate bearer tokens on every incoming request. The middleware extracts tokens from `Authorization` headers and enforces origin rules using `verify_token()`.

## Step-by-Step OAuth Authorization Code Flow

When a user executes `kimi login`, the CLI orchestrates the following sequence:

1. **Platform Selection**: The shell command selects the Kimi platform using the constant `KIMI_CODE_PLATFORM_ID` defined in [`src/kimi_cli/auth/platforms.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/platforms.py).

2. **Authorization Request**: The `login_kimi_code()` helper constructs a URL pointing to `https://auth.kimi.ai/authorize` and launches the system browser via `webbrowser.open()`.

3. **Local Callback Server**: A temporary `uvicorn` HTTP server starts on a random local port (`localhost:<random-port>`) to receive the OAuth callback.

4. **User Authorization**: After the user approves the application in the browser, the Kimi auth service redirects to `http://localhost:<port>/?code=<auth_code>&state=<state>`.

5. **Code Extraction**: The temporary server's callback handler extracts the authorization code from query parameters, closes the HTTP listener, and yields a `waiting` event to the UI.

6. **Token Exchange**: The helper POSTs the authorization code to `https://auth.kimi.ai/token` (using built-in client credentials) and receives an access token and optional refresh token in the response.

7. **Credential Persistence**: The access token is stored in the CLI configuration under `config.providers[KIMI_CODE_PLATFORM_ID]` with the structure `{ "access_token": "...", "expires_at": <epoch> }`. The helper yields a `success` event.

8. **Shell Reload**: The `login()` function records a telemetry event and raises `Reload` to restart the shell with the new authentication context applied.

## Core OAuth Implementation Files

Understanding the source code locations is essential for extending or debugging the authentication flow:

- **[`src/kimi_cli/auth/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/oauth.py)**: Contains `login_kimi_code()` and `logout_kimi_code()` async generators that emit `waiting`, `success`, or `error` events during the authentication lifecycle.

- **[`src/kimi_cli/ui/shell/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/ui/shell/oauth.py)**: Houses the `login()` and `logout()` shell commands that wrap the OAuth helpers and handle UI event streaming.

- **[`src/kimi_cli/web/auth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/web/auth.py)**: Implements `AuthMiddleware` which performs timing-safe token comparison via `verify_token()` and returns **401 Unauthorized** for invalid or missing credentials.

- **[`src/kimi_cli/auth/platforms.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/platforms.py)**: Defines platform-specific constants including `KIMI_CODE_PLATFORM_ID` and authorization endpoint URL builders.

- **[`src/kimi_cli/config.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/config.py)**: Handles global configuration persistence, storing provider tokens and managing the `providers` dictionary structure.

## Practical Code Examples

### Interactive Login Command

When working in the Kimi shell, users trigger authentication with a single command:

```python

# In the interactive Kimi shell

>>> login

# Internally executes:

#   - Platform selection (KIMI_CODE_PLATFORM_ID)

#   - Browser opening to https://auth.kimi.ai/authorize

#   - Temporary uvicorn server startup on localhost

#   - Token exchange at https://auth.kimi.ai/token

#   - Configuration update with access_token and expires_at

#   - Shell reload via Reload exception

```

### Programmatic Login Implementation

Third-party tools can integrate the OAuth flow using the public async generator API:

```python
from kimi_cli.auth.oauth import login_kimi_code
from kimi_cli.config import load_config

async def perform_login():
    cfg = load_config()
    async for event in login_kimi_code(cfg):
        if event.type == "success":
            print("✅ Successfully authenticated with Kimi platform")
        elif event.type == "error":
            print(f"❌ Authentication failed: {event.message}")

```

### Accessing Stored Credentials

Retrieve the active access token from the configuration store:

```python
from kimi_cli.config import load_config
from kimi_cli.auth.platforms import KIMI_CODE_PLATFORM_ID

cfg = load_config()
provider = cfg.providers.get(KIMI_CODE_PLATFORM_ID)
access_token = provider["access_token"] if provider else None
print(f"Current token: {access_token}")

```

### Logout Implementation

Terminate the session by removing stored credentials:

```python
from kimi_cli.auth.oauth import logout_kimi_code
from kimi_cli.config import load_config

async def perform_logout():
    cfg = load_config()
    async for event in logout_kimi_code(cfg):
        print(event.message)  # Outputs success or error status

```

## API Token Validation

After authentication, every API request passes through the `AuthMiddleware` implemented in [`src/kimi_cli/web/auth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/web/auth.py). The middleware extracts bearer tokens from the `Authorization: Bearer <token>` header (or `?token=<token>` query parameter for GET requests) and validates them using constant-time comparison via `verify_token()`.

If the token is missing, malformed, or invalid, the middleware immediately returns a **401 Unauthorized** response. Valid tokens allow the request to proceed to the underlying API handlers. This validation occurs on every request, ensuring continuous security even for long-running CLI sessions.

## Summary

- **Kimi CLI uses OAuth 2.0 Authorization Code flow** with a temporary local callback server to bridge browser-based authentication and CLI environments.
- **Three architectural layers** (UI, OAuth helpers, and Web middleware) separate concerns between user interaction, protocol implementation, and request validation.
- **Key implementation files** include [`src/kimi_cli/auth/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/oauth.py) for flow logic and [`src/kimi_cli/web/auth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/web/auth.py) for token validation.
- **Tokens are stored** in `config.providers[KIMI_CODE_PLATFORM_ID]` with expiration timestamps and validated on every API call.
- **Async generators** emit structured events (`waiting`, `success`, `error`) enabling real-time UI feedback during authentication.

## Frequently Asked Questions

### What OAuth 2.0 grant type does Kimi CLI implement?

Kimi CLI implements the **Authorization Code** grant type as defined in RFC 6749. The flow initiates in the browser, returns an authorization code to a temporary local server listening on `localhost`, and exchanges that code for an access token at the `https://auth.kimi.ai/token` endpoint. This approach keeps client credentials and tokens out of the browser history while enabling secure CLI authentication.

### Where does Kimi CLI store access tokens locally?

Access tokens are persisted in the user configuration file managed by [`src/kimi_cli/config.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/config.py), specifically within the `providers` dictionary under the key `KIMI_CODE_PLATFORM_ID`. The stored object includes the `access_token` string and an `expires_at` Unix timestamp. This configuration is typically stored in the user's home directory and is distinct from shell environment variables for security isolation.

### How does Kimi CLI handle token expiration and refresh?

The current implementation stores an `expires_at` timestamp alongside the access token in the provider configuration. While the raw token exchange may include refresh tokens in the OAuth response, the CLI checks expiration timestamps during API request validation in `AuthMiddleware`. Users must re-run `kimi login` to obtain fresh credentials when tokens expire, as the flow prioritizes security over automatic background refresh in the current implementation.

### Is the temporary local callback server secure?

Yes, the temporary server implemented in [`src/kimi_cli/auth/oauth.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/auth/oauth.py) uses several security measures: it binds only to `localhost` (preventing external network access), uses a random ephemeral port, validates the `state` parameter to prevent CSRF attacks, and shuts down immediately after receiving the first callback. The server runs via `uvicorn` in a dedicated async context, ensuring the authorization code is captured only by the local CLI process and never exposed to external networks.