Authorization Basics

6 mins read

Authorization Code Flow With Proof Key of Code Exchange (PKCE)

Learn what an authorization code grant with the Proof Key of Code Exchange is and what its process is. Find out which applications can use the authorization code grant flow with PKCE safely and securely.

In a Nutshell

Authorization code grant with the Proof Key of Code Exchange (PKCE) is an extension of the standard authorization code grant OAuth flow. It is designed to be a secure substitute for the implicit flow for single-page applications (SPA) or native applications.

SPAs and native applications are vulnerable to reverse engineering practices. For SPAs, the source code of the application is available within browsers. Native apps can be decompiled. Because of those reasons, SPAs and native applications cannot securely store their client credentials (especially client secrets) and are considered public clients.

Authorization code grant with PKCE introduces a technique to prevent unauthorized access to resources in the case of code interception. And here’s how it works.

Flow in Depth

For proper and secure flow of authorization code grant with PKCE, the following is recommended:

  • Configure the redirection endpoint for the client application before making calls.

  • Limit the scope the client application can access when calling the /authorize and /token endpoints.

[mermaid-begin]
sequenceDiagram autoNumber participant User participant Client application participant Authorization server participant Resource server (API) activate User User->>Client application: Access activate Client application Client application->>Client application: Generate code_verifier and transform it to code_challenge activate Authorization server Client application->>Authorization server: Authorization code request + code_challenge to /authorize deactivate Client application Authorization server->>User:Display consent User->>Authorization server: Authenticate and give consent deactivate User Authorization server->>Client application: Issue authorization code activate Client application Client application->>Authorization server: Authorization code + code_verifier to /token Authorization server->>Authorization server: Verify the authorization code, code_verifier, and code_challenge Authorization server->>Client application: Return token deactivate Authorization server Client application->>Resource server (API): Call API with token activate Resource server (API) Resource server (API)->>Client application: Return data deactivate Resource server (API) deactivate Client application

The example diagram above illustrates the interactions that occur during the OAuth authorization code grant flow with PKCE.

  1. A user tries to access the client application.

  2. The client application generates code_verifier and transforms it into code_challenge.

    • code_verifier is a random key that prevents the authorization code from being intercepted. code_verifier is generated by the client application for every authorization request and transformed into code_challenge according to the code_challenge_method set for the client application in advance. It’s mandatory to set the code_challenge_method value to S256, where possible.
  3. The client application calls the authorization server’s authorize endpoint and sends the code challenge along with the authorization request.

    • At least one redirection URI must be configured for the client application. When the application features several redirection URIs, the request to the authorize endpoint must always include the redirect_uri parameter.

    Sample call to the authorize endpoint with Cloudentity as an authorization server

    curl --location \
    --get \
    --url "https://$TENANT_ID.$REGION_ID.authz.cloudentity.io/$TENANT_ID/$WORKSPACE_ID/oauth2/authorize" \
    --data-urlencode "response_type=code" \
    --data-urlencode "redirect_uri=$REDIRECT_URI" \
    --data-urlencode "client_id=$CLIENT_ID" \
    --data-urlencode "code_challenge=$CODE_CHALLENGE" \
    --data-urlencode "code_challenge_method=$CODE_CHALLENGE_METHOD"
    

    Region identifier

    REGION_ID is available for recently created tenants in the tenant URL next to TENANT_ID. The region IDs are assigned as follows:

    • Australia: au

    • Europe: eu

    • USA: us

    For tenants without the region identifier, the REGION_ID parameter must be skipped.

    • Along with the request, the client application sends code_challenge and code_challenge_method.
  4. The authorization server responds with the redirect URI. The user gets redirected to the consent form, if any.

  5. The user authenticates with their identity source and gives their consent.

  6. The authorization server issues an authorization code.

  7. The client application requests authentication to the token endpoint using the authorization code provided in the previous step.

    • The requests to the authorization server must also include the code_challenge with value equal to that sent in the request to the authorize endpoint. This is one of the mandatory requirements of a successful token issue.

    Sample call to the token endpoint with Cloudentity as an authorization server

    curl --request POST \
    --url "https://$TENANT_ID.$REGION_ID.authz.cloudentity.io/$TENANT_ID/$WORKSPACE_ID/oauth2/token" \
    --data-raw "authorization_code=$CODE&code_verifier=$CODE_VERIFIER"
    
  8. The authorization server validates the authorization code, code_verifier, and code_challenge.

    Upon the following:

    • The authorization code is valid

    AND

    • The code_verifier and code_challenge values sent in steps 3 and 7 are equal (pairwise), then
  9. The authorization server returns the token.

  10. The client application requests protected resources from the resource server and submits the token it received in the previous step.

  11. The resource server validates the token and responds with the requested resources.

Cloudentity as Authorization Server

Cloudentity provides application and security teams with a better way to automate and control how information is shared over APIs. As part of our services, we support authorization code grant with PKCE.

This section covers the essential steps to try the authorization code grant with PKCE for applications created with Cloudentity.

In case you need more intro information, take a look at the Quickstart section. It will guide you through the key concepts Cloudentity offers. Take in the fundamentals of access management, find out the conditions of compliance with open banking, and discover how Cloudentity APIs can make your life easier.

Launch a free tenant and use the Demo workspace to explore the authorization code flow with PKCE. To add users, connect a Sandbox IDP (for testing purposes) or any of IDPs from the wide range of supported by Cloudentity. Alternatively, you can connect the Cloudentity Identity Pools IDP, when you haven’t any preferred ones. Then try the authorization code flow with PKCE to see how the flow goes.

To activate the PKCE extension for the authorization code grant, enforce PKCE for your client application.

Read More

To learn more about this authentication method, see the Client authentication set to none and with the use of PKCE article.

You can set up dynamic scopes for your application, from coarse- to fine-grained. Upon scope modifications, configure the user consent form based on your changes.

Cloudentity Auth JS

Cloudentity-auth-js is a library that provides you with a client that makes it possible for JavaScript single-page applications to use the authorization code grant flow with PKCE. To make use of the library, see the cloudentity-auth-js library dedicated GitHub repository.

More in Cloudentity

Cloudentity supports other grant types as well. So when the authorization code grant with PKCE isn’t suitable for your use case, you can select another type based on your needs.

For example, use the PAR extension when you need to comply with FAPI advanced requirements—according to Consumer Data Right, Open Banking, or Open Insurance Brazil.

To ensure a secure browserless device authorization, use the Device Flow.

You can find more info about oauth grant types in our article, namely, what grant types are available in Cloudentity, and choose the type that meets your case.

Updated: May 15, 2023