OAuth device flow is safe only when users can tell which device and request they are authorizing. The constrained client receives a secret device code for polling and a short user code for human entry. Keep those channels distinct, make codes hard to guess, rate-limit both endpoints, and show recognizable transaction details before approval. A QR code should accelerate navigation, not silently remove user confirmation.
Trace the two credentials
In the device authorization grant, the client requests authorization and receives a device_code, user_code, verification URI, expiry, and polling interval. The client keeps the device code and displays the user code and instructions. The user opens the verification page on another device, authenticates, enters or confirms the user code, and approves. Meanwhile the constrained client polls the token endpoint.
RFC 8628 defines this flow, including separate codes, polling responses, minimum polling intervals, and security considerations for user-code brute force and phishing. The device code is not meant for the user and needs enough entropy to resist guessing. The shorter user code needs server-side rate limiting, expiry, and attempt limits because usability constrains its length.
A common phishing attack begins when an attacker starts their own device flow and persuades a victim to enter the attacker’s user code. The victim authenticates correctly but authorizes the attacker’s session. TLS and a legitimate verification domain do not solve the confusion: the user must recognize what they are approving.
Put context at the confirmation point
After authentication and code entry, show the client name, requested access, tenant or account, approximate device type where known, and whether the request came from a CLI, television, or appliance. Require an explicit approve action. Do not rely on a generic “Success” page, and do not complete authorization before showing the context.
For a CLI, display a short phrase or nonce on both screens and ask the user to confirm they match. Do not treat IP address as a reliable identity signal, but a surprising location or device description can inform risk handling. For high-impact scopes, require stronger authentication or disallow device flow if the client cannot give enough transaction context.
QR codes can encode a complete verification URI to remove typing. They can also make the attacker’s transaction one tap away. The server should still display the user code or matching phrase and require confirmation after login. Never put the device code in a QR code exposed to the user; possession of that polling credential belongs to the initiating client.
Bound polling and token authority
Honor the issued interval and slow down when the server returns slow_down. Stop at expiry, denial, or success. Add jitter to large fleets so thousands of devices do not synchronize. The authorization server must rate-limit device authorization, verification attempts, and token polling independently, while avoiding error detail that helps enumerate valid codes.
Apply the broader protections in RFC 9700: narrow tokens to their intended audience and scopes, protect refresh credentials, and use sender-constrained or otherwise replay-resistant designs when the deployment supports them. Public device clients cannot safely keep a universal client secret. Treat each installation as untrusted and make issued authority no broader than the selected account and task.
Test confusion, not just completion
Run tests with two simultaneous device flows and deliberately swap their user codes. Try an expired code, repeated wrong codes, polling faster than allowed, a denied request, duplicate approval, and reuse after success. Verify that the confirmation page names the initiating client and that audit events connect user, client, grant, and result without logging codes or tokens.
Take one device login screen and add a matching phrase plus explicit client, tenant, and scope confirmation. Then run a user test where an attacker sends a legitimate verification link with their code. The flow succeeds only if the person notices and refuses the wrong transaction.
Sources are linked throughout this guide. Product capabilities can change; consult the linked documentation for your deployment.
Read our editorial approach ↗