---
schema_version: "1"
id: ba530da99c4ce9ba78b9851021cdb3605120fdad10f3177d92ee594167fe9e72
title: Proof Key for Code Exchange (PKCE) Extension
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_pkce.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_pkce.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 7835cc3f15953d800cd9e1eb671d3f04b97165c2b3027347c1ccf695a6e26e7f
description: To improve the security of your OAuth and authentication provider implementations, use the OAuth 2.0 Proof Key for Code Exchange (PKCE) extension. You can require PKCE at an org-wide level, require it for a specific connected app, and automatically enable it for supported authentication providers.
products:
  - Security
  - Cross Cloud
release: "264"
---
# Proof Key for Code Exchange (PKCE) Extension

To improve the security of your OAuth and authentication provider implementations, use the OAuth 2.0 Proof Key for Code Exchange (PKCE) extension. You can require PKCE at an org-wide level, require it for a specific connected app, and automatically enable it for supported authentication providers.

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition"><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: all editions</td></tr></tbody></table>

During the OAuth authorization code flow and its derivatives, the PKCE extension helps ensure that the client that initiates the flow is the same client that completes the flow. During these flows, an app requests an authorization code from Salesforce, which it then exchanges for an access token. Traditionally, the app can secure the token request by including its connected app consumer secret. Because the consumer secret is information that only the app and Salesforce know, it functions as a password for accessing the Salesforce token endpoint. Even if an attacker somehow gains access to an authorization code, they can’t use it to get an access token unless they have the consumer secret.

But public clients like mobile apps and single-page apps can’t keep the consumer secret confidential. Unlike private client apps with a traditional client-server architecture, public clients don’t have a private backend where they can store the consumer secret. If a public client sends the consumer secret in the token request, it risks leaking it. For this reason, we never recommend including the consumer secret in token requests for a public client.

With no consumer secret, the app is vulnerable to an attacker intercepting the authorization code and attempting to exchange it for an access token. PKCE helps fill the consumer secret gap with a set of hashed parameters that only your app and Salesforce can understand. During a flow that implements PKCE, the app creates a random string, known as the `code_verifier` parameter. It then hashes this value with an SHA-256 algorithm. This hashed value is the `code_challenge` parameter. A key concept of SHA-256 hashing is that it only works one way. You can get the `code_challenge` from the `code_verifier` by running the SHA-256 algorithm. But you can’t run it backwards to get the `code_verifier` from the `code_challenge`.

The concept of a one-way function plays an important role in why PKCE works. When the app sends its initial request for an authorization code, it includes the hashed `code_challenge` parameter. Then, when it requests an access token, it includes the `code_verifier` parameter. Now, Salesforce has both parameters, and it can run the SHA-256 algorithm on the `code_verifier` value to compare it to the `code_challenge`. If the values match, Salesforce can verify that the same app sent the authorization request and the token request. Even if an attacker has the authorization code, they can’t exchange it for an access token because they don’t have the PKCE parameters that only your app and Salesforce know.

We recommend that you always implement PKCE for public clients. For private clients, we recommend that you implement PKCE and include the consumer secret in token requests.

You can optionally implement PKCE by including `code_challenge` and `code_verifier` parameters when you build variations of the authorization code flow with Salesforce. These flows support PKCE.

- [Web server flow](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&type=5&language=en_US)
- [Hybrid web server flow](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_hybrid_web_server_flow.htm&type=5&language=en_US)
- All variations of the Authorization Code and Credentials Flow, including headless registration, headless passwordless login, and headless guest flows. See [Headless Identity Flows](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_headless_identity_pointer.htm&type=5&language=en_US).

To ensure that PKCE is enforced, we recommend that you take these security measures.

- [Require PKCE at an org-wide level](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_disable_username_password_flow.htm&type=5&language=en_US) from the OAuth and OpenID Connect settings page. With this setting enabled, all authorization code flow variations that don’t use PKCE are automatically blocked.
- [Require PKCE for specific connected apps](https://help.salesforce.com/s/articleView?id=xcloud.connected_app_create_api_integration.htm&type=5&language=en_US). As a connected app developer, if you enable this setting, you must implement PKCE when you build authorization flows with this app.
- Use PKCE for an authentication provider. For supported authentication providers, you can automatically use PKCE by selecting a single setting. These authentication providers support PKCE.
    - [Facebook](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_facebook.htm&type=5&language=en_US)
    - [Google](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_google.htm&type=5&language=en_US)
    - [Microsoft](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_microsoft_only.htm&type=5&language=en_US)
    - [Open ID Connect](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_openid_connect.htm&type=5&language=en_US)
    - [Salesforce](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_sfdc.htm&type=5&language=en_US)
    - [Custom authentication providers](https://help.salesforce.com/s/articleView?id=xcloud.sso_provider_plugin_custom.htm&type=5&language=en_US)

## Generate PKCE Parameters

Use the PKCE Generator endpoint to quickly generate `code_challenge` and `code_verifier` parameters that you can implement in variations of the authorization code flow.

1. [Enable Cross-Origin Resource Sharing (CORS) for OAuth endpoints](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_endpoints_cors.htm&type=5&language=en_US), which automatically enables CORS for the `/services/oauth2/pkce/generator` endpoint.
2. To generate the `code_challenge` and `code_verifier` parameters, send an HTTP GET request to the `/services/oauth2/pkce/generator` endpoint on your My Domain login URL or Experience Cloud site URL. Don’t include any headers or body parameters in this request.
    
    Here’s an example request that uses a My Domain login URL.
    
    ```
    GET /services/oauth2/pkce/generator? HTTP 1.1
    Host: MyDomainName.my.site.salesforce.com
    ```
    
    Here’s an example request that uses an Experience Cloud site URL.
    
    ```
    GET /services/oauth2/pkce/generator? HTTP 1.1
    Host: MyDomainName.my.site.com
    ```
    
    Salesforce responds with these PKCE parameters. <table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
                <colgroup>
                  <col style="width:50%">
                  <col style="width:50%">
                </colgroup>
                <thead class="slds-text-title_caps ">
                  <tr class="">
                    <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d89410e241">Parameter</th>
                    <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d89410e243">Description</th>
                  </tr>
                </thead>
                <tbody>
                  <tr class="">
                    <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e241 "><code>code_challenge_method</code></td>
                    <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e243 ">The method used to compute the <code>code_challenge</code>
                      from the <code>code_verifier</code>. Salesforce uses the <code>S256</code> method, which computes the <code>code_challenge</code> from the <code>code_verifier</code>
                      using an SHA256 algorithm. For more information, see Section 4.2 in <a href="https://datatracker.ietf.org/doc/html/rfc7636" target="_blank">RFC 7636: Proof Key for Code Exchange by OAuth Public
                        Clients</a>.</td>
                  </tr>
                  <tr class="">
                    <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e241 "><code>code_challenge</code></td>
                    <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e243 ">
                      <p>Specifies the SHA256 hash value of the <code>code_verifier</code> value in the token request. The value is Base-64 URL encoded as
                        defined in Section 5 of <a href="https://datatracker.ietf.org/doc/html/rfc4648#section-5" target="_blank">RFC 4648: The Base16, Base32, and Base64 Data Encodings</a>.</p>
                      <p style="margin-bottom:0;">When
                        you configure your authorization flow, include this value in the authorization
                        request.</p>
                    </td>
                  </tr>
                  <tr class="">
                    <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e241 "><code>code_verifier</code></td>
                    <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d89410e243 ">
                      <p>Specifies 128 bytes of random data with high entropy to make guessing the code value
                        difficult. Set this parameter to help prevent authorization code interception attacks. The
                        value is Base-64 URL encoded as defined in Section 5 of <a href="https://datatracker.ietf.org/doc/html/rfc4648#section-5" target="_blank">RFC 4648: The Base16, Base32, and Base64 Data Encodings</a>. </p>
                      <p style="margin-bottom:0;">When
                        you configure your authorization flow, include this value in the token
                        request.</p>
                    </td>
                  </tr>
                </tbody>
              </table>Here’s an example response.
    
    ```
    {
    “code_challenge_method”:“S256”
    “code_challenge”:“JB7nT*************”
    “code_verifier”:“GkLvw**************”
    }
    ```

When you configure the [web server flow](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&type=5&language=en_US), [hybrid web server flow](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_hybrid_web_server_flow.htm&type=5&language=en_US), and variations of the [Authorization Code and Credentials Flow](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_headless_identity_pointer.htm&type=5&language=en_US), include the `code_challenge` and `code_verifier` parameters in your requests as directed.