TL;DR: PKCE closes a structural OAuth gap by binding each authorization request to its token exchange, so a stolen code cannot be redeemed without the original verifier, according to Ory. That matters because mobile apps, SPAs, and even confidential clients face code interception and injection risks that client secrets alone do not reliably solve.
At a glance
What this is: PKCE is an OAuth 2.0 extension that binds the authorization request to the token exchange and blocks code interception and injection attacks.
Why it matters: It matters because IAM teams need to treat PKCE as a default control for public clients and a defense-in-depth requirement for confidential clients, especially as OAuth 2.1 moves it into the baseline.
👉 Read Ory's explanation of PKCE and OAuth code interception
Context
PKCE is a protocol control for OAuth 2.0, not a separate identity system. It exists because some clients cannot safely hold a secret, and once an authorization code can be intercepted the access token exchange becomes the weak point in the flow. For IAM teams, that makes PKCE part of OAuth hardening rather than an optional implementation detail.
The identity governance issue is straightforward: if the application cannot prove it is the same client that started the login, an attacker can complete the flow instead. That risk affects mobile apps, browser-based apps, and increasingly automated and machine-driven access patterns that rely on OAuth for API access. Ory’s article is a protocol explainer, but the practitioner question is how to make code exchange resistant to interception by design.
Key questions
Q: How should security teams implement PKCE across OAuth clients?
A: Apply PKCE to every authorization code flow, including confidential clients, and make it non-optional in your authorization server policy. Pair it with exact redirect URI registration and session binding so an intercepted code cannot be replayed into a different context. For workloads and agents, treat this as baseline identity hardening, not an advanced feature.
Q: Why does PKCE matter if a client already has a secret?
A: A client secret protects the application, but it does not prove that the entity redeeming the authorization code is the same one that requested it. PKCE adds that proof. It prevents intercepted codes from being exchanged elsewhere and reduces the risk created by modern browser, mobile, and distributed app delivery models.
Q: What breaks when PKCE is not enforced in OAuth 2.1?
A: Without PKCE, intercepted authorization codes can be redeemed by an attacker, and redirect tampering becomes easier to exploit. The result is that code possession becomes too powerful, especially in browser, mobile, and proxy-mediated flows where front-channel exposure is realistic.
Q: Who is accountable for enforcing PKCE in enterprise IAM?
A: Application owners, IAM platform teams, and identity architects all share responsibility. The application team must request it, the IAM team must enforce it in policy and client registration, and security governance must verify that confidential clients are included, not just public ones. OAuth 2.1 is making that shared obligation harder to avoid.
Technical breakdown
How PKCE binds the authorization request to the token exchange
PKCE adds a one-time cryptographic proof to the OAuth authorization code flow. The client generates a random code verifier, derives a code challenge from it, and sends the challenge during authorization. Later, when it exchanges the authorization code for tokens, it must present the original verifier. The authorization server hashes the verifier and compares it with the stored challenge. If they do not match, the token request fails even if the code itself is valid. This is what makes a stolen code useless without the original proof.
Practical implication: require PKCE for every authorization code flow and reject any token exchange that does not present a valid verifier.
Why the plain method is weak and S256 should be the default
PKCE defines two challenge methods. Plain sends the verifier as the challenge, which removes the security property because anyone who sees the request also sees the secret needed to finish the exchange. S256 transforms the verifier with SHA-256 and base64url encoding, so the challenge can be transmitted safely without revealing the original value. In practice, S256 is the only method that preserves the binding property PKCE is meant to provide. The plain method exists for rare constrained platforms, not as a normal operating mode.
Practical implication: disable plain wherever possible and make S256 the mandatory method in client registration and policy.
Why PKCE now applies to confidential clients as well as public clients
PKCE was originally created for public clients such as mobile apps and SPAs that cannot keep a secret. The OAuth Security BCP now recommends it for confidential clients too because code injection is a different attack from secret theft. In a code injection scenario, the attacker uses a legitimate client to redeem a stolen code, so a client secret alone does not stop the flow. PKCE still works because the code is bound to the verifier generated by the original client session, not to the server-side secret. That is why the control has moved from optional safeguard to baseline expectation.
Practical implication: extend PKCE enforcement to server-side OAuth clients, not just public apps, and validate redirect URI handling at the same time.
Threat narrative
Attacker objective: The attacker wants to obtain valid access tokens from a stolen authorization code and use them to impersonate the intended client.
- Entry occurs when an attacker intercepts or injects an OAuth authorization code through a malicious app, competing redirect handler, or manipulated client flow.
- Escalation happens when the attacker redeems the captured code before the legitimate client finishes the exchange, turning a transient code into usable tokens.
- Impact follows when the attacker gains authenticated access to the target application or API without ever possessing the original client secret or verifier.
Breaches seen in the wild
- Salesloft OAuth token breach — hackers stole OAuth tokens to access Salesforce data via Salesloft.
- GitHub Dependabot Breach — GitHub Dependabot tokens stolen and abused to push malicious commits to repositories.
Read our 52 NHI Breaches Analysis report for a comprehensive view of breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
PKCE is now a baseline identity binding control, not an edge-case mobile safeguard. The article reflects the broader shift in OAuth practice: code interception is no longer an acceptable risk left to app teams to absorb. For IAM programmes, that means PKCE belongs in client policy, registration workflows, and assurance checks, not in developer tribal knowledge. The practical conclusion is to treat PKCE as required state for any authorization code deployment.
The real control objective is proof of continuity between request and exchange. PKCE works because it preserves the linkage between the identity that started the flow and the identity that completes it. That matters across human, app, and machine-driven access because the security property is not user-centric, it is session-centric. IAM teams should read this as a reminder that token issuance is only as trustworthy as the proof attached to the exchange.
Code interception is a lifecycle failure, not just a cryptographic one. The verifier must be generated fresh, held briefly, and discarded after the exchange, which makes PKCE part of short-lived credential governance. The same lifecycle logic applies to workload and agent access patterns that rely on ephemeral tokens. The practitioner takeaway is that transient credentials still need explicit binding and expiration rules, even when no long-lived secret exists.
OAuth 2.1 is formalising what security teams should already be doing. Making PKCE mandatory in the draft standard validates the direction of travel for identity governance. The important implication is not novelty, but convergence: teams that have not standardised PKCE are carrying avoidable implementation debt. The field is moving toward default binding controls, and IAM governance has to keep pace.
What this signals
PKCE should be treated as part of the control set for token-bound trust, especially where applications, SPAs, and machine access flows converge. The governance shift is toward short-lived proof attached to each exchange, not assumptions about where the client runs or whether a secret can be hidden.
For IAM programmes, the practical risk is configuration drift. If some clients enforce PKCE and others still allow plain or optional enforcement, the weakest path becomes the exploitable one, and attackers will target the flow that still lets a valid code be redeemed without proof.
For practitioners
- Require PKCE for all authorization code clients Make PKCE mandatory in client registration and reject any authorization code flow that does not present a valid verifier at the token endpoint.
- Enforce S256 as the only accepted challenge method Block plain in policy, allow it only when a platform genuinely cannot hash, and review all existing client configurations for downgrade paths.
- Keep verifiers short-lived and out of logs Generate a fresh high-entropy verifier for each request, store it in memory or secure storage only, and prevent it from appearing in URLs, browser history, or access logs.
- Pair PKCE with redirect URI validation and state handling Use exact redirect URI matching, preserve state for CSRF protection, and treat these controls as complementary rather than interchangeable.
Key takeaways
- PKCE closes the gap between OAuth authorization and token exchange by requiring proof that the same client completed both steps.
- The control matters because authorization code interception and injection remain viable whenever the verifier is optional, weak, or reused.
- IAM teams should make PKCE mandatory now, with S256 enforcement and exact redirect validation, rather than waiting for OAuth 2.1 to force the change.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
NIST SP 800-63, NIST Zero Trust (SP 800-207) and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST SP 800-63 | SP 800-63C | PKCE protects the OAuth federation exchange between client and authorization server. |
| NIST Zero Trust (SP 800-207) | PKCE supports continuous proof of request continuity in token-based access flows. | |
| NIST CSF 2.0 | PR.AC-1 | Identity proofing and access control both depend on trustworthy authentication flows. |
Treat authorization code flows as trust decisions that need per-request binding and verification.
Key terms
- PKCE: Proof Key for Code Exchange is a binding mechanism that links the authorization request to the later token exchange. It helps stop authorization code interception and injection by requiring proof that the same client that started the flow is the one completing it.
- Authorization Code Interception: An attack where a malicious process steals the authorization code before the intended client can redeem it. The threat is strongest in public clients and redirect environments that can be observed or hijacked. PKCE is the control designed to prevent the stolen code from being useful.
- Authorization Code Injection: Authorization code injection is an attack where a valid code is steered to an attacker-controlled endpoint or session. In MCP and OAuth flows, it often succeeds when state, consent, and redirect_uri validation are not bound tightly enough to the originating user session.
What's in the full article
Ory's full article covers the operational detail this post intentionally leaves for the source:
- Step-by-step walkthrough of the PKCE request and token exchange sequence in OAuth 2.0 clients
- Parameter-level examples for code verifier, code challenge, and code_challenge_method implementation
- Comparison of S256 and plain method behaviour in real client integrations
- Practical guidance on where PKCE fits alongside state, nonce, and redirect URI validation
Deepen your knowledge
NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are responsible for identity security strategy or NHI governance in your organisation, it is worth exploring.
Published by the NHIMG editorial team on August 18, 2026.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org