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 yourverificationUri. 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)
/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
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 opensverification_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 formatXXXX-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
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.