From a03b7f7ea308320e15f943863ebca5b44d133be6 Mon Sep 17 00:00:00 2001 From: gazzadownunder <32623517+gazzadownunder@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:41:03 +1100 Subject: [PATCH] Fix: Support multi-cookie sessions in OAuth authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When OAuth sessions exceed 4KB (typically from auth providers with many roles/groups), oauth2-proxy splits the session across multiple cookies named obot_access_token_0, obot_access_token_1, etc. In this mode, the base cookie "obot_access_token" does NOT exist. The AuthenticateRequest function only checked for the base cookie name, causing authentication to fail for large sessions even though valid session cookies were present. This resulted in users being redirected back to the login page in an infinite loop. This fix checks for both the base cookie (obot_access_token) and the first multi-cookie (obot_access_token_0), allowing authentication to succeed for both normal and multi-cookie sessions. Impact: - Fixes infinite login loop for users with large OAuth sessions - Particularly affects Keycloak deployments with many roles/groups - No impact on normal (<4KB) sessions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pkg/proxy/proxy.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index ac037fa344..e707d0ac3c 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -51,8 +51,14 @@ func NewProxyManager(dispatcher *dispatcher.Dispatcher, gptClient *gptscript.GPT func (pm *Manager) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) { // Check for the access token cookie. // This authenticator requires the cookie in order to authenticate any users. - if _, err := req.Cookie(ObotAccessTokenCookie); errors.Is(err, http.ErrNoCookie) { - return nil, false, nil + // When sessions exceed 4KB, oauth2-proxy splits them into multiple cookies (_0, _1, _2, etc.) + // so we check for either the base cookie or the _0 cookie. + _, err := req.Cookie(ObotAccessTokenCookie) + if errors.Is(err, http.ErrNoCookie) { + // Try the _0 cookie for multi-cookie sessions + if _, err := req.Cookie(ObotAccessTokenCookieZero); errors.Is(err, http.ErrNoCookie) { + return nil, false, nil + } } configuredProvider, err := pm.dispatcher.GetConfiguredAuthProvider(req.Context())