From c6d037aa54d7af17065d4656866cfdb3302db5a1 Mon Sep 17 00:00:00 2001 From: vibe Date: Wed, 11 Jun 2025 00:19:50 -0700 Subject: [PATCH 1/5] feature(translator): expose OIDC oauth cookie samesite configuration Signed-off-by: vibe --- api/v1alpha1/oidc_types.go | 36 ++++++++ api/v1alpha1/zz_generated.deepcopy.go | 75 ++++++++++++++++ ...ateway.envoyproxy.io_securitypolicies.yaml | 83 ++++++++++++++++++ ...ateway.envoyproxy.io_securitypolicies.yaml | 83 ++++++++++++++++++ internal/ir/xds.go | 5 ++ internal/ir/zz_generated.deepcopy.go | 5 ++ internal/xds/translator/oidc.go | 53 ++++++++++++ internal/xds/translator/oidc_test.go | 86 +++++++++++++++++++ release-notes/current.yaml | 1 + site/content/en/latest/api/extension_types.md | 35 ++++++++ 10 files changed, 462 insertions(+) create mode 100644 internal/xds/translator/oidc_test.go diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index 61476ee6b4..92bc850e74 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -37,6 +37,11 @@ type OIDC struct { // +optional CookieNames *OIDCCookieNames `json:"cookieNames,omitempty"` + // CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + // If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + // +optional + CookieConfigs *OIDCCookieConfigs `json:"cookieConfigs,omitempty"` + // The optional domain to set the access and ID token cookies on. // If not set, the cookies will default to the host of the request, not including the subdomains. // If set, the cookies will be set on the specified domain and all subdomains. @@ -187,3 +192,34 @@ type OIDCCookieNames struct { // +optional IDToken *string `json:"idToken,omitempty"` } + +type SameSite string + +const ( + // SameSiteLax specifies the "Lax" SameSite policy. + SameSiteLax SameSite = "Lax" + // SameSiteStrict specifies the "Strict" SameSite policy. + SameSiteStrict SameSite = "Strict" + // SameSiteNone specifies the "None" SameSite policy. Requires a Secure cookie. + SameSiteNone SameSite = "None" + + // SameSiteDisabled specifies the "Disabled" SameSite policy. + SameSiteDisabled SameSite = "Disabled" +) + +type OIDCCookieConfigs struct { + BearerToken *OIDCCookieConfig `json:"bearerToken,omitempty"` + OauthHmac *OIDCCookieConfig `json:"oauthHmac,omitempty"` + OauthExpires *OIDCCookieConfig `json:"oauthExpires,omitempty"` + IdToken *OIDCCookieConfig `json:"idToken,omitempty"` + RefreshToken *OIDCCookieConfig `json:"RefreshToken,omitempty"` + OauthNonce *OIDCCookieConfig `json:"oauthNonce,omitempty"` + CodeVerifier *OIDCCookieConfig `json:"codeVerifier,omitempty"` +} + +type OIDCCookieConfig struct { + // +optional + // +kubebuilder:validation:Enum=Lax;Strict;None;Disabled + // +kubebuilder:default=Disabled + SameSite *string `json:"sameSite,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 8507c2946c..f0722b244a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -4454,6 +4454,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = new(OIDCCookieNames) (*in).DeepCopyInto(*out) } + if in.CookieConfigs != nil { + in, out := &in.CookieConfigs, &out.CookieConfigs + *out = new(OIDCCookieConfigs) + (*in).DeepCopyInto(*out) + } if in.CookieDomain != nil { in, out := &in.CookieDomain, &out.CookieDomain *out = new(string) @@ -4521,6 +4526,76 @@ func (in *OIDC) DeepCopy() *OIDC { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCCookieConfig) DeepCopyInto(out *OIDCCookieConfig) { + *out = *in + if in.SameSite != nil { + in, out := &in.SameSite, &out.SameSite + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieConfig. +func (in *OIDCCookieConfig) DeepCopy() *OIDCCookieConfig { + if in == nil { + return nil + } + out := new(OIDCCookieConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCCookieConfigs) DeepCopyInto(out *OIDCCookieConfigs) { + *out = *in + if in.BearerToken != nil { + in, out := &in.BearerToken, &out.BearerToken + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.OauthHmac != nil { + in, out := &in.OauthHmac, &out.OauthHmac + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.OauthExpires != nil { + in, out := &in.OauthExpires, &out.OauthExpires + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.IdToken != nil { + in, out := &in.IdToken, &out.IdToken + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.RefreshToken != nil { + in, out := &in.RefreshToken, &out.RefreshToken + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.OauthNonce != nil { + in, out := &in.OauthNonce, &out.OauthNonce + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } + if in.CodeVerifier != nil { + in, out := &in.CodeVerifier, &out.CodeVerifier + *out = new(OIDCCookieConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieConfigs. +func (in *OIDCCookieConfigs) DeepCopy() *OIDCCookieConfigs { + if in == nil { + return nil + } + out := new(OIDCCookieConfigs) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OIDCCookieNames) DeepCopyInto(out *OIDCCookieNames) { *out = *in diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 1f3189dc98..3565e1fe05 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3612,6 +3612,89 @@ spec: required: - name type: object + cookieConfigs: + description: |- + CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + properties: + RefreshToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + bearerToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + codeVerifier: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + idToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthExpires: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthHmac: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthNonce: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + type: object cookieDomain: description: |- The optional domain to set the access and ID token cookies on. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index c2bc80a65f..709af3c561 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3611,6 +3611,89 @@ spec: required: - name type: object + cookieConfigs: + description: |- + CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + properties: + RefreshToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + bearerToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + codeVerifier: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + idToken: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthExpires: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthHmac: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthNonce: + properties: + sameSite: + default: Disabled + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + type: object cookieDomain: description: |- The optional domain to set the access and ID token cookies on. diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 50b4972c93..2d855fd1e7 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1128,6 +1128,11 @@ type OIDC struct { // CookieDomain sets the domain of the cookies set by the oauth filter. CookieDomain *string `json:"cookieDomain,omitempty"` + // CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + // If a specific cookie is not configured, it will use the default xds value of disabled. + // +optional + CookieConfigs *egv1a1.OIDCCookieConfigs `json:"cookieConfigs,omitempty"` + // Skips OIDC authentication when the request contains any header that will be extracted by the JWT // filter, normally "Authorization: Bearer ...". This is typically used for non-browser clients that // may not be able to handle OIDC redirects and wish to directly supply a token instead. diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index fb6d3b44d6..388404b552 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2397,6 +2397,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = new(string) **out = **in } + if in.CookieConfigs != nil { + in, out := &in.CookieConfigs, &out.CookieConfigs + *out = new(v1alpha1.OIDCCookieConfigs) + (*in).DeepCopyInto(*out) + } if in.DenyRedirect != nil { in, out := &in.DenyRedirect, &out.DenyRedirect *out = new(v1alpha1.OIDCDenyRedirect) diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 266e8df586..bcbe1e6f9c 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -139,6 +139,7 @@ func oauth2Config(securityFeatures *ir.SecurityFeatures) (*oauth2v3.OAuth2, erro }, AuthorizationEndpoint: oidc.Provider.AuthorizationEndpoint, RedirectUri: oidc.RedirectURL, + CookieConfigs: buildCookieConfigs(oidc), RedirectPathMatcher: &matcherv3.PathMatcher{ Rule: &matcherv3.PathMatcher_Path{ Path: &matcherv3.StringMatcher{ @@ -235,6 +236,58 @@ func oauth2Config(securityFeatures *ir.SecurityFeatures) (*oauth2v3.OAuth2, erro return oauth2, nil } +func getSameSiteOrDefault(config *egv1a1.OIDCCookieConfig) oauth2v3.CookieConfig_SameSite { + if config == nil || config.SameSite == nil { + return oauth2v3.CookieConfig_DISABLED + } + + samesite := egv1a1.SameSite(*config.SameSite) + + switch samesite { + case egv1a1.SameSiteStrict: + return oauth2v3.CookieConfig_STRICT + case egv1a1.SameSiteLax: + return oauth2v3.CookieConfig_LAX + case egv1a1.SameSiteNone: + return oauth2v3.CookieConfig_NONE + case egv1a1.SameSiteDisabled: + return oauth2v3.CookieConfig_DISABLED + default: + return oauth2v3.CookieConfig_DISABLED + } +} + +// buildCookieConfigs translates the OIDC configuration from the US +func buildCookieConfigs(oidc *ir.OIDC) *oauth2v3.CookieConfigs { + cookieConfigs := &oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + } + + // If the user did not specify any custom cookie configurations at all, return the defaults. + if oidc.CookieConfigs == nil { + return cookieConfigs + } + + // Apply the user-defined SameSite policy for each cookie if it has been configured. + // The helper function handles the logic of falling back to DISABLED if a specific + // cookie's configuration is omitted in the CRD. + cookieConfigs.BearerTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.BearerToken) + cookieConfigs.OauthHmacCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthHmac) + cookieConfigs.OauthExpiresCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthExpires) + cookieConfigs.IdTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.IdToken) + cookieConfigs.RefreshTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.RefreshToken) + cookieConfigs.OauthNonceCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthNonce) + cookieConfigs.CodeVerifierCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.CodeVerifier) + + return cookieConfigs +} + func buildDenyRedirectMatcher(oidc *ir.OIDC) []*routev3.HeaderMatcher { denyRedirectPathMatchers := make([]*routev3.HeaderMatcher, 0, len(oidc.DenyRedirect.Headers)) diff --git a/internal/xds/translator/oidc_test.go b/internal/xds/translator/oidc_test.go new file mode 100644 index 0000000000..3892fc1cce --- /dev/null +++ b/internal/xds/translator/oidc_test.go @@ -0,0 +1,86 @@ +package translator + +import ( + "testing" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" + oauth2v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/oauth2/v3" + "github.com/stretchr/testify/require" + "k8s.io/utils/ptr" +) + +func TestOIDCCookieConfigSameSite(t *testing.T) { + tests := []struct { + name string + input ir.OIDC + expect oauth2v3.CookieConfigs + }{ + { + name: "defaults all cookie to disabled", + input: ir.OIDC{}, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + }, + }, + { + name: "partial configuration on bearer token", + input: ir.OIDC{ + CookieConfigs: &egv1a1.OIDCCookieConfigs{ + BearerToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("Lax")}, + }, + }, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + }, + }, + { + name: "all cookie configs set to None", + input: ir.OIDC{ + CookieConfigs: &egv1a1.OIDCCookieConfigs{ + BearerToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + OauthHmac: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + OauthExpires: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + IdToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + RefreshToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + OauthNonce: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + CodeVerifier: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + }, + }, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + actual := buildCookieConfigs(&tc.input) + require.Equal(t, tc.expect.BearerTokenCookieConfig.SameSite, actual.BearerTokenCookieConfig.SameSite) + require.Equal(t, tc.expect.OauthHmacCookieConfig.SameSite, actual.OauthHmacCookieConfig.SameSite) + require.Equal(t, tc.expect.OauthExpiresCookieConfig.SameSite, actual.OauthExpiresCookieConfig.SameSite) + require.Equal(t, tc.expect.IdTokenCookieConfig.SameSite, actual.IdTokenCookieConfig.SameSite) + require.Equal(t, tc.expect.RefreshTokenCookieConfig.SameSite, actual.RefreshTokenCookieConfig.SameSite) + require.Equal(t, tc.expect.OauthNonceCookieConfig.SameSite, actual.OauthNonceCookieConfig.SameSite) + require.Equal(t, tc.expect.CodeVerifierCookieConfig.SameSite, actual.CodeVerifierCookieConfig.SameSite) + }) + } +} diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 6a7c3024b5..361a68d260 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -21,6 +21,7 @@ new features: | Added support for setting previous priorities retry predicate. Added support for using extension server policies to in PostTranslateModify hook. Added support for configuring cluster stat name for HTTPRoute and GRPCRoute in EnvoyProxy CRD. + Added support for configuring `SameSite` attribute for Oauth cookies for OIDC authentication. bug fixes: | Handle integer zone annotation values diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 33a235b077..7d91e02414 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -3177,6 +3177,7 @@ _Appears in:_ | `clientID` | _string_ | true | | The client ID to be used in the OIDC
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | | The Kubernetes secret which contains the OIDC client secret to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key
"client-secret". | | `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | | The optional cookie name overrides to be used for Bearer and IdToken cookies in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
If not specified, uses a randomly generated suffix | +| `cookieConfigs` | _[OIDCCookieConfigs](#oidccookieconfigs)_ | false | | CookieConfigs allows overriding the SameSite attribute for OIDC cookies.
If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. | | `cookieDomain` | _string_ | false | | The optional domain to set the access and ID token cookies on.
If not set, the cookies will default to the host of the request, not including the subdomains.
If set, the cookies will be set on the specified domain and all subdomains.
This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. | | `scopes` | _string array_ | false | | The OIDC scopes to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
The "openid" scope is always added to the list of scopes if not already
specified. | | `resources` | _string array_ | false | | The OIDC resources to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | @@ -3190,6 +3191,38 @@ _Appears in:_ | `passThroughAuthHeader` | _boolean_ | false | | Skips OIDC authentication when the request contains a header that will be extracted by the JWT filter. Unless
explicitly stated otherwise in the extractFrom field, this will be the "Authorization: Bearer ..." header.
The passThroughAuthHeader option is typically used for non-browser clients that may not be able to handle OIDC
redirects and wish to directly supply a token instead.
If not specified, defaults to false. | +#### OIDCCookieConfig + + + + + +_Appears in:_ +- [OIDCCookieConfigs](#oidccookieconfigs) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `sameSite` | _string_ | false | Disabled | | + + +#### OIDCCookieConfigs + +ODICCookieConfigs provides configurable mappings for SameSite attributes on OIDC Cookies. + +_Appears in:_ +- [OIDC](#oidc) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `bearerToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `oauthHmac` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `oauthExpires` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `idToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `RefreshToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `oauthNonce` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `codeVerifier` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | + + #### OIDCCookieNames @@ -4282,6 +4315,8 @@ _Appears in:_ | `Endpoint` | EndpointRoutingType is the RoutingType for Endpoint routing.
| + + #### SecurityPolicy From 81e0fd9283811b7e5c82141715fd8627cc60bd4c Mon Sep 17 00:00:00 2001 From: vibe Date: Sat, 14 Jun 2025 01:50:34 -0700 Subject: [PATCH 2/5] chore(translator): update oidc cookie configs to default to strict, regenerate manifests Signed-off-by: vibe --- api/v1alpha1/oidc_types.go | 22 ++--- api/v1alpha1/zz_generated.deepcopy.go | 70 ++++++++-------- ...ateway.envoyproxy.io_securitypolicies.yaml | 16 ++-- ...ateway.envoyproxy.io_securitypolicies.yaml | 16 ++-- internal/gatewayapi/securitypolicy.go | 1 + internal/ir/xds.go | 2 +- internal/ir/zz_generated.deepcopy.go | 6 +- internal/xds/translator/oidc.go | 44 +++++----- internal/xds/translator/oidc_test.go | 61 ++++++++------ ...port-with-different-filters.listeners.yaml | 15 ++++ ...dc-and-jwt-with-passthrough.listeners.yaml | 15 ++++ ...dc-backend-cluster-provider.listeners.yaml | 15 ++++ .../testdata/out/xds-ir/oidc.listeners.yaml | 30 +++++++ ...ypolicy-with-oidc-jwt-authz.listeners.yaml | 15 ++++ release-notes/current.yaml | 1 + site/content/en/latest/api/extension_types.md | 42 +++++----- test/helm/gateway-crds-helm/all.out.yaml | 83 +++++++++++++++++++ .../envoy-gateway-crds.out.yaml | 83 +++++++++++++++++++ 18 files changed, 402 insertions(+), 135 deletions(-) diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index 92bc850e74..3026a21983 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -40,7 +40,7 @@ type OIDC struct { // CookieConfigs allows overriding the SameSite attribute for OIDC cookies. // If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. // +optional - CookieConfigs *OIDCCookieConfigs `json:"cookieConfigs,omitempty"` + CookieConfig *OIDCCookieConfig `json:"cookieConfig,omitempty"` // The optional domain to set the access and ID token cookies on. // If not set, the cookies will default to the host of the request, not including the subdomains. @@ -207,19 +207,19 @@ const ( SameSiteDisabled SameSite = "Disabled" ) -type OIDCCookieConfigs struct { - BearerToken *OIDCCookieConfig `json:"bearerToken,omitempty"` - OauthHmac *OIDCCookieConfig `json:"oauthHmac,omitempty"` - OauthExpires *OIDCCookieConfig `json:"oauthExpires,omitempty"` - IdToken *OIDCCookieConfig `json:"idToken,omitempty"` - RefreshToken *OIDCCookieConfig `json:"RefreshToken,omitempty"` - OauthNonce *OIDCCookieConfig `json:"oauthNonce,omitempty"` - CodeVerifier *OIDCCookieConfig `json:"codeVerifier,omitempty"` +type OIDCCookieConfig struct { + BearerToken *CookieConfig `json:"bearerToken,omitempty"` + OauthHmac *CookieConfig `json:"oauthHmac,omitempty"` + OauthExpires *CookieConfig `json:"oauthExpires,omitempty"` + IDToken *CookieConfig `json:"idToken,omitempty"` + RefreshToken *CookieConfig `json:"RefreshToken,omitempty"` + OauthNonce *CookieConfig `json:"oauthNonce,omitempty"` + CodeVerifier *CookieConfig `json:"codeVerifier,omitempty"` } -type OIDCCookieConfig struct { +type CookieConfig struct { // +optional // +kubebuilder:validation:Enum=Lax;Strict;None;Disabled - // +kubebuilder:default=Disabled + // +kubebuilder:default=Strict SameSite *string `json:"sameSite,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f0722b244a..d79262a5be 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1336,6 +1336,26 @@ func (in *Cookie) DeepCopy() *Cookie { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CookieConfig) DeepCopyInto(out *CookieConfig) { + *out = *in + if in.SameSite != nil { + in, out := &in.SameSite, &out.SameSite + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieConfig. +func (in *CookieConfig) DeepCopy() *CookieConfig { + if in == nil { + return nil + } + out := new(CookieConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomHeaderExtensionSettings) DeepCopyInto(out *CustomHeaderExtensionSettings) { *out = *in @@ -4454,9 +4474,9 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = new(OIDCCookieNames) (*in).DeepCopyInto(*out) } - if in.CookieConfigs != nil { - in, out := &in.CookieConfigs, &out.CookieConfigs - *out = new(OIDCCookieConfigs) + if in.CookieConfig != nil { + in, out := &in.CookieConfig, &out.CookieConfig + *out = new(OIDCCookieConfig) (*in).DeepCopyInto(*out) } if in.CookieDomain != nil { @@ -4528,70 +4548,50 @@ func (in *OIDC) DeepCopy() *OIDC { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OIDCCookieConfig) DeepCopyInto(out *OIDCCookieConfig) { - *out = *in - if in.SameSite != nil { - in, out := &in.SameSite, &out.SameSite - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieConfig. -func (in *OIDCCookieConfig) DeepCopy() *OIDCCookieConfig { - if in == nil { - return nil - } - out := new(OIDCCookieConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OIDCCookieConfigs) DeepCopyInto(out *OIDCCookieConfigs) { *out = *in if in.BearerToken != nil { in, out := &in.BearerToken, &out.BearerToken - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } if in.OauthHmac != nil { in, out := &in.OauthHmac, &out.OauthHmac - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } if in.OauthExpires != nil { in, out := &in.OauthExpires, &out.OauthExpires - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } - if in.IdToken != nil { - in, out := &in.IdToken, &out.IdToken - *out = new(OIDCCookieConfig) + if in.IDToken != nil { + in, out := &in.IDToken, &out.IDToken + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } if in.RefreshToken != nil { in, out := &in.RefreshToken, &out.RefreshToken - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } if in.OauthNonce != nil { in, out := &in.OauthNonce, &out.OauthNonce - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } if in.CodeVerifier != nil { in, out := &in.CodeVerifier, &out.CodeVerifier - *out = new(OIDCCookieConfig) + *out = new(CookieConfig) (*in).DeepCopyInto(*out) } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieConfigs. -func (in *OIDCCookieConfigs) DeepCopy() *OIDCCookieConfigs { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieConfig. +func (in *OIDCCookieConfig) DeepCopy() *OIDCCookieConfig { if in == nil { return nil } - out := new(OIDCCookieConfigs) + out := new(OIDCCookieConfig) in.DeepCopyInto(out) return out } diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 3565e1fe05..8371302aa9 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3612,7 +3612,7 @@ spec: required: - name type: object - cookieConfigs: + cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. @@ -3620,7 +3620,7 @@ spec: RefreshToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3631,7 +3631,7 @@ spec: bearerToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3642,7 +3642,7 @@ spec: codeVerifier: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3653,7 +3653,7 @@ spec: idToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3664,7 +3664,7 @@ spec: oauthExpires: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3675,7 +3675,7 @@ spec: oauthHmac: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3686,7 +3686,7 @@ spec: oauthNonce: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 709af3c561..0e3731a2e8 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3611,7 +3611,7 @@ spec: required: - name type: object - cookieConfigs: + cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. @@ -3619,7 +3619,7 @@ spec: RefreshToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3630,7 +3630,7 @@ spec: bearerToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3641,7 +3641,7 @@ spec: codeVerifier: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3652,7 +3652,7 @@ spec: idToken: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3663,7 +3663,7 @@ spec: oauthExpires: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3674,7 +3674,7 @@ spec: oauthHmac: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict @@ -3685,7 +3685,7 @@ spec: oauthNonce: properties: sameSite: - default: Disabled + default: Strict enum: - Lax - Strict diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index f9fd860037..5e536cbfa5 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -959,6 +959,7 @@ func (t *Translator) buildOIDC( CookieSuffix: suffix, CookieNameOverrides: policy.Spec.OIDC.CookieNames, CookieDomain: policy.Spec.OIDC.CookieDomain, + CookieConfig: policy.Spec.OIDC.CookieConfig, HMACSecret: hmacData, PassThroughAuthHeader: passThroughAuthHeader, DenyRedirect: oidc.DenyRedirect, diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 2d855fd1e7..bb8c4d8186 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1131,7 +1131,7 @@ type OIDC struct { // CookieConfigs allows overriding the SameSite attribute for OIDC cookies. // If a specific cookie is not configured, it will use the default xds value of disabled. // +optional - CookieConfigs *egv1a1.OIDCCookieConfigs `json:"cookieConfigs,omitempty"` + CookieConfig *egv1a1.OIDCCookieConfig `json:"cookieConfig,omitempty"` // Skips OIDC authentication when the request contains any header that will be extracted by the JWT // filter, normally "Authorization: Bearer ...". This is typically used for non-browser clients that diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 388404b552..7bfbe49461 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2397,9 +2397,9 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = new(string) **out = **in } - if in.CookieConfigs != nil { - in, out := &in.CookieConfigs, &out.CookieConfigs - *out = new(v1alpha1.OIDCCookieConfigs) + if in.CookieConfig != nil { + in, out := &in.CookieConfig, &out.CookieConfig + *out = new(v1alpha1.OIDCCookieConfig) (*in).DeepCopyInto(*out) } if in.DenyRedirect != nil { diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index bcbe1e6f9c..67bebd787e 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -236,9 +236,9 @@ func oauth2Config(securityFeatures *ir.SecurityFeatures) (*oauth2v3.OAuth2, erro return oauth2, nil } -func getSameSiteOrDefault(config *egv1a1.OIDCCookieConfig) oauth2v3.CookieConfig_SameSite { +func getSameSiteOrDefault(config *egv1a1.CookieConfig) oauth2v3.CookieConfig_SameSite { if config == nil || config.SameSite == nil { - return oauth2v3.CookieConfig_DISABLED + return oauth2v3.CookieConfig_STRICT } samesite := egv1a1.SameSite(*config.SameSite) @@ -253,39 +253,39 @@ func getSameSiteOrDefault(config *egv1a1.OIDCCookieConfig) oauth2v3.CookieConfig case egv1a1.SameSiteDisabled: return oauth2v3.CookieConfig_DISABLED default: - return oauth2v3.CookieConfig_DISABLED + return oauth2v3.CookieConfig_STRICT } } // buildCookieConfigs translates the OIDC configuration from the US func buildCookieConfigs(oidc *ir.OIDC) *oauth2v3.CookieConfigs { - cookieConfigs := &oauth2v3.CookieConfigs{ - BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + cookieConfig := &oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, } // If the user did not specify any custom cookie configurations at all, return the defaults. - if oidc.CookieConfigs == nil { - return cookieConfigs + if oidc.CookieConfig == nil { + return cookieConfig } // Apply the user-defined SameSite policy for each cookie if it has been configured. // The helper function handles the logic of falling back to DISABLED if a specific // cookie's configuration is omitted in the CRD. - cookieConfigs.BearerTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.BearerToken) - cookieConfigs.OauthHmacCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthHmac) - cookieConfigs.OauthExpiresCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthExpires) - cookieConfigs.IdTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.IdToken) - cookieConfigs.RefreshTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.RefreshToken) - cookieConfigs.OauthNonceCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.OauthNonce) - cookieConfigs.CodeVerifierCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfigs.CodeVerifier) - - return cookieConfigs + cookieConfig.BearerTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.BearerToken) + cookieConfig.OauthHmacCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthHmac) + cookieConfig.OauthExpiresCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthExpires) + cookieConfig.IdTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.IDToken) + cookieConfig.RefreshTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.RefreshToken) + cookieConfig.OauthNonceCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthNonce) + cookieConfig.CodeVerifierCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.CodeVerifier) + + return cookieConfig } func buildDenyRedirectMatcher(oidc *ir.OIDC) []*routev3.HeaderMatcher { diff --git a/internal/xds/translator/oidc_test.go b/internal/xds/translator/oidc_test.go index 3892fc1cce..d37a1a27da 100644 --- a/internal/xds/translator/oidc_test.go +++ b/internal/xds/translator/oidc_test.go @@ -1,13 +1,19 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + package translator import ( "testing" - egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" - "github.com/envoyproxy/gateway/internal/ir" oauth2v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/oauth2/v3" "github.com/stretchr/testify/require" "k8s.io/utils/ptr" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" ) func TestOIDCCookieConfigSameSite(t *testing.T) { @@ -17,46 +23,46 @@ func TestOIDCCookieConfigSameSite(t *testing.T) { expect oauth2v3.CookieConfigs }{ { - name: "defaults all cookie to disabled", + name: "defaults all cookie to strict", input: ir.OIDC{}, expect: oauth2v3.CookieConfigs{ - BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, }, }, { name: "partial configuration on bearer token", input: ir.OIDC{ - CookieConfigs: &egv1a1.OIDCCookieConfigs{ - BearerToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("Lax")}, + CookieConfig: &egv1a1.OIDCCookieConfig{ + BearerToken: &egv1a1.CookieConfig{SameSite: ptr.To("Lax")}, }, }, expect: oauth2v3.CookieConfigs{ BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, - OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, - CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, }, }, { name: "all cookie configs set to None", input: ir.OIDC{ - CookieConfigs: &egv1a1.OIDCCookieConfigs{ - BearerToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - OauthHmac: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - OauthExpires: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - IdToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - RefreshToken: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - OauthNonce: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, - CodeVerifier: &egv1a1.OIDCCookieConfig{SameSite: ptr.To("None")}, + CookieConfig: &egv1a1.OIDCCookieConfig{ + BearerToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + OauthHmac: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + OauthExpires: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + IDToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + RefreshToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + OauthNonce: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + CodeVerifier: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, }, }, expect: oauth2v3.CookieConfigs{ @@ -71,7 +77,8 @@ func TestOIDCCookieConfigSameSite(t *testing.T) { }, } - for _, tc := range tests { + for i := range tests { + tc := &tests[i] t.Run(tc.name, func(t *testing.T) { actual := buildCookieConfigs(&tc.input) require.Equal(t, tc.expect.BearerTokenCookieConfig.SameSite, actual.BearerTokenCookieConfig.SameSite) diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml index 5c6552fd10..bbaf7a47c4 100755 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml @@ -115,6 +115,21 @@ - profile authType: BASIC_AUTH authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: client.oauth.foo.com cookieNames: diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-and-jwt-with-passthrough.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-and-jwt-with-passthrough.listeners.yaml index 8996b15c63..016e048f00 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc-and-jwt-with-passthrough.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc-and-jwt-with-passthrough.listeners.yaml @@ -23,6 +23,21 @@ - openid authType: BASIC_AUTH authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: client.oauth.foo.com cookieNames: diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml index ab9e55eadf..945a1c4dd6 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc-backend-cluster-provider.listeners.yaml @@ -23,6 +23,21 @@ - openid authType: BASIC_AUTH authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: client1.apps.googleusercontent.com cookieNames: diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml index 3a94b3a8bd..22bb54807b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml @@ -25,6 +25,21 @@ - profile authType: BASIC_AUTH authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: client.oauth.foo.com cookieNames: @@ -72,6 +87,21 @@ - profile authType: BASIC_AUTH authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: client.oauth.bar.com cookieDomain: example.com diff --git a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml index eb5f36cb40..1bdf68e4f0 100644 --- a/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/securitypolicy-with-oidc-jwt-authz.listeners.yaml @@ -25,6 +25,21 @@ - profile authType: BASIC_AUTH authorizationEndpoint: https://oidc.example.com/authorize + cookieConfigs: + bearerTokenCookieConfig: + sameSite: STRICT + codeVerifierCookieConfig: + sameSite: STRICT + idTokenCookieConfig: + sameSite: STRICT + oauthExpiresCookieConfig: + sameSite: STRICT + oauthHmacCookieConfig: + sameSite: STRICT + oauthNonceCookieConfig: + sameSite: STRICT + refreshTokenCookieConfig: + sameSite: STRICT credentials: clientId: prometheus cookieNames: diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 361a68d260..bc1b4d3440 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -3,6 +3,7 @@ date: Pending # Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs. breaking changes: | Use gateway name as proxy fleet name for gateway namespace mode. + SameSite attribute for Oauth cookies defaults to `Strict`, make sure to set `CookieConfig.SameSite` to `Disabled` if you want to keep the previous behavior. # Updates addressing vulnerabilities, security flaws, or compliance requirements. security updates: | diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 7d91e02414..6f24e866bc 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -941,6 +941,20 @@ _Appears in:_ | `attributes` | _object (keys:string, values:string)_ | false | | Additional Attributes to set for the generated cookie. | +#### CookieConfig + + + + + +_Appears in:_ +- [OIDCCookieConfig](#oidccookieconfig) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `sameSite` | _string_ | false | Strict | | + + #### CustomHeaderExtensionSettings @@ -3177,7 +3191,7 @@ _Appears in:_ | `clientID` | _string_ | true | | The client ID to be used in the OIDC
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | | The Kubernetes secret which contains the OIDC client secret to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key
"client-secret". | | `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | | The optional cookie name overrides to be used for Bearer and IdToken cookies in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
If not specified, uses a randomly generated suffix | -| `cookieConfigs` | _[OIDCCookieConfigs](#oidccookieconfigs)_ | false | | CookieConfigs allows overriding the SameSite attribute for OIDC cookies.
If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. | +| `cookieConfig` | _[OIDCCookieConfig](#oidccookieconfig)_ | false | | CookieConfigs allows overriding the SameSite attribute for OIDC cookies.
If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. | | `cookieDomain` | _string_ | false | | The optional domain to set the access and ID token cookies on.
If not set, the cookies will default to the host of the request, not including the subdomains.
If set, the cookies will be set on the specified domain and all subdomains.
This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. | | `scopes` | _string array_ | false | | The OIDC scopes to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
The "openid" scope is always added to the list of scopes if not already
specified. | | `resources` | _string array_ | false | | The OIDC resources to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | @@ -3197,30 +3211,18 @@ _Appears in:_ -_Appears in:_ -- [OIDCCookieConfigs](#oidccookieconfigs) - -| Field | Type | Required | Default | Description | -| --- | --- | --- | --- | --- | -| `sameSite` | _string_ | false | Disabled | | - - -#### OIDCCookieConfigs - -ODICCookieConfigs provides configurable mappings for SameSite attributes on OIDC Cookies. - _Appears in:_ - [OIDC](#oidc) | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | -| `bearerToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `oauthHmac` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `oauthExpires` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `idToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `RefreshToken` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `oauthNonce` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | -| `codeVerifier` | _[OIDCCookieConfig](#oidccookieconfig)_ | true | | | +| `bearerToken` | _[CookieConfig](#cookieconfig)_ | true | | | +| `oauthHmac` | _[CookieConfig](#cookieconfig)_ | true | | | +| `oauthExpires` | _[CookieConfig](#cookieconfig)_ | true | | | +| `idToken` | _[CookieConfig](#cookieconfig)_ | true | | | +| `RefreshToken` | _[CookieConfig](#cookieconfig)_ | true | | | +| `oauthNonce` | _[CookieConfig](#cookieconfig)_ | true | | | +| `codeVerifier` | _[CookieConfig](#cookieconfig)_ | true | | | #### OIDCCookieNames diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 34756b1c6d..73be56d82e 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -42256,6 +42256,89 @@ spec: required: - name type: object + cookieConfig: + description: |- + CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + properties: + RefreshToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + bearerToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + codeVerifier: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + idToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthExpires: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthHmac: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthNonce: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + type: object cookieDomain: description: |- The optional domain to set the access and ID token cookies on. diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index b2ae01533d..b719383572 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -24944,6 +24944,89 @@ spec: required: - name type: object + cookieConfig: + description: |- + CookieConfigs allows overriding the SameSite attribute for OIDC cookies. + If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + properties: + RefreshToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + bearerToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + codeVerifier: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + idToken: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthExpires: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthHmac: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + oauthNonce: + properties: + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string + type: object + type: object cookieDomain: description: |- The optional domain to set the access and ID token cookies on. From e275772bdb0b022ba3e735613b311a0efaa46aad Mon Sep 17 00:00:00 2001 From: vibe Date: Sun, 15 Jun 2025 13:55:28 -0700 Subject: [PATCH 3/5] chore(translator): use single CookieConfig for all oauth cookies Signed-off-by: vibe --- api/v1alpha1/oidc_types.go | 10 --- api/v1alpha1/zz_generated.deepcopy.go | 58 +------------ ...ateway.envoyproxy.io_securitypolicies.yaml | 85 ++----------------- ...ateway.envoyproxy.io_securitypolicies.yaml | 85 ++----------------- internal/xds/translator/oidc.go | 19 +++-- internal/xds/translator/oidc_test.go | 79 +++++++++++++---- site/content/en/latest/api/extension_types.md | 22 +---- test/helm/gateway-crds-helm/all.out.yaml | 85 ++----------------- .../envoy-gateway-crds.out.yaml | 85 ++----------------- 9 files changed, 109 insertions(+), 419 deletions(-) diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index 3026a21983..e02500f046 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -208,16 +208,6 @@ const ( ) type OIDCCookieConfig struct { - BearerToken *CookieConfig `json:"bearerToken,omitempty"` - OauthHmac *CookieConfig `json:"oauthHmac,omitempty"` - OauthExpires *CookieConfig `json:"oauthExpires,omitempty"` - IDToken *CookieConfig `json:"idToken,omitempty"` - RefreshToken *CookieConfig `json:"RefreshToken,omitempty"` - OauthNonce *CookieConfig `json:"oauthNonce,omitempty"` - CodeVerifier *CookieConfig `json:"codeVerifier,omitempty"` -} - -type CookieConfig struct { // +optional // +kubebuilder:validation:Enum=Lax;Strict;None;Disabled // +kubebuilder:default=Strict diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index d79262a5be..569996b981 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1336,26 +1336,6 @@ func (in *Cookie) DeepCopy() *Cookie { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CookieConfig) DeepCopyInto(out *CookieConfig) { - *out = *in - if in.SameSite != nil { - in, out := &in.SameSite, &out.SameSite - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieConfig. -func (in *CookieConfig) DeepCopy() *CookieConfig { - if in == nil { - return nil - } - out := new(CookieConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomHeaderExtensionSettings) DeepCopyInto(out *CustomHeaderExtensionSettings) { *out = *in @@ -4549,40 +4529,10 @@ func (in *OIDC) DeepCopy() *OIDC { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OIDCCookieConfig) DeepCopyInto(out *OIDCCookieConfig) { *out = *in - if in.BearerToken != nil { - in, out := &in.BearerToken, &out.BearerToken - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.OauthHmac != nil { - in, out := &in.OauthHmac, &out.OauthHmac - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.OauthExpires != nil { - in, out := &in.OauthExpires, &out.OauthExpires - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.IDToken != nil { - in, out := &in.IDToken, &out.IDToken - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.RefreshToken != nil { - in, out := &in.RefreshToken, &out.RefreshToken - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.OauthNonce != nil { - in, out := &in.OauthNonce, &out.OauthNonce - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) - } - if in.CodeVerifier != nil { - in, out := &in.CodeVerifier, &out.CodeVerifier - *out = new(CookieConfig) - (*in).DeepCopyInto(*out) + if in.SameSite != nil { + in, out := &in.SameSite, &out.SameSite + *out = new(string) + **out = **in } } diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 8371302aa9..955522bc08 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3617,83 +3617,14 @@ spec: CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. properties: - RefreshToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - bearerToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - codeVerifier: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - idToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthExpires: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthHmac: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthNonce: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string type: object cookieDomain: description: |- diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 0e3731a2e8..40b968e4f0 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3616,83 +3616,14 @@ spec: CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. properties: - RefreshToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - bearerToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - codeVerifier: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - idToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthExpires: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthHmac: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthNonce: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string type: object cookieDomain: description: |- diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 67bebd787e..857bfd4df1 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -236,7 +236,7 @@ func oauth2Config(securityFeatures *ir.SecurityFeatures) (*oauth2v3.OAuth2, erro return oauth2, nil } -func getSameSiteOrDefault(config *egv1a1.CookieConfig) oauth2v3.CookieConfig_SameSite { +func getSameSiteOrDefault(config *egv1a1.OIDCCookieConfig) oauth2v3.CookieConfig_SameSite { if config == nil || config.SameSite == nil { return oauth2v3.CookieConfig_STRICT } @@ -275,15 +275,16 @@ func buildCookieConfigs(oidc *ir.OIDC) *oauth2v3.CookieConfigs { } // Apply the user-defined SameSite policy for each cookie if it has been configured. - // The helper function handles the logic of falling back to DISABLED if a specific + // The helper function handles the logic of falling back to STRICT if a specific // cookie's configuration is omitted in the CRD. - cookieConfig.BearerTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.BearerToken) - cookieConfig.OauthHmacCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthHmac) - cookieConfig.OauthExpiresCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthExpires) - cookieConfig.IdTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.IDToken) - cookieConfig.RefreshTokenCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.RefreshToken) - cookieConfig.OauthNonceCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.OauthNonce) - cookieConfig.CodeVerifierCookieConfig.SameSite = getSameSiteOrDefault(oidc.CookieConfig.CodeVerifier) + samesite := getSameSiteOrDefault(oidc.CookieConfig) + cookieConfig.BearerTokenCookieConfig.SameSite = samesite + cookieConfig.OauthHmacCookieConfig.SameSite = samesite + cookieConfig.OauthExpiresCookieConfig.SameSite = samesite + cookieConfig.IdTokenCookieConfig.SameSite = samesite + cookieConfig.RefreshTokenCookieConfig.SameSite = samesite + cookieConfig.OauthNonceCookieConfig.SameSite = samesite + cookieConfig.CodeVerifierCookieConfig.SameSite = samesite return cookieConfig } diff --git a/internal/xds/translator/oidc_test.go b/internal/xds/translator/oidc_test.go index d37a1a27da..62c3693292 100644 --- a/internal/xds/translator/oidc_test.go +++ b/internal/xds/translator/oidc_test.go @@ -36,14 +36,48 @@ func TestOIDCCookieConfigSameSite(t *testing.T) { }, }, { - name: "partial configuration on bearer token", + name: "all cookie configs set to None", + input: ir.OIDC{ + CookieConfig: &egv1a1.OIDCCookieConfig{ + SameSite: ptr.To("None"), + }, + }, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + }, + }, + { + name: "all cookie configs set to Lax", input: ir.OIDC{ CookieConfig: &egv1a1.OIDCCookieConfig{ - BearerToken: &egv1a1.CookieConfig{SameSite: ptr.To("Lax")}, + SameSite: ptr.To("Lax"), }, }, expect: oauth2v3.CookieConfigs{ BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_LAX}, + }, + }, + { + name: "all cookie configs set to Strict", + input: ir.OIDC{ + CookieConfig: &egv1a1.OIDCCookieConfig{ + SameSite: ptr.To("Strict"), + }, + }, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, @@ -53,26 +87,37 @@ func TestOIDCCookieConfigSameSite(t *testing.T) { }, }, { - name: "all cookie configs set to None", + name: "all cookie configs set to Disabled", input: ir.OIDC{ CookieConfig: &egv1a1.OIDCCookieConfig{ - BearerToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - OauthHmac: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - OauthExpires: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - IDToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - RefreshToken: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - OauthNonce: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, - CodeVerifier: &egv1a1.CookieConfig{SameSite: ptr.To("None")}, + SameSite: ptr.To("Disabled"), }, }, expect: oauth2v3.CookieConfigs{ - BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, - CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_NONE}, + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_DISABLED}, + }, + }, + { + name: "cookie config received invalid SameSite value will default to Strict", + input: ir.OIDC{ + CookieConfig: &egv1a1.OIDCCookieConfig{ + SameSite: ptr.To("InvalidValue"), + }, + }, + expect: oauth2v3.CookieConfigs{ + BearerTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthHmacCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthExpiresCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + IdTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + RefreshTokenCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + OauthNonceCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, + CodeVerifierCookieConfig: &oauth2v3.CookieConfig{SameSite: oauth2v3.CookieConfig_STRICT}, }, }, } diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 6f24e866bc..45614f4be6 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -941,20 +941,6 @@ _Appears in:_ | `attributes` | _object (keys:string, values:string)_ | false | | Additional Attributes to set for the generated cookie. | -#### CookieConfig - - - - - -_Appears in:_ -- [OIDCCookieConfig](#oidccookieconfig) - -| Field | Type | Required | Default | Description | -| --- | --- | --- | --- | --- | -| `sameSite` | _string_ | false | Strict | | - - #### CustomHeaderExtensionSettings @@ -3216,13 +3202,7 @@ _Appears in:_ | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | -| `bearerToken` | _[CookieConfig](#cookieconfig)_ | true | | | -| `oauthHmac` | _[CookieConfig](#cookieconfig)_ | true | | | -| `oauthExpires` | _[CookieConfig](#cookieconfig)_ | true | | | -| `idToken` | _[CookieConfig](#cookieconfig)_ | true | | | -| `RefreshToken` | _[CookieConfig](#cookieconfig)_ | true | | | -| `oauthNonce` | _[CookieConfig](#cookieconfig)_ | true | | | -| `codeVerifier` | _[CookieConfig](#cookieconfig)_ | true | | | +| `sameSite` | _string_ | false | Strict | | #### OIDCCookieNames diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 73be56d82e..711444920a 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -42261,83 +42261,14 @@ spec: CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. properties: - RefreshToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - bearerToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - codeVerifier: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - idToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthExpires: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthHmac: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthNonce: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string type: object cookieDomain: description: |- diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index b719383572..dc56eb770d 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -24949,83 +24949,14 @@ spec: CookieConfigs allows overriding the SameSite attribute for OIDC cookies. If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. properties: - RefreshToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - bearerToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - codeVerifier: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - idToken: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthExpires: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthHmac: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object - oauthNonce: - properties: - sameSite: - default: Strict - enum: - - Lax - - Strict - - None - - Disabled - type: string - type: object + sameSite: + default: Strict + enum: + - Lax + - Strict + - None + - Disabled + type: string type: object cookieDomain: description: |- From aebf223e5c16999ef02c692becd5a96c9c3fec90 Mon Sep 17 00:00:00 2001 From: vibe Date: Mon, 16 Jun 2025 15:25:32 -0700 Subject: [PATCH 4/5] chore(translator): fix doc strings and add yaml test Signed-off-by: vibe --- api/v1alpha1/oidc_types.go | 2 +- ...ateway.envoyproxy.io_securitypolicies.yaml | 2 +- ...ateway.envoyproxy.io_securitypolicies.yaml | 2 +- ...-with-oidc-custom-cookies-samesite.in.yaml | 75 ++++++ ...with-oidc-custom-cookies-samesite.out.yaml | 214 ++++++++++++++++++ site/content/en/latest/api/extension_types.md | 2 +- test/helm/gateway-crds-helm/all.out.yaml | 2 +- .../envoy-gateway-crds.out.yaml | 2 +- 8 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.in.yaml create mode 100644 internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index e02500f046..d87f2f2037 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -38,7 +38,7 @@ type OIDC struct { CookieNames *OIDCCookieNames `json:"cookieNames,omitempty"` // CookieConfigs allows overriding the SameSite attribute for OIDC cookies. - // If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + // If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. // +optional CookieConfig *OIDCCookieConfig `json:"cookieConfig,omitempty"` diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 955522bc08..9b90060747 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3615,7 +3615,7 @@ spec: cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. - If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. properties: sameSite: default: Strict diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 40b968e4f0..b02e833854 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3614,7 +3614,7 @@ spec: cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. - If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. properties: sameSite: default: Strict diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.in.yaml new file mode 100644 index 0000000000..8c396b4713 --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.in.yaml @@ -0,0 +1,75 @@ +secrets: +- apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway + name: client1-secret + data: + client-secret: Y2xpZW50MTpzZWNyZXQK +- apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway-system + name: envoy-oidc-hmac + data: + hmac-secret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - www.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway # This policy should attach httproute-2 + uid: b8284d0f-de82-4c65-b204-96a0d3f258a1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + oidc: + provider: + issuer: "https://accounts.google.com" + clientID: "client1.apps.googleusercontent.com" + clientSecret: + name: "client1-secret" + redirectURL: "https://www.example.com/bar/oauth2/callback" + logoutPath: "/bar/logout" + cookieNames: + idToken: "CustomIdTokenCookie" + accessToken: "CustomAccessTokenCookie" + cookieConfig: + sameSite: None diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml new file mode 100644 index 0000000000..7d9e7c1899 --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml @@ -0,0 +1,214 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - www.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + uid: b8284d0f-de82-4c65-b204-96a0d3f258a1 + spec: + oidc: + clientID: client1.apps.googleusercontent.com + clientSecret: + group: null + kind: null + name: client1-secret + cookieConfig: + sameSite: None + cookieNames: + accessToken: CustomAccessTokenCookie + idToken: CustomIdTokenCookie + logoutPath: /bar/logout + provider: + issuer: https://accounts.google.com + redirectURL: https://www.example.com/bar/oauth2/callback + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: www.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + security: + oidc: + clientID: client1.apps.googleusercontent.com + clientSecret: '[redacted]' + cookieConfig: + sameSite: None + cookieNameOverrides: + accessToken: CustomAccessTokenCookie + idToken: CustomIdTokenCookie + cookieSuffix: b0a1b740 + hmacSecret: '[redacted]' + logoutPath: /bar/logout + name: securitypolicy/envoy-gateway/policy-for-gateway + provider: + authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth + tokenEndpoint: https://oauth2.googleapis.com/token + redirectPath: /bar/oauth2/callback + redirectURL: https://www.example.com/bar/oauth2/callback + scopes: + - openid + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 45614f4be6..6f55a38fb4 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -3177,7 +3177,7 @@ _Appears in:_ | `clientID` | _string_ | true | | The client ID to be used in the OIDC
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | | The Kubernetes secret which contains the OIDC client secret to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
This is an Opaque secret. The client secret should be stored in the key
"client-secret". | | `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ | false | | The optional cookie name overrides to be used for Bearer and IdToken cookies in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
If not specified, uses a randomly generated suffix | -| `cookieConfig` | _[OIDCCookieConfig](#oidccookieconfig)_ | false | | CookieConfigs allows overriding the SameSite attribute for OIDC cookies.
If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. | +| `cookieConfig` | _[OIDCCookieConfig](#oidccookieconfig)_ | false | | CookieConfigs allows overriding the SameSite attribute for OIDC cookies.
If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. | | `cookieDomain` | _string_ | false | | The optional domain to set the access and ID token cookies on.
If not set, the cookies will default to the host of the request, not including the subdomains.
If set, the cookies will be set on the specified domain and all subdomains.
This means that requests to any subdomain will not require reauthentication after users log in to the parent domain. | | `scopes` | _string array_ | false | | The OIDC scopes to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
The "openid" scope is always added to the list of scopes if not already
specified. | | `resources` | _string array_ | false | | The OIDC resources to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 711444920a..3e5795947c 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -42259,7 +42259,7 @@ spec: cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. - If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. properties: sameSite: default: Strict diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index dc56eb770d..a460a5faa1 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -24947,7 +24947,7 @@ spec: cookieConfig: description: |- CookieConfigs allows overriding the SameSite attribute for OIDC cookies. - If a specific cookie is not configured, it will use the "Disabled" SameSite policy and xds will omit SameSite when generating the cookie. + If a specific cookie is not configured, it will use the "Strict" SameSite policy by default. properties: sameSite: default: Strict From a8b2210fab9943f68e6f38a9b9bf2e8305f40548 Mon Sep 17 00:00:00 2001 From: vibe Date: Mon, 16 Jun 2025 16:03:18 -0700 Subject: [PATCH 5/5] chore(translator): make testdata - update cookies samesite yaml test out Signed-off-by: vibe --- .../securitypolicy-with-oidc-custom-cookies-samesite.out.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml index 7d9e7c1899..2927b1a496 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies-samesite.out.yaml @@ -93,6 +93,9 @@ infraIR: labels: gateway.envoyproxy.io/owning-gateway-name: gateway-1 gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class name: envoy-gateway/gateway-1 namespace: envoy-gateway-system securityPolicies: