---
title: "Step 05: PKCE Implementation"
source: Panaversity Learn Agentic AI
source_url: https://github.com/panaversity/learn-agentic-ai
licence: Apache-2.0
domain: agentic-ai
subdomain: panaversity-agentic
date_added: 2026-04-25
---

# Step 05: PKCE Implementation


PKCE (Proof Key for Code Exchange) is a **security extension** to the OAuth 2.1 Authorization Code flow, not a separate flow. According to the [MCP Authorization specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization.md), **PKCE is mandatory** for MCP clients.

This step is dedicated to PKCE. Here we will:
- Add code_verifier/code_challenge generation
-Enhance Step 04's flow with PKCE security
- MCP compliance achieved

## What is PKCE?

**PKCE** protects against **authorization code interception attacks** by ensuring that only the client that initiated the authorization request can exchange the authorization code for tokens.

### How PKCE Works:

1. **Client generates random secret** (`code_verifier`)
2. **Client creates hash** of the secret (`code_challenge`) 
3. **Authorization request** includes `code_challenge`
4. **Authorization server** stores the challenge
5. **Token exchange** includes the original `code_verifier`
6. **Server verifies** that `SHA256(code_verifier) == code_challenge`

## MCP PKCE Requirements

From the MCP specification:

### Mandatory Implementation
> "MCP clients **MUST** implement PKCE according to [OAuth 2.1 Section 7.5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.5.2)"

### Security Purpose
> "PKCE helps prevent authorization code interception and injection attacks by requiring clients to create a secret verifier-challenge pair, ensuring that only the original requestor can exchange an authorization code for tokens."

## PKCE vs Regular Authorization Code Flow

| Step | Regular Flow | PKCE Flow |
|------|-------------|-----------|
| 1. Authorization Request | `response_type=code&client_id=...` | `response_type=code&client_id=...&code_challenge=...&code_challenge_method=S256` |
| 2. Authorization Response | `code=abc123` | `code=abc123` (same) |
| 3. Token Exchange | `grant_type=authorization_code&code=abc123` | `grant_type=authorization_code&code=abc123&code_verifier=original_secret` |

## PKCE in Step 03 Implementation

Our current Step 03 focuses on **Dynamic Client Registration**. The next step implements the ** OAuth flow**:

```python
# Example PKCE implementation (for future steps)
import secrets
import hashlib
import base64

def generate_pkce_params():
    code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode('utf-8').rstrip('=')
    code_challenge = base64.urlsafe_b64encode(
        hashlib.sha256(code_verifier.encode('utf-8')).digest()
    ).decode('utf-8').rstrip('=')
    
    return {
        'code_verifier': code_verifier,
        'code_challenge': code_challenge,
        'code_challenge_method': 'S256'
    }
```

## Why PKCE is Critical for MCP

1. **Public Clients**: MCP clients often can't securely store client secrets
2. **Mobile/Desktop Apps**: Vulnerable to authorization code interception
3. **Security by Default**: OAuth 2.1 makes PKCE mandatory for all clients
4. **MCP Compliance**: Required by the MCP specification for HTTP transports

The `basic` scope we just added supports PKCE-enabled clients! Step 04: Basic Authorization Code Flow Focus on core OAuth concepts, User interaction, redirect URIs, state parameter so No PKCE complexity - pure learning.
