Illustrated Device Flow (RFC 8628)

Takahiko Kawasaki
10 min readApr 13, 2020

--

This article explains RFC 8628 (OAuth 2.0 Device Authorization Grant), a.k.a. “Device Flow”.

Device Flow is another way to issue an access token as well as the flows defined in RFC 6749 (The OAuth 2.0 Authorization Framework).

The reason for developing the new flow is described at the top of the specification as follows.

The OAuth 2.0 device authorization grant is designed for Internet-connected devices that either lack a browser to perform a user-agent-based authorization or are input constrained to the extent that requiring the user to input text in order to authenticate during the authorization flow is impractical.

Let’s start learning the device flow.

1. Device Flow

(1) There is a device. A typical example is a smart TV. A client application runs on the device.

(2) Prepare an authorization server.

(3) An authorization server that supports the device flow has a device authorization endpoint.

(4) A client application sends a request to the endpoint.

The specification about the request is described in “3.1. Device Authorization Request”. Request parameters are as follows.

  • client_id — Required. Client ID.
  • scope — Optional. Scopes.

The following is an example of the device authorization request shown in the specification.

POST /device_authorization HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

client_id=1406020730&scope=example_scope

(5) The endpoint returns a response.

The specification about the response is described in “3.2. Device Authorization Response”. Response parameters are as follows.

  • device_code — Required. Device code (device verification code).
  • user_code — Required. User code (end-user verification code).
  • verification_uri — Required. End-user verification URI.
  • verification_uri_complete — Optional. End-user verification URI including a user code.
  • expires_in — Required. Lifetime in seconds of the device code and the user code.
  • interval — Optional. The minimum amount of time in seconds between polling requests to the token endpoint.

The following is an example of the device authorization response shown in the specification.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
"user_code": "WDJB-MJHT",
"verification_uri": "https://example.com/device",
"verification_uri_complete":
"https://example.com/device?user_code=WDJB-MJHT",
"expires_in": 1800,
"interval": 5
}

It should be noted that a user code (end-user verification code) and a device code (device verification code) are issued. They will be used in a request to an end-user verification endpoint and a token request, which will be explained later.

(6) The client application displays the values of verification_uri and user_code which are contained in the device authorization response.

(7) For end-users’ convenience, typical implementations additionally show a QR code that represents the value of verification_uri, or verification_uri_complete if one is included in the device authorization response.

(8) verification_uri represents the URI of the end-user verification endpoint of the authorization server.

verification_uri_complete also represents the URI of the end-user verification endpoint, but it contains a user code as a part of the path or a query parameter, too. Please refer to the example in the step (5).

(9) The end-user prepares a web browser. In typical cases, it is a web browser on a PC or a smartphone.

(10) The end-user accesses the device verification endpoint using the web browser.

(11) The device verification endpoint returns an HTML page for user authentication and getting a user code.

(12) The end-user inputs required values and sends them to the server.

(13) The authorization server authenticates the end-user and verifies the user code.

(14) The authorization server returns a page to get consent from the end-user. Implementations may omit this step by integrating it into the previous step.

(15) The end-user selects approval or disapproval and sends the decision to the server.

(16) The authorization server processes the decision and returns the result.

(17) Meanwhile, after receiving the response from the device authorization endpoint, the client application repeats token requests until it gets the final result.

The specification about the token request is described in “3.4. Device Access Token Request”. Request parameters are as follows.

  • grant_type — Required. The fixed string, urn:ietf:params:oauth:grant-type:device_code.
  • device_code — Required. The device code.
  • client_id — Client ID.

The following is an example of token request shown in the specification.

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
&client_id=1406020730

The value of the grant_type request parameter is urn:ietf:params:oauth:grant-type:device_code and this indicates that the token request is for the device flow. A token request for the device flow must include the device_code request parameter whose value is the value of the device_code response parameter in the device authorization response.

(18) A token response is returned.

Even if the token response indicates an error, the client application repeats token requests while the error code is either authorization_pending or slow_down. The token endpoint continues to return either the authorization_pending error or the slow_down error until the decision of (dis)approval in the step (16) is processed or the device code expires.

When receiving a successful response or an error code other than authorization_pending or slow_down, the client application stops making token requests and the device flow finishes there.

(Summary)

2. User Code

If a means that simplifies the input method such as QR code is not provided, end-users have to input a user code manually. Therefore, user codes should not be too long while securing entropy to some extent and should avoid containing characters that are easily confused with each other, like 0 (zero) and O (capital letter “O”). “6.1. User Code Recommendations” lists recommendations for the user code like these.

The first example of character set for user codes listed in the section consists of 20 characters, BCDFGHJKLMNPQRSTVWXZ. This is the result of removing vowels (AEIOUY) from the alphabet 26 characters. The character set is case-insensitive, and including punctuation such as dashes is allowed for readability while such punctuation should be ignored when user codes are compared for verification. The specification shows WDJB-MJHT as an example of user code that uses the character set.

The second example consists of 10 characters, 0123456789. This is the character set that simply consists of digits only. The specification shows 019-450-730 as an example.

3. Device Flow Implementation

This section introduces the device flow implementation of Authlete.

Authlete supports the device flow since the version 2.1. As the version of the shared server (api.authlete.com) was updated to 2.1 in February, 2020, developers can try the device flow using the shared server without contract for a dedicated server.

3.1. Service Configuration

A new tab, “Device Flow”, has been added to the service management console. To use the device flow, the fields in the tab need to be set up.

  • Device Authorization Endpoint — The URL of the device authorization endpoint. This property corresponds to the device_authorization_endpoint metadata defined in OAuth 2.0 Device Authorization Grant (Device Flow). The value must consist of only ASCII characters and its length must not exceed 200. The scheme part must be https. This property is used as the value of device_authorization_endpoint in the response from the discovery endpoint. Also, if a JWT-based client authentication method (client_secret_jwt or private_key_jwt) is used, the aud claim in the client assertion (client_assertion) is compared to the value of this property.
  • Verification URI — The verification URI. This property is used as the value of the verification_uri parameter in responses from the device authorization endpoint. The value must consist of only ASCII characters and its length must not exceed 200. The scheme part must be https. This property must be set in advance to use Device Flow. Otherwise, an error is returned when /api/device/authorization API is called.
  • Verification URI with Placeholder — The verification URI with a placeholder for a user code. The value must consist of only ASCII characters and its length must not exceed 200. The scheme part must be https. If this property is set and its value includes a fixed string USER_CODE (e.g. https://example.com/verification?user_code=USER_CODE), it is used to generate the value of the verification_uri_complete parameter in responses from the device authorization endpoint. Authlete replaces the fixed string with an actual user code. If the value of this property is not set or does not include the fixed string, the verification_uri_complete parameter will not be embedded in responses from the device authorization endpoint.
  • Verification Code Duration — The duration of device verification codes (device_code) and end-user verification codes (user_code) in seconds. The value is used as the value of the expires_in parameter in responses from the device authorization endpoint. A positive number must be set to this property in advance to use Device Flow. Otherwise, an error is returned when /api/device/authorization API is called.
  • Polling Interval — The minimum interval between polling requests to the token endpoint in seconds. The value must be between 0 to 65,535. The value is used as the value of the interval parameter in responses from the device authorization endpoint unless it is zero.
  • User Code Character Set — The character set for user codes (user_code). If BASE20 is selected, user codes will consist of BCDFGHJKLMNPQRSTVWXZ (20 upper-case non-vowel characters) (e.g. WDJBMJHT). If NUMERIC is selected, 0123456789 are used (e.g. 019450730). If this property is not set, BASE20 is used as the default value. Note that user codes generated by Authlete do not include dashes and other punctuation.
  • User Code Length — The length of user codes (user_code). The value must be between 0 to 255. If the value is 0, the length of user codes will be 8 in the case of the character set BASE20 (the entropy is 20^8) and 9 in the case of the character set NUMERIC (the entropy is 10^9). The value of this property affects the entropy of user codes directly. Too small values would cause DB errors frequently due to the UNIQUE constraint. Too big values would demotivate end-users from inputting user codes. Therefore, don't set an extreme value.

In addition, DEVICE_CODE in the list of “Supported Grant Types” in the “Authorization” tab needs to be checked.

3.2. Client Configuration

Please check DEVICE_CODE in the list of “Grant Types” in the “Authorization” tab in the client management console, too.

3.3. Authorization Server

java-oauth-server, an open-source authorization server, has implementations of the device authorization endpoint and the end-user verification endpoint. Their paths are /api/device/authorization and /api/device/verification, respectively. Download it and try the device flow.

3.4. Authlete API

The following APIs have been added to Authlete to support the device flow.

  • /api/device/authorization — processes device authorization requests.
  • /api/device/complete — processes the (dis)approval by end-users.
  • /api/device/verification — verifies user codes and returns information.

The relationship between an authorization server and the Authlete APIs are as follows.

For details about the specification of the APIs, please refer to descriptions of Device* classes in the JavaDoc of the authlete-java-common library.

3.5. Good Points of Authlete’s Device Flow Implementation

Authlete’s good points compared to ordinary implementations are as follows.

  1. The device authorization endpoint supports the resource parameter which is defined in RFC 8707 (Resource Indicators for OAuth 2.0).
  2. The device authorization endpoint supports the authorization_details parameter which is defined in RAR (Rich Authorization Requests for OAuth 2.0).
  3. The device authorization endpoint supports client authentication methods that are defined in RFC 7523 (JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants) and RFC 8705 (OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens).
  4. There are no restrictions on implementations of the end-user verification endpoint. Especially, developers can adopt any user authentication method and any structure for the HTML page.
  5. When openid is included in the scope parameter, an ID token is issued in addition to an access token. This behavior is a relatively big extension for RFC 8628, but there already exist such implementations (e.g. Microsoft) and demand for the feature from the market is strong.
  6. For ID tokens, the device authorization endpoint additionally supports the acr_values parameter, which follows the acr_values parameter of the backchannel authentication request of CIBA (Client Initiated Backchannel Authentication).

Finally

Authlete is a certified implementation that supports OAuth 2.0, OpenID Connect, Financial-grade API, CIBA, and other specifications (Spec Sheet). And now, Authlete supports RFC 8628, the device flow. Please enjoy new specifications with Authlete!

--

--

Takahiko Kawasaki

Co-founder and representative director of Authlete, Inc., working as a software engineer since 1997. https://www.authlete.com/