Visual RFC.
ALL RFCs / RFC 9700
Read the RFC ↗
RFC 9700 / THE FOUNDATIONS

Authorization code + PKCE

02

Proof Key for Code Exchange (PKCE) lets an app prove that it started the request. A stolen authorization code alone is not enough.

Terms in this drawing
App / client
The software asking for permission to use your data.
Verifier and challenge
The verifier is a fresh secret kept by the app. The challenge is a value derived from it, sent before the code is issued.
S256
A method that hashes the verifier with SHA-256 and base64url-encodes the result. This is not encryption; the server later repeats the calculation.
Public and confidential clients
A public client cannot keep an app credential secret, for example code installed on a user device. A confidential client can protect its credentials, for example on its own server.
OIDC and nonce
OpenID Connect (OIDC) adds sign-in identity to OAuth. Its nonce is a fresh value binding the sign-in response to the request; the alternative below has additional conditions.
What PKCE proves
It binds a code exchange to the transaction that kept the verifier. It is separate from proving the app identity, and does not encrypt the code.
Related RFCs and changes

“Updates” changes part of an earlier RFC. “Obsoletes” replaces it. This list shows selected related documents.

RFC 9700 · § 2.1.1EXAMPLE
4 / 4
Authorization code + PKCEProof Key for Code Exchange (PKCE) lets an app prove that it started the request. A stolen authorization code alone is not enough. Current state: Only a matching exchange succeeds..Authorization code + PKCEClientfresh secretAuthorization servercode · saved challengemethod: S256codecode + secretproof matchestoken issued
04
Only a matching exchange succeeds.

Knowing the code alone does not provide the verifier needed to redeem it.

Protocol participantThreat or exceptionProtocol controlSimplified drawings · precise section references
WHAT CHANGED
RFC 6749 § 4.1RFC 9700 § 2.1.1

The framework did not require PKCE. Public clients now MUST use it; confidential clients are RECOMMENDED to use it. Servers MUST support PKCE, enforce the verifier, and prevent downgrade.

Read the updated RFC section ↗
KEY POINT

Bind the code to this transaction.

  • Public clients MUST use PKCE; confidential clients are RECOMMENDED to use it. Authorization servers MUST support it.
  • Use a fresh, session-bound challenge. Clients SHOULD use a method that hides the verifier; S256 is the available method named here.
  • The token endpoint MUST check the verifier when a challenge was supplied. Confidential OIDC clients may instead use nonce with the precautions in § 4.5.3.2.
DETAILS

PKCE is for web apps too. It is separate from client authentication: proving which app you are does not prove which user transaction a code belongs to.

Read the RFC section ↗

Diagrams simplify the RFC. Read the linked sections for complete requirements.

Privacy
All chapters in this RFC
  1. OAuth overview
  2. Authorization code + PKCE
  3. Retire unsafe grants
  4. Prevent token replay
  5. Limit token privileges
  6. Authenticate the client
  7. Metadata, TLS & CORS
  8. The attacker model
  9. Redirect URI validation
  10. Referer header leakage
  11. Browser history leakage
  12. Authorization server mix-up
  13. Authorization code injection
  14. Access token injection
  15. Cross-site request forgery
  16. PKCE downgrade
  17. Leakage at resource servers
  18. Misuse of stolen tokens
  19. Open redirection
  20. 307 credential forwarding
  21. TLS termination & proxies
  22. Refresh token protection
  23. Client as resource owner
  24. Clickjacking
  25. In-browser messaging

Drawing view

Scroll the drawing to see every part. Playback controls stay above it.

RFC 9700 / CHAPTERS

Chapters

For full details, tables, algorithms, and exceptions, read the original RFC.

RFC status and corrections ↗