Separate identity from authorization
An OpenID Connect ID token communicates an authentication result to a client. An OAuth access token authorizes access to a resource server according to its scope and audience. They serve different purposes. An API should not accept an ID token merely because it is signed by a familiar identity provider.
Use the issuer and subject together as the durable external identity key. An email address can change and should not silently merge accounts across issuers. Map the external identity to local membership and authorization rules, then reevaluate those rules when the user accesses a protected resource.
Use an authorization code flow with PKCE
For an interactive application, use an established client library implementing authorization code flow and PKCE with the S256 method. Bind the authentication response to the initiating browser transaction, validate the redirect URI, and apply the provider's supported protections against request forgery and response injection. Avoid designing a custom login protocol.
Treat browser clients as public clients because a bundled client secret cannot remain secret. Where a server session architecture is appropriate, keep tokens on the server and use a securely configured session cookie with request forgery protection. Session expiration, account switching, and logout behavior must be designed explicitly rather than inferred from token presence.
| Artifact | Purpose | Validation boundary |
|---|---|---|
| Authorization code | Exchange for tokens | Token endpoint and PKCE verifier |
| ID token | Describe authentication to a client | Issuer, audience, expiry, signature, and nonce when used |
| Access token | Call a protected resource | Resource audience, validity, and granted permissions |
| Session cookie | Maintain application session | Session service and browser protections |
Validate tokens through the intended trust relationship
Use a configured issuer and an explicit audience. For signed JWTs, enforce the allowed algorithm, verify the signature with trusted provider keys, and validate applicable time and protocol claims. Decoding a token is not validation. Do not fetch signing keys from arbitrary URLs supplied inside an untrusted token.
Handle key rotation through the identity provider's documented discovery and key distribution mechanism. Bound caches and refresh behavior so a new key does not cause an outage or an attacker controlled refresh storm. Opaque access tokens require the provider's supported validation mechanism; they should not be treated as malformed JWTs.
Test the complete session lifecycle
Exercise expired tokens, incorrect audience, mismatched issuer, replayed authentication responses, missing transaction state, revoked membership, and a provider outage. Apply current OAuth security guidance for refresh tokens, including rotation or sender constraints where required by the client type and authorization server policy.
A failed refresh should not send the user through a redirect loop, and a stale local session should not preserve revoked permissions indefinitely. Test both cases and record security outcomes without logging tokens or authorization codes.