Inferensys

Glossary

Proof Key for Code Exchange (PKCE)

Proof Key for Code Exchange (PKCE) is an OAuth 2.0 extension that prevents authorization code interception attacks by having the client create and verify a cryptographically random key.
Stylish WeWork-like workspace with hot desks and document wall, professional searching through enterprise knowledge base on a mounted ultrawide display, warm industrial pendants overhead.
API AUTHENTICATION FLOWS

What is Proof Key for Code Exchange (PKCE)?

Proof Key for Code Exchange (PKCE, pronounced 'pixie') is a critical security extension to the OAuth 2.0 Authorization Code flow, specifically designed to protect public clients like mobile and single-page applications from authorization code interception attacks.

Proof Key for Code Exchange (PKCE) is an OAuth 2.0 security extension that mitigates authorization code interception attacks by having the client create and verify a cryptographically random key. In the PKCE-enhanced Authorization Code flow, the client generates a secret, one-time code verifier and a derived code challenge. It sends the challenge with the initial authorization request and later must present the matching verifier to exchange the received authorization code for an access token. This mechanism prevents a stolen authorization code from being used by a malicious actor.

PKCE is essential for public clients—applications that cannot securely store a client secret, such as native mobile apps and single-page applications (SPAs) executing in a user's browser. It is formally defined in RFC 7636 and is now a mandatory requirement for OAuth 2.0 public clients by best practice standards like OAuth 2.1. The protocol strengthens the security posture of AI agents and automated systems that must authenticate with external APIs without relying on a confidential client credential.

PKCE MECHANICS

Key Features and Security Properties

Proof Key for Code Exchange (PKCE, pronounced 'pixie') is a critical extension to the OAuth 2.0 Authorization Code flow. It is designed to secure public clients—applications that cannot securely store a client secret, such as mobile apps and single-page applications (SPAs)—from authorization code interception attacks.

01

The Code Interception Attack

PKCE was created to mitigate a specific OAuth 2.0 vulnerability: the authorization code interception attack. In the standard Authorization Code flow, a malicious actor could potentially steal the short-lived authorization code as it is transmitted back to the client (e.g., via a malicious browser plugin or by logging the URI). If the attacker can intercept this code and use it before the legitimate client does, they can obtain an access token. PKCE makes this stolen code useless by cryptographically binding it to a secret only the legitimate client knows.

02

Code Verifier & Code Challenge

PKCE introduces two cryptographically linked values:

  • Code Verifier: A high-entropy cryptographically random string created by the client. It is typically a 43-128 character string using characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~".
  • Code Challenge: A transformed version of the Code Verifier. The client sends this to the authorization server during the initial authorization request. The transformation is either a plain S256 (SHA-256 hash, Base64URL-encoded) or plain (no transformation). S256 is mandatory for public clients in standards like OAuth 2.1. This pair creates a proof-of-possession mechanism for the authorization code.
03

The Two-Step Handshake

PKCE modifies the OAuth flow in two key steps:

  1. Authorization Request: The client generates a Code Verifier and derives a Code Challenge. It sends the Code Challenge (and the code_challenge_method, e.g., S256) to the authorization server along with the standard OAuth parameters. The server stores this challenge.
  2. Token Request: When the client receives the authorization code, it makes the token request to the authorization server's token endpoint. This request must include the original Code Verifier. The server recalculates the Code Challenge from the provided verifier and compares it to the stored challenge. Only if they match is the authorization code considered valid, and an access token is issued.
04

Public Client Security

PKCE is fundamentally designed for public clients where the use of a static client secret is insecure. This includes:

  • Native Mobile Applications: Code and resources can be decompiled, making embedded secrets insecure.
  • Single-Page Applications (SPAs): All application code, including any client secret, is executed in the user's browser and is therefore publicly viewable.
  • Desktop Applications: Similar to mobile apps, they cannot protect a secret from a determined user. For these clients, PKCE provides the missing proof-of-possession element that a client secret would provide for a confidential server-side application.
05

Mandatory in Modern Standards

Due to its critical security role, PKCE has evolved from a recommendation to a requirement in modern security profiles:

  • OAuth 2.1: The in-progress revision of OAuth 2.0 makes PKCE mandatory for the Authorization Code flow for all clients, effectively deprecating the plain flow without PKCE.
  • Financial-grade API (FAPI): This high-security profile mandates the use of PKCE with the S256 challenge method.
  • Major Identity Providers: Services like Auth0, Okta, Microsoft Identity Platform, and others strongly recommend or require PKCE for public client flows, and it is the default for their SDKs.
06

Relationship to Other Flows

PKCE is often discussed alongside other OAuth 2.0 extensions and best practices:

  • Not a Replacement for Client Authentication: PKCE secures the code exchange but does not authenticate the client itself. For confidential clients, client authentication (e.g., client secret, private_key_jwt, mTLS) is still required at the token endpoint.
  • Complementary to Refresh Tokens: PKCE protects the initial authorization code. If a refresh token is issued, it must also be protected, often by binding it to the client ID or using Refresh Token Rotation.
  • Foundation for Advanced Flows: PKCE is a core component of newer, more secure patterns like the OAuth 2.0 Device Authorization Grant and is integral to BFF (Backend for Frontend) architectures that further isolate tokens from the browser.
PKCE

Frequently Asked Questions

Proof Key for Code Exchange (PKCE, pronounced 'pixie') is a critical security extension to the OAuth 2.0 Authorization Code flow. These FAQs address its core mechanisms, use cases, and implementation details for developers building secure client-side and mobile applications.

Proof Key for Code Exchange (PKCE, RFC 7636) is a security extension to the OAuth 2.0 Authorization Code flow designed to prevent authorization code interception attacks, particularly in public clients like mobile and single-page applications (SPAs).

It works by having the client create a secret, the Code Verifier, and a derived transformation, the Code Challenge, before initiating the authorization request:

  1. The client generates a cryptographically random string called the code_verifier.
  2. It creates a code_challenge by applying a transformation (S256 hash or plain) to the verifier.
  3. The client sends this code_challenge and the chosen code_challenge_method to the authorization server during the initial authorization request.
  4. After the user authenticates, the server returns an authorization code, binding it to the received challenge.
  5. When the client exchanges this code for an access token, it must present the original code_verifier.
  6. The authorization server recomputes the challenge from the verifier and only issues tokens if it matches the initially stored challenge. This proves the client exchanging the code is the same one that initiated the flow.
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.