Skip to main content

Validate an OpenID Connect sign-in

Trace OpenID Connect sign-in and validate issuer, client, redirect, state, nonce, ID token, and access-token boundaries.

Learning outcomes

  • Separate the OpenID Provider, relying party, browser, and resource server roles.
  • Separate an ID token from an OAuth access token.
  • Validate one authorization-code sign-in from request through local session creation.
  • Test state, nonce, issuer, audience, redirect, signature, time, and replay failures.

Protocol roles

The OpenID Provider authenticates the end user and issues an ID token. The relying party is the OAuth client that requests authentication, validates the response, and creates its local session. The browser carries front-channel requests and responses. A UserInfo endpoint or another API is a resource server and accepts an access token.

An ID token is evidence for the client about an authentication event and subject. Its audience is the relying party. An access token authorizes a client to call a resource server. Its audience is that resource. Sending an ID token to an API or using an access token as the only proof of sign-in crosses these roles.

OpenID Connect Core Section 2 defines the ID token. Section 3.1 defines authorization-code sign-in, and Section 3.1.3.7 defines ID-token validation for that flow.

Message flow

  1. The relying party starts from a configured or safely discovered issuer. It records the issuer, client identifier, exact redirect URI, transaction expiry, state, nonce, and PKCE verifier.
  2. It redirects the browser to the issuer's authorization endpoint with scope=openid, the registered redirect URI, state, nonce, and S256 PKCE challenge.
  3. The OpenID Provider authenticates the user, obtains required authorization, and returns a short-lived authorization code to the exact redirect URI.
  4. The relying party validates the callback state and issuer, then sends the code and PKCE verifier to the token endpoint. A confidential client also authenticates according to its registration.
  5. The OpenID Provider validates the code transaction and returns an ID token and, when requested, an access token.
  6. The relying party validates the ID token before it creates a local session. It compares exact issuer, client audience, authorized party when required, signature and algorithm, expiry, issued time, and nonce. It applies any required authentication time, context, or method policy.
  7. If the relying party calls UserInfo, it sends the access token to that resource and verifies that the returned subject exactly matches the ID-token subject.

Validation and failure cases

Use trusted issuer configuration to select metadata and keys. Never let an unverified token select an arbitrary issuer or key URL. Require an allowed signing algorithm. Validate exact iss; ensure aud contains the client identifier; validate azp when the audience rules require it; verify signature, exp, acceptable iat, and transaction nonce. Treat subject identifiers as issuer-scoped. The same sub value from another issuer is a different identity.

Reject a callback with wrong or reused state, unexpected issuer, unregistered redirect URI, invalid PKCE verifier, replayed code, invalid signature, unknown key after bounded refresh, wrong audience, invalid authorized party, expired token, mismatched nonce, or UserInfo subject mismatch.

Test account confusion with two issuers and two browser tabs. Swap codes and state values. Change the token audience to another client. Return a valid token from another issuer with the same subject text. A local session must not exist until every required check passes.

Design tradeoffs and residual risk

Discovery reduces manual endpoint configuration but adds metadata and key-fetch trust. Shared callbacks reduce deployment work but make issuer correlation more important. Pairwise subject identifiers improve privacy across relying parties but require issuer-and-client-aware account linking. Long sessions improve usability but make authentication freshness and account disable propagation less immediate.

OIDC proves what the issuer states about authentication. It does not prove device health, current employment, resource permission, or every factor property unless the relying party requests and validates defined claims. Local account linking can still attach a valid external identity to the wrong internal account.

Pomerium boundary

Pomerium can act as the relying party for a configured identity provider. It validates the authentication response and creates its own access session before applying route policy. Operators own provider trust, claim mapping, session policy, and account lifecycle. Upstream applications still authorize their own resources and must not treat an unverified identity header as an OIDC result.

Exercise

Trace one staging sign-in. Record the configured issuer, authorization endpoint, token endpoint, JWKS location, client identifier, redirect URI, state and nonce hashes, PKCE method, ID-token issuer and audience, signing-key identifier, subject, authentication time, and local-session creation time.

Run negative tests for wrong state, wrong issuer, wrong audience, invalid signature, expired token, nonce mismatch, reused code, near-match redirect URI, and UserInfo subject mismatch. Confirm that no local session or application request is accepted.

Evaluation checklist

  • Can the team distinguish the ID token, access token, and local session by issuer, audience, and consumer?
  • Does validation begin from an approved issuer and key source?
  • Are state, issuer, redirect URI, PKCE, signature, audience, time, nonce, and subject checked?
  • Does the relying party create no session before all required validation succeeds?
  • Can mixed issuer, parallel-tab, replay, and account-linking failures be reproduced safely?

Next learning unit

Sources and further reading

Keep learning

Application and Service AccessIdentity and Authentication

JSON Web Token (JWT)

Learn how JSON Web Tokens carry signed or encrypted claims, which checks a receiver must make, and how Pomerium uses a signed identity assertion.

Learn this term

Get a Personalized Demo

Schedule a Call with a Pomerium Engineer

Get a Demo