Skip to main content

Proof Key of Code Exchange (PKCE)

Proof Key of Code Exchange (PKCE), pronounced "pixy", strengthens the OAuth 2.0 authorization process, making it a secure choice for single-page applications (SPAs) and native apps. Unlike traditional flows, PKCE addresses vulnerabilities where client credentials can't be safely stored, protecting against attacks like code interception. This guide explains the concept of PKCE, its importance for application security, and the key principles behind its implementation.

What is PKCE?

Proof Key of Code Exchange (PKCE) enhances the OAuth 2.0 authorization code grant flow. It secures single-page applications (SPAs) and native apps, which are vulnerable to reverse engineering and cannot safely store client credentials. PKCE replaces the less secure implicit flow for these applications.

Why use PKCE?

SPAs and native apps are "public clients," meaning they lack secure storage for sensitive data like client secrets. PKCE prevents attackers from intercepting authorization codes during the OAuth process, ensuring safer authentication.

How PKCE works

The following diagram illustrates the key interactions between the user, client application, authorization server, and resource server.

How_PKCE_Works.svg

This sequence of steps provides a detailed breakdown of how the PKCE flow operates based on the interactions shown in the diagram.

  1. User Access. User initiates access to the client application.

  2. Generate Code Verifier and Challenge. Client application generates a code_verifier and transforms it into a code_challenge using a secure hashing method like S256.

  3. Authorization Request. Client application sends an authorization request to the /authorize endpoint on the authorization server. This request includes the code_challenge, redirect_uri, client_id, and other required parameters.

    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:

    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 ID notes

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

    If the tenant URL doesn't include a region identifier, omit the REGION_ID parameter.

    • Australia: au

    • Europe: eu

    • USA: us

  4. Consent Displayed. Authorization server displays a consent form to the user, explaining what the application will access.

  5. User Authentication and Consent. User authenticates with their identity source and provides consent for the requested actions.

  6. Authorization Code Issued. After successful authentication and consent, the authorization server issues an authorization code and redirects it to the client application.

  7. Token Request. Client application sends the authorization code and code_verifier to the /token endpoint on the authorization server.

    Sample call to the token endpoint:

    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. Validation by Authorization Server. Authorization server validates the authorization code, code_verifier, and code_challenge.

  9. Token Issued. If validation succeeds, the authorization server issues an access token to the client application.

  10. Request to Resource Server. The client application sends a request to the resource server (API), including the access token for authentication.

  11. Resource Access. The resource server validates the token and responds with the requested resources or data.

Best practices

  • Redirection Endpoints. Configure valid redirection URIs before making authorization requests.

  • Scope Management. Limit the application's access by defining appropriate scopes during requests.

Additonal resources

  • PKCE Library: Use the SecureAuth-auth-js library for JavaScript SPAs to implement the PKCE flow.

  • Github Repository. Find the library at SecureAuth GitHub page.