Skip to main content
The device authorization grant (RFC 8628) lets a device that cannot show a browser, a CLI tool, smart TV, game console, or IoT sensor, authenticate by delegating the sign-in step to a secondary device the user already trusts. The device displays a short code like BDFK-RSTV. The user opens a URL on their phone or laptop, signs in, types the code, and the waiting device gets a session. No credentials ever travel through the constrained device.

Setup

1

Add the plugin

lib/kavach.ts
2

Build the user-facing approval page

Create a page at your verificationUri. It should let a signed-in user enter the code the device is showing and approve or deny the request.
app/device/page.tsx (Next.js)
The /auth/device/authorize endpoint requires an active session. The user must be signed in before they can approve or deny a device code.

Device flow

1

Request codes (on the device)

POST /auth/device/codeThe device calls this endpoint to start a new authorization attempt. No authentication required.
CLI tool
Display user_code prominently, this is what the user types. verification_uri_complete includes the code as a query parameter, so you can also show a QR code for it.
2

Poll for authorization (on the device)

POST /auth/device/tokenPoll this endpoint at the interval returned in the previous step (default: every 5 seconds). Keep polling until you get an authorized response or the code expires.
CLI tool
3

User approves (on the secondary device)

The user opens verification_uri on their phone or laptop, signs in, and enters the code. The approval page calls /auth/device/authorize with the user code and action: 'approve'. The next poll from the device returns { authorized: true, user_id: '...' }.

User code format

User codes use the format XXXX-XXXX, two four-character segments separated by a hyphen. The character set is consonants only (BCDFGHJKLMNPQRSTVWXZ), which avoids:
  • Visually ambiguous characters (no 0/O, 1/I, 5/S)
  • Characters that read awkwardly when pronounced aloud
The alphabet and segment length are fixed. The codeLength option controls the length of each segment (default: 4). Input on the approval page is case-insensitive and whitespace-tolerant, bdfk rstv, BDFK-RSTV, and BDFKRSTV all resolve to the same grant.

Polling interval and slow-down

The initial interval is returned by the /auth/device/code endpoint (default: 5 seconds). The server enforces a minimum gap between polls. If the device polls too quickly, the response includes error: 'slow_down' and an updated interval value. The device must use the new interval for all subsequent polls.
Polling too frequently will trigger slow_down responses. Use the interval from the initial response as your starting poll delay, and always update it when you receive slow_down.

Endpoints

/auth/device/code response

/auth/device/token error codes

Configuration reference

Last modified on April 20, 2026