By NHI Mgmt Group Editorial TeamPublished 2026-04-14Domain: Governance & RiskSource: WorkOS

TL;DR: State binds the browser redirect to the original login request, nonce binds the ID token to the current session, and PKCE binds the authorization code to the party that requested it, according to WorkOS. Dropping any one of them reopens a distinct attack path, so OIDC security depends on all three checkpoints working together.


At a glance

What this is: This is an analysis of three OAuth and OpenID Connect safeguards, showing that state, nonce, and PKCE each defend a different trust boundary and none can replace the others.

Why it matters: IAM teams need this distinction because authentication hardening fails when browser redirect controls, token replay controls, and code exchange controls are treated as interchangeable.

👉 Read WorkOS's explanation of state, nonce, and PKCE in OIDC flows


Context

OAuth 2.0 and OpenID Connect security depends on protecting three separate moments in the flow: the browser redirect, the token contents, and the code exchange. The article's core point is that these are not overlapping protections, but distinct checks that fail in different ways if one is missing.

For IAM practitioners, the practical issue is not whether the flow is complex enough to deserve more controls, but whether each checkpoint has a control that matches its threat. That is a human identity problem, a federation problem, and a protocol integrity problem at once.


Key questions

Q: How should security teams implement state, nonce, and PKCE together in OIDC flows?

A: Treat them as three separate checks in one flow. Validate state at the callback, validate nonce after token exchange, and send the PKCE verifier only to the token endpoint. Keep the generated values independent and session-bound so one compromise does not weaken the others.

Q: Why do OAuth and OIDC flows need both callback protection and token validation?

A: Because the redirect and the token are different trust boundaries. Callback protection stops unsolicited browser responses, while token validation stops replay and code misuse after the exchange. If teams only harden one side, attackers move to the checkpoint that was left unguarded.

Q: What do teams get wrong about PKCE in enterprise authentication?

A: They often treat PKCE as optional when a client secret exists. That is a mistake because PKCE proves possession of the original authorization request at the token endpoint, which is a different control problem from client authentication. In practice, both controls should be in place.

Q: How can IAM teams tell whether OIDC hardening is complete?

A: A complete implementation has unique state, nonce, and PKCE values per request, validates each one at the correct checkpoint, and rejects any login that skips a step. If one parameter is reused, static, or unverified, the flow still has a known bypass path.


Technical breakdown

State parameter and callback CSRF protection

State is the browser-redirect guard in the authorization code flow. The client generates a random value before redirecting the user, stores it with the session, and expects the authorization server to echo it back unchanged. That lets the client reject unsolicited callbacks that were never initiated by the application. The threat it blocks is callback forgery, where an attacker tries to force the browser to deliver an authorization code into a session the application did not start. State does not protect token freshness or code redemption, only the request-response binding at the redirect boundary.

Practical implication: tie every authorization request to a unique, unguessable state value and reject any callback that fails the session match.

Nonce claim and ID token replay defence

Nonce lives inside the ID token, which makes it a token freshness check rather than a redirect check. The client sends nonce in the authorization request, and the authorization server returns it inside the signed ID token so the application can confirm the token was minted for this specific login attempt. This blocks ID token replay, where a valid token from a previous session is reused in a new one. Because the nonce is verified after the code exchange, it protects a different checkpoint from state and addresses a different trust question: whether the token belongs to this session.

Practical implication: validate nonce on every OIDC login and treat any missing or mismatched value as a replay condition.

PKCE and authorization code interception

PKCE protects the token endpoint, not the redirect. The client sends a hashed code_challenge in the authorization request and later proves possession by presenting the original code_verifier when redeeming the code. The server compares the verifier-derived hash to the stored challenge before issuing tokens. That prevents code interception attacks, where a malicious process steals the code and races to redeem it first. PKCE matters even for confidential clients because it binds the code exchange to the original request origin, which neither state nor nonce can do.

Practical implication: require PKCE with S256 for every client type and do not treat a client secret as a substitute for proof-of-possession.


Read our 52 NHI Breaches Analysis report for a comprehensive view of breaches impacting Non-Human Identities including AI Agents.


NHI Mgmt Group analysis

Authentication assurance fails when redirect integrity, token freshness, and code possession are collapsed into one control. State, nonce, and PKCE each protect a different checkpoint in the OAuth and OIDC flow, and that separation is the point. When teams treat them as interchangeable, they leave the browser callback, the ID token, or the token endpoint exposed to a different class of abuse. The practitioner conclusion is simple: identity assurance in federation is only as strong as the weakest checkpoint-specific control.

State is a session-binding control, not a general authentication control. It was designed for a browser redirect that can be forged because HTTP carries no inherent proof of origin. That assumption fails if teams expect state to validate token freshness or code redemption, because it never sees either of those events. The implication is that callback protection and token protection must be governed separately, even when they are deployed in the same login flow.

PKCE is the clearest example of where federation security becomes proof-of-possession security. The code verifier proves that the party redeeming the authorization code is the one that initiated the request, which is a different problem from session correlation or token replay. In NHI terms, PKCE shifts trust from the front channel to the exchange boundary, and that matters because intercepted codes are only useful when the server cannot bind them back to the originating client. Practitioners should treat that boundary as mandatory, not optional.

Nonce exposes a frequent governance blind spot in OpenID Connect implementations. Teams often assume signature validation is enough once an ID token arrives over a protected back channel. That assumption fails because a valid token can still be replayed into the wrong session if nonce is not checked. The practitioner conclusion is that OIDC hardening is not complete until freshness is verified at the token layer, not just at the transport layer.

Independent random values are a governance requirement, not an implementation detail. Reusing the same string for state, nonce, and code verifier collapses the separation between checkpoints and creates shared failure modes. That design mistake turns three controls into one compromise surface. The practitioner conclusion is to govern each parameter as an independent security primitive with its own generation, storage, and validation logic.

From our research:

  • Lack of credential rotation is cited as the top cause of NHI-related attacks by 45% of organisations, followed by inadequate monitoring and logging (37%) and over-privileged accounts (37%), according to The State of Non-Human Identity Security.
  • Only 1.5 out of 10 organisations are highly confident in their ability to secure NHIs, compared to nearly 1 in 4 for securing human identities, according to the same study.
  • That confidence gap is why lifecycle discipline and federation controls need to be read together, as shown in Salesloft OAuth token breach.

What this signals

Checkpoint-specific identity control is becoming the practical test of mature federation governance. Teams that can describe where state, nonce, and PKCE are enforced are usually stronger than teams that simply say they use OIDC. That distinction matters because identity failures now often come from boundary confusion, not from a missing login standard. For a broader control lens, map these checks back to the NIST Cybersecurity Framework 2.0.

Session-binding failures are a useful named concept for review work. When the callback, token, and exchange checks are handled as one undifferentiated authentication step, the programme loses the ability to spot where abuse enters. The operational signal is straightforward: if your team cannot explain which checkpoint each parameter protects, the implementation is already too coarse for reliable governance.

Enterprises should expect stronger scrutiny of OIDC implementations in both application security and identity reviews, especially where mobile, SPA, and API-first architectures remove traditional trust anchors. The next governance step is not more protocol complexity, but clearer proof that each trust boundary is enforced with its own control and evidence.


For practitioners

  • Generate independent values for each OIDC checkpoint Create separate cryptographically random values for state, nonce, and code_verifier on every authorization request. Store them in the session or equivalent client-side binding and validate each one at its own checkpoint rather than reusing one value across multiple controls.
  • Enforce callback validation before any session advancement Reject unsolicited redirects as soon as the callback arrives if state is missing or mismatched. Do not exchange the code, issue local sessions, or read profile claims until the request-response binding has been confirmed.
  • Treat nonce as a mandatory OIDC login check Decode the ID token after exchange and compare the embedded nonce to the value stored for that login attempt. If the nonce is absent, mismatched, or reused, treat the login as invalid and do not let signed-token verification override the failure.
  • Require PKCE with S256 across all client types Use the code challenge and verifier pair for public and confidential clients alike so the authorization server can verify code possession at the token endpoint. Keep client secrets as an additional control, not the only binding between request and redemption.

Key takeaways

  • State, nonce, and PKCE solve different problems, so replacing one with another creates a specific bypass path rather than a smaller control set.
  • The main risk is checkpoint confusion: redirect integrity, token freshness, and code possession all fail differently when they are governed as one mechanism.
  • Practitioners should verify that each OIDC control is independent, session-bound, and enforced at the correct boundary before calling the flow secure.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

NIST CSF 2.0, NIST SP 800-63 and NIST Zero Trust (SP 800-207) set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
NIST CSF 2.0PR.AC-1OIDC checkpoint validation is part of access control assurance.
NIST SP 800-63OIDC login assurance depends on correct federation and session binding.
NIST Zero Trust (SP 800-207)The flow separates trust boundaries and requires continuous verification.

Use NIST 800-63 guidance to validate session binding and replay resistance in federated login flows.


Key terms

  • State Parameter: A random value sent with an OAuth or OIDC authorization request and returned unchanged on the callback. It binds the browser redirect to the session that initiated it and helps prevent unsolicited callback injection. It does not validate the token itself or prove who redeemed the code.
  • Nonce Claim: A one-time value sent in an OpenID Connect request and returned inside the ID token. It proves the token was minted for the current authentication attempt and helps prevent replay. The nonce is checked after token exchange, so it protects token freshness rather than callback integrity.
  • Pkce: Proof Key for Code Exchange is a mechanism that binds an authorization code to the client that initiated the login. The client sends a hashed challenge up front and later proves possession with the original verifier at the token endpoint. This blocks intercepted codes from being redeemed by a different party.
  • 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.

Deepen your knowledge

OAuth and OpenID Connect checkpoint governance is covered in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are standardising login assurance across application, platform, or identity teams, it is worth exploring.

This post draws on content published by WorkOS: Understanding state, nonce, and PKCE. Read the original.

NHIMG Editorial Note
Published by the NHIMG editorial team on 2026-04-14.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org