diff --git a/Clients.md b/Clients.md index 1195676..aa87af1 100644 --- a/Clients.md +++ b/Clients.md @@ -257,6 +257,41 @@ RFC 6749 forbids refresh tokens for the client credentials flow, so when the tok re-runs the client credentials exchange (still no browser). This makes it suitable for CI, servers, and other non-interactive environments. +### Device Authorization Grant (Device Flow, RFC 8628) + +For CLIs and headless environments โ€” no browser callback required. Coyote displays a short +`user_code` and a `verification_uri`. You visit the URL on any device (your phone, another +computer, or the same browser Coyote tries to open) and enter the code to approve. Coyote +polls the token endpoint until you approve or the code expires. + +To enable, set `flow: device_code` in your `oauth:` block and provide a `device_authorization_url`: + + clients: + - type: openai-compatible + name: my-device-flow-provider + api_base: https://api.example.com/v1 + auth: oauth + oauth: + client_id: '{{MY_CLIENT_ID}}' + device_authorization_url: https://auth.example.com/oauth/device_authorization + token_url: https://auth.example.com/oauth/token + flow: device_code + +**Optional:** some providers require PKCE with device flow (per draft-ietf-oauth-device-flow ยง5.4). +Set `use_pkce_in_device_flow: true` to opt in โ€” Coyote generates a fresh `code_verifier` and +`code_challenge` (S256) on each authentication. + +Token refresh works the same as the Auth Code + PKCE flow: `refresh_token` is silently +exchanged for a new `access_token` when the current one expires. + +**Sandbox / headless environments:** when Coyote runs inside a sandbox (`coyote --sandbox`), +your host OAuth tokens (`~/.cache/coyote/oauth/`) are copied into the container so agents can +call OAuth-authenticated providers without re-authenticating. If you do need to authenticate +from inside a sandbox, Device Flow works out of the box โ€” Coyote prints a QR code you can +scan with your phone camera to visit the verification URL. Auth Code + PKCE flows (like xAI's) +generally cannot complete inside a sandbox because they require an inbound callback listener; +authenticate on the host first and let the token copy carry you through. + ### 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` @@ -273,6 +308,9 @@ To prevent accidental collisions, Coyote now rejects configuration files with du * 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)) +> Additional providers using Device Authorization Grant (RFC 8628) can be configured inline via +> `flow: device_code` in the `oauth:` block. See [Device Authorization Grant](#device-authorization-grant-device-flow-rfc-8628). + # Extra Settings Coyote also lets you customize some extra settings for interacting with APIs: