---
title: Proof Key for Code Exchange (PKCE) in the AuthPlayground
description: Explore how PKCE protects OAuth authorization-code redemption from interception attacks in the AuthPlayground.
component: identity-for-ai
page_id: identity-for-ai:protocols:authplayground-pkce
canonical_url: https://developer.pingidentity.com/identity-for-ai/protocols/authplayground-pkce.html
llms_txt: https://developer.pingidentity.com/identity-for-ai/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2026-08-26T20:20:14Z
keywords: ["Identity for AI", "OAuth 2.0 protocols", "PKCE", "Proof Key for Code Exchange", "Authorization Code Flow", "enterprise AI", "AuthPlayground"]
section_ids:
  the-pkce-model: The PKCE model
  the-authplayground-implementation: The AuthPlayground implementation
  step-1-generate-the-verifier-and-challenge: "Step 1: Generate the verifier and challenge"
  step-2-send-the-code_challenge: "Step 2: Send the code_challenge"
  step-3-redeem-the-code-with-the-code_verifier: "Step 3: Redeem the code with the code_verifier"
  how-pkce-compares-to-other-concepts: How PKCE compares to other concepts
  bringing-it-back-to-enterprise-ai: Bringing it back to enterprise AI
  pkce-and-par: PKCE and PAR
  key-takeaways: Key takeaways
---

# Proof Key for Code Exchange (PKCE) in the AuthPlayground

Protecting the authorization code from interception attacks.

When Sarah asks her AI assistant to prepare a meeting briefing for Apex Logistics, the assistant needs data from Salesforce, ServiceNow, and other enterprise systems. Before that happens, the application must establish Sarah's authenticated session through an OAuth Authorization Code flow.

What if someone intercepts the short-lived authorization code? Can they redeem it, instead of the client that started the flow? PKCE ([RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)) protects against this by requiring the client redeeming the code to prove knowledge of a secret created when the flow began.

## The PKCE model

The client creates a high-entropy random value called the `code_verifier`. Using `S256`, it derives the `code_challenge`:

```json
"code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))"
```

The client uses the two values at different points:

* **Authorization request**: The client sends the `code_challenge`. The verifier itself isn't sent in the authorization request.

* **Token request**: The client sends the `code_verifier`.

When the client redeems the code, the authorization server derives the challenge from the submitted verifier and compares it with the challenge associated with the original request. An intercepted authorization code alone isn't enough.

## The AuthPlayground implementation

**Entities involved**: Client application, IdP (authorization server)

The AuthPlayground demonstrates the [Proof Key for Code Exchange](https://www.authplayground.dev/flows/pkce) flow in three steps:

1. Generate `code_verifier` and `code_challenge`.

2. Send the authorization request with `code_challenge`.

3. Redeem the code with the `code_verifier`.

### Step 1: Generate the verifier and challenge

The first step happens locally without a network request. The playground generates a `code_verifier` and derives the `code_challenge` using SHA-256 and Base64url encoding:

```json
{
  "code_verifier": "zMmfa-o_LRRLZJRDwXfvZ5oyrF4K__IJnwoD9SUaZtQ",
  "code_challenge": "FSm-7wdqeus-41oeOeSjglqXdnSt-LhmvRwJgzR59DY",
  "code_challenge_method": "S256"
}
```

The client keeps the `code_verifier` and sends only the derived challenge during authorization.

### Step 2: Send the `code_challenge`

The authorization request includes the following information in the query string:

```json
GET /idp/authorize
    response_type=code
    client_id=playground-demo-client
    redirect_uri=https://.../callback
    scope=openid profile email
    code_challenge=FSm-7wdqeus-41oeOeSjglqXdnSt-LhmvRwJgzR59DY
    code_challenge_method=S256
```

The authorization server returns an authorization code through the browser redirect:

```json
302
location: https://.../callback

{
  "code": "<authorization_code>",
  "state": "<state>",
  "note": "Authorization Response: code returned via redirect_uri (RFC 6749 §4.1.2)"
}
```

At this point, the authorization code has traveled through the redirect. The original `code_verifier` hasn't. That separation is the core of PKCE.

### Step 3: Redeem the code with the `code_verifier`

The legitimate client sends both the authorization code and its original verifier:

```json
POST /idp/token
Content-Type: application/x-www-form-urlencoded

{
  "grant_type": "authorization_code",
  "code": "<authorization_code>",
  "redirect_uri": "https://.../callback",
  "client_id": "playground-demo-client",
  "code_verifier": "RvtACdjYxEsvE_kEJ6W6w3WsrG2nKZUtfepOY5EosFQ"
}
```

The authorization server derives the challenge from the submitted verifier and compares it with the challenge associated with the authorization request. The authorization server:

1. Receives the `code_verifier`.

2. Calculates the challenge using SHA-256 and Base64url encoding.

3. Compares the calculated challenge with the original `code_challenge`.

4. Returns tokens if they match, or rejects the request if they don't.

In the playground flow, the values match and the authorization server returns an access token and ID token for Sarah (`demo-user@example.com`).

## How PKCE compares to other concepts

### Bringing it back to enterprise AI

Sarah's request might eventually cause the AI assistant to reach Salesforce opportunity data or ServiceNow support history. PKCE operates much earlier in the flow:

* Sarah initiates the request to the AI assistant application.

* The application performs the authorization code flow with PKCE against the authorization server.

* The authorization server issues the tokens.

* The AI workflow uses the tokens for downstream integrations such as Salesforce or ServiceNow.

PKCE doesn't decide what Salesforce or ServiceNow will allow. It doesn't establish workload identity or carry delegated identity across authorization domains. Its job is narrower. PKCE protects authorization-code redemption to ensure that possession of an intercepted code alone isn't enough to obtain the resulting tokens.

### PKCE and PAR

PKCE and [Pushed Authorization Requests (PAR)](authplayground-par.html) are often used together, but they protect different parts of the flow:

* PAR protects how the authorization request reaches the server.

* PKCE protects authorization-code redemption.

A deployment might use one or both depending on the requirements.

## Key takeaways

The complete PKCE flow looks like this:

1. Generate `code_verifier`.

2. Derive `code_challenge`.

3. Authorize with `code_challenge`.

4. Receive `authorization_code`.

5. Redeem with `code_verifier`.

6. Receive tokens.

The important security property of PKCE is that obtaining the authorization code by itself isn't enough to redeem it. For an AI workflow that might reach many enterprise systems, PKCE gives the rest of the authorization chain a stronger starting point.
