docs: OAuth for openai-compatible providers (xAI, generic gateways)

2026-07-20 13:10:03 -06:00
parent 4eacfb97a7
commit 9e1fb33729
+81
@@ -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: <name>` (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: