Effectively move the session creation (or most of it) to the token endpoint.
Store only the hashes of all authorization tokens, i.e. authorization_code, access_token, refresh_token, cookie_value.
Flow details
Authorize request, if successful, generates an authorization code and internally stores its hash as a key and authorization details (credentials_id, authentication data (=root_session_id), scope, client_id, pkce...) as the value. It returns the code in the response to the client.
On the token request, the server hashes the received code, retrieves the authorization details and performs further checks if necessary (pkce...). If successful, it builds a session based on the scope and other parameters. A new ID token is created from the session data. It also generates access and refresh token and stores their hash as the key and the session data as the value.
The content of the ID token should always be the same as the content of the session object. This implies no expiration extensions. Once the session and ID token expires, refresh_token should be used to create a new session.
The OAuth introspection endpoint accepts the access token and responds with a JSON containing the ID token claims (unchanged!, not even if the user changes email or their permissions are changed or whatever) plus the active field (https://datatracker.ietf.org/doc/html/rfc7662#section-2.2) and the introspection timestamp (for caching reasons).
The Nginx auth_request introspection endpoint should return the same data as above, but wrapped in a signed JWT.
The refresh_token works basicaly the same as the authorization_code: it is sent in a request to the token endpoint in order to get a fresh new session plus access, refresh and ID tokens.
Cookie authorization
Cookie token requests are processed similarly at the cookie-entry point. The server always stores only the hash of the cookie value.
This should also work with the quick guest (anonymous) sessions, whose cookies are dispensed directly at the introspection endpoint.
:question: Expiration extension? There is no refresh token or a "proper" ID token and cookie-clients have no agency to request a new cookie. So either the server should automatically extend the cookie session, or let the cookie expire and let nginx trigger the automatic authorization flow again. These redirects can however lead to unexpected data loss on the user side.
Flow details
active
field (https://datatracker.ietf.org/doc/html/rfc7662#section-2.2) and the introspection timestamp (for caching reasons).auth_request
introspection endpoint should return the same data as above, but wrapped in a signed JWT.Cookie authorization