Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 0 additions & 69 deletions .github/workflows/ci.yaml

This file was deleted.

57 changes: 0 additions & 57 deletions .github/workflows/codeql.yml

This file was deleted.

72 changes: 0 additions & 72 deletions .github/workflows/docs.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions .github/workflows/stale.yml

This file was deleted.

26 changes: 0 additions & 26 deletions .github/workflows/test.sh

This file was deleted.

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

### 7.5.1-0.3.2 (upcoming)

* [PLT-3581] Add configurable sign-out URL via `--sign-out-url` / `OAUTH2_PROXY_SIGN_OUT_URL` to support non-standard IdP logout flows (e.g. Autentica/REDSARA)

### 7.5.1-0.3.1 (2025-06-30)

* [PLT-2291] Fix: Handle missing JWT cookie on oauth2-proxy logout
Expand Down
13 changes: 13 additions & 0 deletions docs/docs/configuration/alpha_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ Provider holds all configuration for a single provider
| `googleConfig` | _[GoogleOptions](#googleoptions)_ | GoogleConfig holds all configurations for Google provider. |
| `oidcConfig` | _[OIDCOptions](#oidcoptions)_ | OIDCConfig holds all configurations for OIDC provider<br/>or providers utilize OIDC configurations. |
| `loginGovConfig` | _[LoginGovOptions](#logingovoptions)_ | LoginGovConfig holds all configurations for LoginGov provider. |
| `sisConfig` | _[SISOptions](#sisoptions)_ | SISConfig holds all configurations for SIS provider. |
| `id` | _string_ | ID should be a unique identifier for the provider.<br/>This value is required for all providers. |
| `provider` | _[ProviderType](#providertype)_ | Type is the OAuth provider<br/>must be set from the supported providers group,<br/>otherwise 'Google' is set as default |
| `name` | _string_ | Name is the providers display name<br/>if set, it will be shown to the users in the login page. |
Expand All @@ -423,6 +424,7 @@ Provider holds all configuration for a single provider
| `scope` | _string_ | Scope is the OAuth scope specification |
| `allowedGroups` | _[]string_ | AllowedGroups is a list of restrict logins to members of this group |
| `code_challenge_method` | _string_ | The code challenge method |
| `signOutURL` | _string_ | SignOutURL overrides the provider's default sign-out redirect URL |

### ProviderType
#### (`string` alias)
Expand All @@ -444,6 +446,17 @@ and oidc.
Providers is a collection of definitions for providers.


### SISOptions

(**Appears on:** [Provider](#provider))



| Field | Type | Description |
| ----- | ---- | ----------- |
| `SISRootURL` | _string_ | SISRootURL is the OpenID Connect SISRoot URL |
| `ClearExtraCookieNames` | _[]string_ | ClearExtraCookieNames sets cookie names to clear after sign out |

### SecretSource

(**Appears on:** [ClaimSource](#claimsource), [HeaderValue](#headervalue), [TLS](#tls))
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/options/legacy_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ type LegacyProvider struct {
GoogleUseApplicationDefaultCredentials bool `flag:"google-use-application-default-credentials" cfg:"google_use_application_default_credentials"`

SISRootURL string `flag:"sis-root-url" cfg:"sis_root_url"`
SignOutURL string `flag:"sign-out-url" cfg:"sign_out_url"`
ClearExtraCookieNames []string `flag:"clear-extra-cookie-names" cfg:"clear_extra_cookie_names"`

// These options allow for other providers besides Google, with
Expand Down Expand Up @@ -671,6 +672,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
Scope: l.Scope,
AllowedGroups: l.AllowedGroups,
CodeChallengeMethod: l.CodeChallengeMethod,
SignOutURL: l.SignOutURL,
}

// This part is out of the switch section for all providers that support OIDC
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/options/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type Provider struct {
AllowedGroups []string `json:"allowedGroups,omitempty"`
// The code challenge method
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
// SignOutURL overrides the provider's default sign-out redirect URL
SignOutURL string `json:"signOutURL,omitempty"`
}

// ProviderType is used to enumerate the different provider type options
Expand Down
1 change: 1 addition & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData,
"profile": {dst: &p.ProfileURL, raw: providerConfig.ProfileURL},
"validate": {dst: &p.ValidateURL, raw: providerConfig.ValidateURL},
"resource": {dst: &p.ProtectedResource, raw: providerConfig.ProtectedResource},
"signout": {dst: &p.SignOutURL, raw: providerConfig.SignOutURL},
} {
var err error
*u.dst, err = url.Parse(u.raw)
Expand Down
4 changes: 2 additions & 2 deletions providers/sis.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ func (p *SISProvider) GetSignOutURL(redirectURI string) string {
// copy URL
redirect := *p.SignOutURL
if redirectURI != "" {
v := url.Values{}
v.Add("rd", redirectURI)
v := redirect.Query()
v.Set("rd", redirectURI)
redirect.RawQuery = v.Encode()
}
return redirect.String()
Expand Down
35 changes: 35 additions & 0 deletions providers/sis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,41 @@ func TestSISProviderOverrides(t *testing.T) {
assert.Equal(t, "profile", p.Data().Scope)
}

func TestSISProviderGetSignOutURL(t *testing.T) {
tests := []struct {
name string
signOutURL string
redirectURI string
expected string
}{
{
name: "no redirect preserves sign-out URL as-is",
signOutURL: "https://sis.example.com/sso/logout",
redirectURI: "",
expected: "https://sis.example.com/sso/logout",
},
{
name: "redirect appended as rd param",
signOutURL: "https://sis.example.com/sso/logout",
redirectURI: "https://app.example.com/home",
expected: "https://sis.example.com/sso/logout?rd=https%3A%2F%2Fapp.example.com%2Fhome",
},
{
name: "existing query params preserved when adding rd",
signOutURL: "https://autentica.example.com/logout?appId=5784",
redirectURI: "https://app.example.com/home",
expected: "https://autentica.example.com/logout?appId=5784&rd=https%3A%2F%2Fapp.example.com%2Fhome",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
u, _ := url.Parse(tt.signOutURL)
p := NewSISProvider(&ProviderData{SignOutURL: u}, options.SISOptions{})
assert.Equal(t, tt.expected, p.GetSignOutURL(tt.redirectURI))
})
}
}

func TestSISProviderRedeem(t *testing.T) {
b := testSISBackend(map[string]string{
"/sso/oauth2.0/accessToken": "access_token=imaginary_access_token&expires=10000",
Expand Down