[GH-ISSUE #5753] Reverse proxy SSO: OAuth token exchange missing ClientSecret — breaks Google IdP #11714

Open
opened 2026-08-05 01:30:39 -04:00 by saavagebueno · 1 comment
Owner

Originally created by @FAK55 on GitHub (Mar 31, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5753

Describe the problem

The reverse proxy SSO authentication fails when using Google as a direct external identity provider (not embedded Dex). The OAuth2 token exchange returns client_secret is missing because the proxy auth handler in auth.go constructs the oauth2.Config with PKCE only and no ClientSecret field.

Google requires client_secret for all web application OAuth clients, even when PKCE is used. This means reverse proxy SSO is broken for any deployment using Google as an external IdP.

To Reproduce

  1. Self-hosted multi-container setup with Google as external IdP
  2. Follow the reverse proxy migration guide Option A
  3. Set AuthClientID and AuthCallbackURL in HttpConfig of management.json
  4. Add https://<management-domain>/api/reverse-proxy/callback to Google OAuth client redirect URIs
  5. Create a reverse proxy service with SSO authentication enabled
  6. Access the service URL in incognito → redirects to Google login → callback returns 500

Expected behavior

The OAuth2 token exchange should succeed. The proxy auth handler should support passing a client_secret for IdPs like Google that require it.

A new AuthClientSecret field in HttpConfig would allow this while remaining backwards compatible (empty = PKCE-only).

Root Cause

The relevant code in management/server/http/handlers/proxy/auth.go:

token, err := (&oauth2.Config{
    ClientID:    oidcConfig.ClientID,
    Endpoint:    provider.Endpoint(),
    RedirectURL: oidcConfig.CallbackURL,
}).Exchange(r.Context(), r.URL.Query().Get("code"), oauth2.VerifierOption(codeVerifier))
Originally created by @FAK55 on GitHub (Mar 31, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5753 ## Describe the problem The reverse proxy SSO authentication fails when using **Google as a direct external identity provider** (not embedded Dex). The OAuth2 token exchange returns `client_secret is missing` because the proxy auth handler in `auth.go` constructs the `oauth2.Config` with PKCE only and no `ClientSecret` field. Google **requires `client_secret`** for all web application OAuth clients, even when PKCE is used. This means reverse proxy SSO is broken for any deployment using Google as an external IdP. ## To Reproduce 1. Self-hosted multi-container setup with Google as external IdP 2. Follow the [reverse proxy migration guide](https://docs.netbird.io/selfhosted/reverse-proxy-migration) **Option A** 3. Set `AuthClientID` and `AuthCallbackURL` in `HttpConfig` of `management.json` 4. Add `https://<management-domain>/api/reverse-proxy/callback` to Google OAuth client redirect URIs 5. Create a reverse proxy service with SSO authentication enabled 6. Access the service URL in incognito → redirects to Google login → callback returns **500** ## Expected behavior The OAuth2 token exchange should succeed. The proxy auth handler should support passing a `client_secret` for IdPs like Google that require it. A new `AuthClientSecret` field in `HttpConfig` would allow this while remaining backwards compatible (empty = PKCE-only). ## Root Cause The relevant code in [`management/server/http/handlers/proxy/auth.go`](https://github.com/netbirdio/netbird/blob/main/management/server/http/handlers/proxy/auth.go#L90): ```go token, err := (&oauth2.Config{ ClientID: oidcConfig.ClientID, Endpoint: provider.Endpoint(), RedirectURL: oidcConfig.CallbackURL, }).Exchange(r.Context(), r.URL.Query().Get("code"), oauth2.VerifierOption(codeVerifier))
saavagebueno added the triage-needed label 2026-08-05 01:30:39 -04:00
Author
Owner

@FAK55 commented on GitHub (Apr 6, 2026):

Any update?

<!-- gh-comment-id:4192601888 --> @FAK55 commented on GitHub (Apr 6, 2026): Any update?
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11714