3 Powerful Extensions to Get the Most Out of OAuth 2.0

Posted in

OAuth 2.0 is the golden standard for securing access to APIs. With four well-defined authorization flows or grant types included in the original OAuth 2.0 RFC, OAuth’s functionality is more than adequate for a wide range of use cases and devices.

However, as Michał Trojanowski explains in his talk from the 2019 Platform Summit, a changing tech landscape has created the need for new authorization functionalities. In this post, we’ll look at three powerful additions to the original OAuth 2.0 specification, including the Device Code grant type, the Token Exchange grant type, and the Proof Key for Code Exchange extension, as explained by Michał himself.

Watch Michał Trojanowski describe how to extend OAuth:

1. Device Code Grant Type

In the original OAuth 2.0 Authorization Code grant type, the client initializes the authorization flow through a user-agent, such as a browser. An authorization code is then sent back to the client using a redirect URI in the browser, which the client can then exchange for an access token.

However, Michał explains that if the device has no access to a browser (as is the case for many IoT devices) or has limited input capabilities (like a television), this flow is less than ideal.

Enter the Device Code grant type. This proposed authorization flow is designed especially for browserless or input-constrained devices. It involves the use of two separate devices: one which is asking for authorization, and another on which authorization is actually granted.

As an example of this, Michał describes a user logging into a YouTube application on a television through their mobile phone. The flow is relatively straightforward: the client (in this case, the television) initiates the authorization flow by sending a POST request to the authorization server:

POST /device_authorization
Content-Type: application/w-xxx-form-urlencoded

In the response, the authorization server sends back a device_code, user_code, and verification_uri. The client presents the user code and verification URI to the user, who must browse to the URI and enter the code on their mobile phone.

In the meantime, the client begins polling the authorization server with the device code, asking whether the user has yet authorized the application. At first, the server will respond with a 400 error, indicating that the authorization is still pending. Eventually, though, once the user authorizes on their mobile phone, the server will respond with an access token!

2. Token Exchange Grant Type

The Token Exchange grant type is a draft protocol that allows one user to act on behalf of another. In some cases, this might be an admin account acting on behalf of a regular user; in other cases, this might be sub-accounts acting on behalf of a main account.

This grant type adds at least two new parameters: subject_token — the token of the user in question — and subject_token_type. While these parameters are enough to impersonate a user (meaning that the resource server will not know one user is acting on behalf of another), the grant type also supports explicit delegation of tokens, which additionally requires the actor_token and actor_token_type parameters.

Michał adds that the Token Exchange specification adds four new claims to JSON Web Tokens (JWT), which help identify users who are exchanging tokens:

  • act : This claim contains a list of claims, such as sub and iss, that identify which user initiated the token exchange
  • scope: This claim contains a list of scopes that limits what the user can do on behalf of the other user.
  • client_id: This claim contains the ID of the client which initiated the Token Exchange request.
  • may_act: This claim contains a list of claims that identifies which users can initiate a Token Exchange request.

3. Proof Key for Code Exchange Extension (PKCE)

Proof Key for Code Exchange (PKCE) is a security extension for the original OAuth 2.0 Authorization Code grant type. PKCE, pronounced pronounced “pixy,” is for clients with their entire codebase accessible to users — like Single-Page Applications (SPAs) and many mobile or desktop apps — where access tokens might otherwise be intercepted. Michał notes that, originally, the Implicit grant type was used for these situations; however, its’ use here is discouraged due to security reasons.

The Proof Key for Code Exchange extension is relatively straightforward. It adds two pieces of information to the request that initiates the authorization flow: a transformed code verifier, and the method used to transform it. Later, when the client goes to exchange the authorization code for an access token, the extension adds the original code verifier to the request. Before issuing an access token, the authorization server uses the transformation method to check whether the original code verifier corresponds to the transformed code verifier — in other words, to ensure that the same client is requesting an access token.

Final Thoughts

The original OAuth 2.0 is a powerful standard, but new flows and extensions like these continue to evolve the security and convenience of authorization. The three extensions discussed in this article allow for authorization on constrained devices, a transparent token delegation from one user to another, and secure authorization on public clients.

As always, if you want to learn more about these extensions, Michał suggests diving into the official RFCs: