Configuring Proof Key for Code Exchange

On this page

This tutorial explains how to use Proof Key for Code Exchange (PKCE) with a code flow client. To learn how PKCE works read Understanding Proof Key for Code Exchange.

In short we will add an extra parameter that will protect the authorization redirect from beeing hijacked and the authorization code from being stolen.


This tutorial builds on the configuration setup described in the steps First Configuration and Configure an Authenticator under the menu Getting Started. If you have not gone through those steps yet, you can visit the guides by clicking on the links.

You may run this tutorial on a custom setup also, but keep in mind that names and URLs may be different, as well as the capabilities configured in the profiles.

You will also need a client that can provide access tokens and refresh tokens. If you follow the code flow tutorial, you will have obtained both.

Implementing PKCE in Curity

Using PKCE in Curity is very simple. It is automatically enabled for any client that has the code flow enabled.

While it is not possible to disable PKCE (thus making that client less secure), it is possible to require it (making it more secure).

Setup in Curity

Visit the Profiles screen and click the Token Service.

Click the Clients page and select a client to work with.

Code Flow Capability

To setup required PKCE for a client it needs to have the code flow enabled:

Admin UI showing a client with code flow enabled

Toggle Require PKCE

  1. Navigate to the Client Application Settings section of a client for which you would like to require PKCE.
  2. Expand the Advanced settings section.
  3. Toggle on Require Proof Key.
  4. Optionally and recommended, disallow the client from using the plain proof key challenge method.
Requiring a client to use a proof key for code exchange in the Admin UI

Aside from this, there is nothing more to configure in Curity. Setting up PKCE is that easy :-)

Making requests

To make a PKCE request with the www client that was setup in earlier examples, we need a random proof-key and a verifier. The pseudo code in the Proof Key Overview explains how to obtain these. It's important that they are random for each request.

Here's an example:

  • Code: lszjpzkvqqxuiccquvorhgnxhdmiaholczxqcckotnqkgprymuwhwwutetfd
  • Hashed Code (s256): ps-K7a0ngt1HwZ7N9bK6XyUUJWpcUAkTfetTuZA2qak=

We send the Hashed Code in the authorize request, and the Code in the token request to verify the Hashed Code. So the first part of the code flow needs to include the code_challenge and the code_challenge_method=S256 :


This will now require the backend call to provide the code_verifier or an error will be returned

curl -X POST \
https://localhost:8443/oauth/v2/oauth-token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&client_id=www&client_secret=THE_SECRET&code=sE7mpQHlr3Dv19ZNWeO7RnzPOL5lJTEt&code_verifier=lszjpzkvqqxuiccquvorhgnxhdmiaholczxqcckotnqkgprymuwhwwutetfd'

If the wrong verifier is sent, or the verifier is omitted, no tokens will be issued.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial