diff --git a/Clients.md b/Clients.md index 866f5a4..035300d 100644 --- a/Clients.md +++ b/Clients.md @@ -176,6 +176,85 @@ Simply click the `Advanced` link and click `Go to Coyote (unsafe)` to continue t ![](./images/clients/gemini-oauth-unverified.png) ![](./images/clients/gemini-oauth-unverified-allow.png) +### xAI OAuth Note + +xAI OAuth requires a **SuperGrok** or **X Premium+** subscription. Coyote ships with the required OAuth endpoints and +client ID bundled in `models.yaml`, so you can enable OAuth by just adding `auth: oauth` to your xAI client entry — no +additional endpoints or app registration needed. + +When authenticating, Coyote starts a localhost server on port **56121** to capture the OAuth callback automatically. +This port matches what xAI's OAuth app expects and cannot be changed. Make sure port 56121 is available when you run +`--authenticate`/`.authenticate`. + +If the authorization succeeds but the token exchange returns 403, that indicates your account does not have a valid +SuperGrok / X Premium+ subscription — not a Coyote configuration error. + +Example configuration: + +```yaml +clients: + - type: openai-compatible + name: xai + api_base: https://api.x.ai/v1 + auth: oauth +``` + +### OAuth for OpenAI-Compatible Providers + +For any provider that speaks the OpenAI API shape, you can enable OAuth on an `openai-compatible` client. Coyote resolves +OAuth configuration in two layers: + +1. **Bundled defaults** in `models.yaml` under `provider: ` (Coyote ships defaults for providers like xAI). +2. **Inline overrides** in your `config.yaml` under `clients[i].oauth` — you can either supply the whole block (for + providers not shipped with Coyote) or override individual fields (e.g. to point at a corporate token endpoint). + +For each optional field, the user's `config.yaml` value wins over the `models.yaml` default. If neither source provides +a required field (`client_id`, `token_url`), Coyote will bail with a clear error when you attempt to authenticate. + +**Example — inline OAuth for a private gateway:** + +```yaml +clients: + - type: openai-compatible + name: acme-gateway + api_base: https://gateway.acme.com/v1 + auth: oauth + oauth: + client_id: '{{ACME_CLIENT_ID}}' + client_secret: '{{ACME_CLIENT_SECRET}}' + token_url: https://auth.acme.com/oauth/token + scopes: [openai.chat] + flow: client_credentials +``` + +### Providers with Bundled OAuth Defaults + +Coyote ships OAuth defaults for the following providers, so you only need `auth: oauth` in your config: + +* **xAI** — SuperGrok / X Premium+ subscribers + +To bundle defaults for additional providers locally, edit your `models.yaml` (see [Local Models Override](#local-models-override)) +and add an `oauth:` block under the provider entry. + +### client_credentials Flow + +For headless machine-to-machine (M2M) authentication — no browser, no user interaction — set `flow: client_credentials` +in your `oauth` block. Coyote will POST directly to the token endpoint with `client_id` and `client_secret` and cache +the returned access token. + +RFC 6749 §4.4.3 forbids refresh tokens for the client credentials flow, so when the token expires Coyote silently +re-runs the client credentials exchange (still no browser). This makes it suitable for CI, servers, and other +non-interactive environments. + +### Known Limitation: Token Namespacing + +OAuth tokens are stored on disk at `~/.cache/coyote/oauth/{client_name}_oauth_tokens.json`, keyed by the client's `name` +field only (not by provider type). Two clients with the same `name` — even if they use different provider types — will +overwrite each other's tokens. + +To prevent accidental collisions, Coyote now rejects configuration files with duplicate `name` values across all +`clients[]` entries at load time. Fixing the underlying single-namespace layout is future work. + **Step 3: Use normally** Once authenticated, the client works like any other. Coyote uses the stored OAuth tokens automatically: @@ -191,6 +270,8 @@ coyote -m my-claude-oauth:claude-sonnet-4-20250514 "Hello!" * Claude * Gemini * OpenAI (requires ChatGPT Plus or Pro subscription) +* xAI (requires SuperGrok or X Premium+ subscription; configured via `type: openai-compatible`) +* Any OpenAI-compatible provider via an inline `oauth:` block (see [OAuth for OpenAI-Compatible Providers](#oauth-for-openai-compatible-providers)) # Extra Settings Coyote also lets you customize some extra settings for interacting with APIs: