Correlation values
An authorization response must belong to the browser interaction and issuer that started it. state correlates the response with client state and helps prevent cross-site request forgery. nonce binds an ID token to the authentication request and helps detect replay. Exact redirect URI and issuer validation prevent response and authorization-server mix-up.
Create and bind
Generate unpredictable values for each request. Store them in protected client state with the expected issuer, client identifier, redirect URI, code verifier, and expiry. Send only registered redirect URIs. At the callback, validate the response before changing a session.
Validate the result
Check returned state, authorization server issuer, code and callback binding, exact redirect context, token issuer and audience, signature, time, nonce, and required authentication properties. Consume one-time state and code values atomically.
Failure and residual risk
Login CSRF, code injection, mix-up, open redirect, callback confusion, replay, and parallel-tab races can attach the wrong identity to a session. State without issuer binding cannot prevent every mix-up. Nonce does not replace token signature, issuer, audience, or code-flow validation.
Pomerium boundary
Pomerium performs configured OpenID Connect authentication and manages its callback and session state. The identity provider owns its authorization endpoint and ID token. Upstream applications that implement separate OIDC flows own their own correlation and validation.
Evaluation checklist
- Are state, nonce, and PKCE values unpredictable and unique per request?
- Is stored state bound to issuer, client, redirect URI, and expiry?
- Does the callback validate issuer before accepting the response?
- Are state, code, and nonce consumed once and safe across parallel tabs?
- Do tests cover wrong issuer, wrong redirect, replay, mix-up, and login CSRF?
