OAuth 2.0 — Device Authorization Grant
The Device Authorization Grant (RFC 8628) solves authorization for input-constrained devices like CLIs, smart TVs, media boxes, and IoT sensors that cannot open a browser or receive redirects. The device obtains a user code and verification URI from the AS, displays them to the user, and polls for a token while the user authorizes on a separate device (phone or laptop).
The device requests a device code from the AS's device authorization endpoint. The AS returns a device_code (for polling), a user_code (for the user to type), and a verification_uri (where the user goes on their separate device). No user interaction has occurred yet.
• RFC 8628 §3.1: The device authorization endpoint is a separate endpoint from the token endpoint.
• RFC 8628 §6.1: user_code entropy should resist brute-force for the duration of the code's lifetime (typically 15–30 minutes).
• Public clients (no client_secret) are supported — the client_id alone is sufficient to initiate the flow.
• The device_code and user_code are bound together on the AS — when the user approves via the user_code, the AS marks the corresponding device_code as authorized.
Step 1: POST /device_authorization
application/x-www-form-urlencoded
client_id=s6BhdRkqt3&scope=read:profile+media:stream+playlists:write
Construction Steps
device_code = "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS" This is a high-entropy opaque value. The device sends it on every polling request to identify which authorization session it is waiting for. It MUST be kept confidential — never shown to the user. Expires in 1800 seconds (30 minutes).
user_code = "WDJB-MJHT" RFC 8628 §6.1: The user_code SHOULD have high entropy but MUST be short enough to type on a constrained device (TV remote, game controller). The AS SHOULD display it in a way that is easy to distinguish (hyphens, uppercase, no ambiguous chars like 0/O or 1/l/I). This code is what the user types on their phone/laptop. It corresponds to the device_code on the AS side.
verification_uri = "https://auth.example.com/activate" verification_uri_complete = "https://auth.example.com/activate?user_code=WDJB-MJHT" The device SHOULD display both: • The short URI + user_code (for typing on TV) • A QR code encoding verification_uri_complete (for scanning) verification_uri_complete pre-fills the user_code so the user can skip the manual entry step.
expires_in = 1800 (seconds until device_code expires) interval = 5 (minimum seconds between polling attempts) The device MUST NOT poll more frequently than once per interval seconds. If it polls too fast the AS returns error=slow_down and the device must increase its interval by 5 seconds.
Signature Base String
client_id=s6BhdRkqt3&scope=read:profile+media:stream+playlists:write
Signing Key
No user interaction at this step — device initiates the flowSignature Output
device_code (secret), user_code (short, human-typeable), verification_uri